<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://blog.huhaha.vip/</id>
  <title type="text">小王的博客</title>
  <subtitle type="text">一个上了年纪的猿人</subtitle>
  <updated>2026-10-13T10:00:00.000Z</updated>
  <author><name>小王的博客</name></author>
  <link rel="alternate" href="https://blog.huhaha.vip/"/>
  <link rel="self" href="https://blog.huhaha.vip/atom.xml"/>
  <generator uri="https://github.com/CuteLeaf/Firefly">Firefly v6.16.8</generator>
    <entry>
      <id>https://blog.huhaha.vip/posts/github-multi-account-ssh-config/</id>
      <title type="text">【工具】GitHub 多账号 SSH 配置完整指南</title>
      <published>2026-10-13T10:00:00.000Z</published>
      <updated>2026-10-13T10:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/github-multi-account-ssh-config/"/>
      <summary type="text">解决本地多 GitHub 账号冲突问题：每个账号独立密钥 + .ssh/config 别名 + 仓库独立提交作者配置，一行命令测试连通，避免 A 账号去访问 B 仓库权限报错。</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>很多人电脑上会有两个及以上的 GitHub 账号，比如一个是工作号、一个是个人号。默认的 SSH 配置只有一个私钥，当你用账号 A 的密钥去访问账号 B 的仓库时，GitHub 会认为你是账号 A，而账号 A 没有 B 仓库的权限，直接报”仓库不存在”。</p><p>这个问题的根源是：<strong>两个仓库用了同一个 SSH 地址 <code>git@github.com</code></strong>。解决方法很简单——给每个账号单独配一套密钥，再用 <code>.ssh/config</code> 起个别名，B 的仓库 remote 改成别名地址就完事了。</p></section>
<section><h2>第一步：生成两套独立的 SSH 密钥<a href="#第一步生成两套独立的-ssh-密钥"><span>#</span></a></h2><p>打开 Git Bash 或 PowerShell，执行以下命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># A 账号密钥（如果已有可以跳过）</span></div></div><div><div><div>2</div></div><div><span>ssh-keygen</span><span> </span><span>-t</span><span> </span><span>ed25519</span><span> </span><span>-C</span><span> </span><span>"账号A的github邮箱"</span><span> </span><span>-f</span><span> </span><span>~/.ssh/id_gh_a</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># B 账号密钥（重点，新建这个）</span></div></div><div><div><div>5</div></div><div><span>ssh-keygen</span><span> </span><span>-t</span><span> </span><span>ed25519</span><span> </span><span>-C</span><span> </span><span>"账号B的github邮箱"</span><span> </span><span>-f</span><span> </span><span>~/.ssh/id_gh_b</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>提示输入 passphrase 时，可以直接回车用空密码，也可以设置密码（推荐）。</p></blockquote><p>生成完毕后，把两个公钥分别添加到对应账号：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 查看公钥内容</span></div></div><div><div><div>2</div></div><div><span>cat</span><span> </span><span>~/.ssh/id_gh_a.pub</span></div></div><div><div><div>3</div></div><div><span>cat</span><span> </span><span>~/.ssh/id_gh_b.pub</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后分别登录 GitHub：</p><ul>
<li><strong>账号 A</strong> → Settings → SSH and GPG keys → New SSH key → 粘贴 <code>id_gh_a.pub</code> 内容</li>
<li><strong>账号 B</strong> → Settings → SSH and GPG keys → New SSH key → 粘贴 <code>id_gh_b.pub</code> 内容</li>
</ul></section>
<section><h2>第二步：创建 / 修改 <code>~/.ssh/config</code><a href="#第二步创建--修改-sshconfig"><span>#</span></a></h2><p><strong>Windows</strong> 路径：<code>C:\Users\你的用户名\.ssh\config</code></p><blockquote><p>⚠️ 注意：文件名叫 <code>config</code>，<strong>不要加任何后缀</strong>（比如 <code>.txt</code>），编码用 UTF-8。</p></blockquote><p>写入以下内容：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># GitHub 账号A</span></div></div><div><div><div>2</div></div><div><span>Host gh-a</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>HostName github.com</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>IdentityFile ~/.ssh/id_gh_a</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>User git</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># GitHub 账号B</span></div></div><div><div><div>8</div></div><div><span>Host gh-b</span></div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>HostName github.com</span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>IdentityFile ~/.ssh/id_gh_b</span></div></div><div><div><div>11</div></div><div><span><span>  </span></span><span>User git</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>含义解释：</p><ul>
<li><code>Host gh-a</code>：给这个连接起个别名叫 <code>gh-a</code>，以后用这个别名代替 <code>github.com</code></li>
<li><code>HostName github.com</code>：实际连接的服务器</li>
<li><code>IdentityFile</code>：使用哪个私钥</li>
<li><code>User git</code>：SSH 连接 GitHub 使用的用户名（固定写 git）</li>
</ul></blockquote></section>
<section><h2>第三步：测试连通性<a href="#第三步测试连通性"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 测试账号 A</span></div></div><div><div><div>2</div></div><div><span>ssh</span><span> </span><span>-T</span><span> </span><span>gh-a</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 测试账号 B</span></div></div><div><div><div>5</div></div><div><span>ssh</span><span> </span><span>-T</span><span> </span><span>gh-b</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>成功的话会看到类似这样的输出：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Hi B用户名! You've successfully authenticated, but GitHub does not provide shell access.</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>第四步：修改 B 仓库的 remote 地址<a href="#第四步修改-b-仓库的-remote-地址"><span>#</span></a></h2><p>进入账号 B 的本地仓库目录，先把当前的 remote 地址看一下：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>remote</span><span> </span><span>-v</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>原来大概率是 <code>git@github.com:Bname/repo.git</code>，这个会默认读取 id_gh_a，必须改成别名 <code>gh-b</code>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>remote</span><span> </span><span>set-url</span><span> </span><span>origin</span><span> </span><span>gh-b:B用户名/仓库名.git</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>改完后验证一下：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>remote</span><span> </span><span>-v</span></div></div><div><div><div>2</div></div><div><span># 应该看到 origin 用的是 gh-b:...</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>第五步：设置本仓库独立的提交作者<a href="#第五步设置本仓库独立的提交作者"><span>#</span></a></h2><p>现在 B 仓库用的密钥对了，但 commit 的 author 还是全局配置的 A 账号信息。用 <code>--local</code> 只在本仓库生效，不影响其他仓库：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>config</span><span> </span><span>--local</span><span> </span><span>user.name</span><span> </span><span>"B的GitHub用户名"</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>config</span><span> </span><span>--local</span><span> </span><span>user.email</span><span> </span><span>"B的GitHub邮箱"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>✅ <code>--local</code> 只作用当前仓库，不会污染 A 仓库的配置！</p></blockquote><p>验证配置：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>config</span><span> </span><span>--local</span><span> </span><span>--list</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>第六步：以后的使用规范<a href="#第六步以后的使用规范"><span>#</span></a></h2><p>养成习惯，克隆的时候直接带上别名：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 克隆 A 账号的仓库</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>gh-a:A用户名/repo.git</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 克隆 B 账号的仓库</span></div></div><div><div><div>5</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>gh-b:B用户名/repo.git</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>快速自检命令<a href="#快速自检命令"><span>#</span></a></h2><p>遇到问题先跑这三个，基本能定位：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 看当前仓库 git 配置</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>config</span><span> </span><span>--local</span><span> </span><span>--list</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 看远程地址</span></div></div><div><div><div>5</div></div><div><span>git</span><span> </span><span>remote</span><span> </span><span>-v</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 测试 B 账号 SSH 连通</span></div></div><div><div><div>8</div></div><div><span>ssh</span><span> </span><span>-T</span><span> </span><span>gh-b</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>常见报错：<code>Permission denied (publickey)</code> 排查<a href="#常见报错permission-denied-publickey-排查"><span>#</span></a></h2><p>遇到这个报错的核心原因是：<strong>SSH 找到了私钥，但 GitHub 拒绝了该公钥身份</strong>。最常见的根因是 remote 地址写错了。</p><section><h3>高频坑：remote 地址写错了<a href="#高频坑remote-地址写错了"><span>#</span></a></h3><p>❌ <strong>错误写法</strong>（把别名当成了用户名）：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>gh-b@github.com:用户名/仓库名.git</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p><code>gh-b</code> 是你本地 config 里的 <strong>Host 别名</strong>，不是用户名。SSH 连接 GitHub 的固定用户名是 <code>git</code>，这个在 config 里已经写死了。</p></blockquote><p>✅ <strong>正确写法</strong>（直接用别名冒号分隔）：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>gh-b:用户名/仓库名.git</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>修正命令（进入仓库目录执行）：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>remote</span><span> </span><span>set-url</span><span> </span><span>origin</span><span> </span><span>gh-b:B的GitHub用户名/仓库名.git</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>示例：B 账号名叫 <code>wangbin247</code>，仓库叫 <code>demo</code>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>remote</span><span> </span><span>set-url</span><span> </span><span>origin</span><span> </span><span>gh-b:wangbin247/demo.git</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>按顺序排查（先测试 SSH 连通性）<a href="#按顺序排查先测试-ssh-连通性"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ssh</span><span> </span><span>-T</span><span> </span><span>gh-b</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h4>情况一：依旧返回 <code>Permission denied (publickey)</code><a href="#情况一依旧返回-permission-denied-publickey"><span>#</span></a></h4><p>说明公钥没有正确添加到 B 账号。按以下步骤检查：</p><ol>
<li>完整复制公钥内容（以 <code>ssh-ed25519</code> 开头，结尾是邮箱）：
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cat</span><span> </span><span>~/.ssh/id_gh_b.pub</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>登录 <strong>B 账号</strong> GitHub 网页 → Settings → SSH and GPG keys → New SSH key</li>
<li>粘贴进去，标题随便写，添加</li>
</ol><blockquote><p>⚠️ <strong>公钥必须加到 B 账号，不要加到 A 账号！</strong></p></blockquote></section><section><h4>情况二：返回成功 <code>Hi B用户名! You've successfully authenticated...</code><a href="#情况二返回成功-hi-b用户名-youve-successfully-authenticated"><span>#</span></a></h4><p>SSH 连通正常，问题在 git remote 地址，按下面的优先级检查：</p><ol>
<li><strong>确认 config 内容正确</strong>（Host 名称、IdentityFile 路径）：
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Host gh-b</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>HostName github.com</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>IdentityFile ~/.ssh/id_gh_b</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>User git</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li><strong>确认 remote 地址格式正确</strong>（见上面的正确写法）</li>
<li><strong>确认 B 账号对该仓库有读写权限</strong>（私有仓库必须是 B 创建或被邀请为协作者）</li>
<li><strong>确认公钥已添加到 B 账号</strong>（见情况一的步骤）</li>
</ol></section></section><section><h3>排查顺序总结<a href="#排查顺序总结"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>ssh -T gh-b 失败 → 检查公钥是否添加到了 B 账号</span></div></div><div><div><div>2</div></div><div><span>ssh -T gh-b 成功 → 检查 git remote 地址格式是否正确</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section>
<section><h2>常见问题<a href="#常见问题"><span>#</span></a></h2><p><strong>Q：已经 push 到远程的历史 commit 作者是 A，需要改吗？</strong></p><p>不建议改。已 push 的历史 commit 重写作者会破坏协作，后续新提交用 B 就行。</p><p><strong>Q：两个仓库能不能共用同一个 SSH 地址？</strong></p><p>不能。这正是踩坑的根源，每个账号必须用不同的别名地址。</p><p><strong>Q：<code>ssh -T gh-b</code> 返回权限被拒绝怎么办？</strong></p><p>参考上面的【常见报错排查】，按顺序检查：公钥是否添加到 B 账号 → config 是否正确 → remote 地址格式是否正确。</p></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2>

<table><thead><tr><th>步骤</th><th>操作</th><th>关键命令</th></tr></thead><tbody><tr><td>生成密钥</td><td>为每个账号单独生成一对密钥</td><td><code>ssh-keygen -t ed25519 -f ~/.ssh/id_gh_x</code></td></tr><tr><td>配置别名</td><td>编辑 <code>~/.ssh/config</code> 设置 Host</td><td><code>Host gh-b → IdentityFile ~/.ssh/id_gh_b</code></td></tr><tr><td>修改 remote</td><td>B 仓库 remote 改用别名地址</td><td><code>git remote set-url origin gh-b:user/repo.git</code></td></tr><tr><td>设置本地作者</td><td>仅当前仓库生效</td><td><code>git config --local user.name "B用户名"</code></td></tr></tbody></table><p>整个流程其实就四步：生成密钥 → 配 config → 改 remote → 设 local 作者。记住核心原则：<strong>每个账号一套密钥，每个仓库一个别名</strong>，就不会再踩坑了。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/linux/linux-%E7%A3%81%E7%9B%98%E7%A9%BA%E9%97%B4%E6%A3%80%E6%9F%A5%E4%B8%8E%E6%96%B0%E7%A1%AC%E7%9B%98%E6%8C%82%E8%BD%BD%E5%AE%8C%E6%95%B4%E6%8C%87%E5%8D%97/</id>
      <title type="text">Linux 磁盘空间检查与新硬盘挂载完整指南</title>
      <published>2026-08-18T10:00:00.000Z</published>
      <updated>2026-08-18T10:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/linux/linux-%E7%A3%81%E7%9B%98%E7%A9%BA%E9%97%B4%E6%A3%80%E6%9F%A5%E4%B8%8E%E6%96%B0%E7%A1%AC%E7%9B%98%E6%8C%82%E8%BD%BD%E5%AE%8C%E6%95%B4%E6%8C%87%E5%8D%97/"/>
      <summary type="text">本文详细介绍了在 Linux（银河麒麟 V10）环境下挂载新硬盘前的磁盘空间检查方法，以及完整的硬盘分区、格式化、挂载、开机自动挂载配置流程，同时解决了普通用户无 root 权限操作挂载目录的常见问题。</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>在服务器运维过程中，经常需要为新硬盘挂载数据盘或扩展存储空间。银河麒麟 V10 作为国产主流 Linux 操作系统，其磁盘挂载流程与 CentOS/Ubuntu 基本一致，但也有自身的特点。本文整理自实际生产环境中的磁盘挂载操作，涵盖挂载前检查、完整挂载流程、常见问题解答三个部分，适合运维新手和有一定基础的同学参考。</p></section>
<section><h2>一、挂载前磁盘检查<a href="#一挂载前磁盘检查"><span>#</span></a></h2><section><h3>1. 查看已挂载磁盘使用率<a href="#1-查看已挂载磁盘使用率"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>df</span><span> </span><span>-h</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>重点关注以下字段：</p>

<table><thead><tr><th>字段</th><th>说明</th></tr></thead><tbody><tr><td><code>Size</code></td><td>总大小</td></tr><tr><td><code>Used</code></td><td>已用空间</td></tr><tr><td><code>Avail</code></td><td>空闲空间</td></tr><tr><td><code>Mounted on</code></td><td>挂载点</td></tr></tbody></table></section><section><h3>2. 查看块设备，识别新硬盘<a href="#2-查看块设备识别新硬盘"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>lsblk</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li><code>sda</code> 是第一块盘，<code>sdb</code> 是第二块新硬盘；</li>
<li>没有 <code>Mountpoint</code> 列的设备，代表这块盘还没有挂载。</li>
</ul><p>示例输出：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT</span></div></div><div><div><div>2</div></div><div><span>sda      8:0    0    40G  0 disk</span></div></div><div><div><div>3</div></div><div><span>├─sda1   8:1    0   600M  0 part /boot/efi</span></div></div><div><div><div>4</div></div><div><span>├─sda2   8:2    0     1G  0 part /boot</span></div></div><div><div><div>5</div></div><div><span>└─sda3   8:3    0  38.4G  0 part</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>├─klas-root 253:0 0  34.4G  0 lvm  /</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>└─klas-swap 253:1 0     4G  0 lvm  [SWAP]</span></div></div><div><div><div>8</div></div><div><span>sdb      8:16   0   300G  0 disk      ← 新硬盘，无挂载点</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>3. 查看磁盘分区详情<a href="#3-查看磁盘分区详情"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>fdisk</span><span> </span><span>-l</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>该命令可以查看每块磁盘的详细分区信息，包括磁盘型号、扇区大小、磁盘标签类型等。</p></section><section><h3>4. 查看目录占用空间<a href="#4-查看目录占用空间"><span>#</span></a></h3><p>当磁盘空间告警时，需要用 <code>du</code> 定位哪个目录占用大：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 当前目录下各个目录大小</span></div></div><div><div><div>2</div></div><div><span>du</span><span> </span><span>-sh</span><span> </span><span>*</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 看根目录整体大目录</span></div></div><div><div><div>5</div></div><div><span>sudo</span><span> </span><span>du</span><span> </span><span>-sh</span><span> </span><span>/</span><span>*</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>5. 检查 inode 是否耗尽<a href="#5-检查-inode-是否耗尽"><span>#</span></a></h3><p>有时候磁盘还有空间但无法写入文件，可能是 inode 用尽：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>df</span><span> </span><span>-i</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>注意观察 <code>IUse%</code> 列，如果占用率为 100%，说明 inode 已耗尽，需要清理小文件。</p></blockquote><hr /></section></section>
<section><h2>二、新硬盘完整挂载流程<a href="#二新硬盘完整挂载流程"><span>#</span></a></h2><blockquote><p>假设新磁盘设备名为 <code>/dev/sdb</code>，挂载点为 <code>/data</code></p></blockquote><section><h3>Step 1：分区（可选）<a href="#step-1分区可选"><span>#</span></a></h3><p>如果是整块盘直接使用，可跳过此步；如需分区则执行：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>fdisk</span><span> </span><span>/dev/sdb</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>进入交互式界面后，依次输入：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>g    → 创建 GPT 磁盘标签</span></div></div><div><div><div>2</div></div><div><span>n    → 新建分区</span></div></div><div><div><div>3</div></div><div><span><span>     </span></span><span>→ 回车（默认分区编号 1）</span></div></div><div><div><div>4</div></div><div><span><span>     </span></span><span>→ 回车（默认起始扇区）</span></div></div><div><div><div>5</div></div><div><span><span>     </span></span><span>→ 回车（默认结束扇区，使用全部空间）</span></div></div><div><div><div>6</div></div><div><span>w    → 写入分区表并退出</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>⚠️ <strong>重要提醒</strong>：操作前务必确认设备名是 <code>sdb</code>，不要误操作 <code>sda</code>！如果操作失误，立即输入 <code>q</code> 退出，不保存修改。</p></blockquote></section><section><h3>Step 2：格式化（麒麟 V10 推荐 XFS）<a href="#step-2格式化麒麟-v10-推荐-xfs"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>mkfs.xfs</span><span> </span><span>/dev/sdb1</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>若跳过分直接格式化整块盘：<code>sudo mkfs.xfs /dev/sdb</code></p></blockquote></section><section><h3>Step 3：创建挂载目录<a href="#step-3创建挂载目录"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>mkdir</span><span> </span><span>-p</span><span> </span><span>/data</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Step 4：临时挂载测试<a href="#step-4临时挂载测试"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>mount</span><span> </span><span>/dev/sdb1</span><span> </span><span>/data</span></div></div><div><div><div>2</div></div><div><span>df</span><span> </span><span>-h</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>确认挂载成功后，再配置开机自动挂载。</p></section><section><h3>Step 5：获取 UUID 并配置开机自动挂载<a href="#step-5获取-uuid-并配置开机自动挂载"><span>#</span></a></h3><blockquote><p>⚠️ <strong>千万不要直接用 <code>/dev/sdb1</code> 写入 fstab</strong>，必须使用 UUID，否则磁盘设备名变化后系统将无法启动。</p></blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>blkid</span><span> </span><span>/dev/sdb1</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>复制输出的 UUID 值，编辑 <code>/etc/fstab</code>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>vi</span><span> </span><span>/etc/fstab</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在末尾新增一行：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>UUID="你的UUID值"  /data  xfs  defaults  0  0</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Step 6：校验 fstab 配置（极其重要！）<a href="#step-6校验-fstab-配置极其重要"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>mount</span><span> </span><span>-a</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>无任何输出 = 配置正确</strong>。如果有报错，立即回去修改 <code>/etc/fstab</code>，写错可能导致系统无法开机。</p><hr /></section></section>
<section><h2>三、挂载后确认<a href="#三挂载后确认"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>df</span><span> </span><span>-h</span></div></div><div><div><div>2</div></div><div><span>lsblk</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>确认 <code>/data</code> 已正确挂载，空间可用。</p><hr /></section>
<section><h2>四、常见问题：普通用户如何免 sudo 操作挂载目录<a href="#四常见问题普通用户如何免-sudo-操作挂载目录"><span>#</span></a></h2><p>挂载完磁盘到 <code>/data</code>，默认属主为 root，普通用户 <code>yunwei</code> 没有读写权限。以下是两种常用解决方案：</p><section><h3>方案一：修改目录属主（推荐用于普通业务数据）<a href="#方案一修改目录属主推荐用于普通业务数据"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>chown</span><span> </span><span>-R</span><span> </span><span>yunwei:yunwei</span><span> </span><span>/data</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>chmod</span><span> </span><span>755</span><span> </span><span>/data</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>执行后，<code>yunwei</code> 用户可以直接读写 <code>/data</code>，无需 sudo。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>su</span><span> </span><span>-</span><span> </span><span>yunwei</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>/data</span></div></div><div><div><div>3</div></div><div><span>touch</span><span> </span><span>test.txt</span></div></div><div><div><div>4</div></div><div><span>ls</span><span> </span><span>-l</span><span> </span><span>test.txt</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>方案二：MySQL 数据目录场景（特殊处理）<a href="#方案二mysql-数据目录场景特殊处理"><span>#</span></a></h3><p>如果 <code>/data/mysql</code> 存放 MySQL 数据，mysqld 进程运行用户是 <code>mysql</code>，不能直接将所有者改成 <code>yunwei</code>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 目录本身给 yunwei 访问权限</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>chmod</span><span> </span><span>755</span><span> </span><span>/data</span></div></div><div><div><div>3</div></div><div><span># mysql 数据目录归属 mysql 用户</span></div></div><div><div><div>4</div></div><div><span>sudo</span><span> </span><span>chown</span><span> </span><span>-R</span><span> </span><span>mysql:mysql</span><span> </span><span>/data/mysql</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>这种场景下，<code>yunwei</code> 可以通过 MySQL 客户端操作数据库，但不建议直接裸写数据文件，存在安全风险。</p></blockquote></section><section><h3>补充：让权限配置开机自动生效<a href="#补充让权限配置开机自动生效"><span>#</span></a></h3><p>XFS 文件系统不支持在 fstab 中指定 <code>uid/gid</code>，因此每次重启后权限可能丢失。可以将授权写入 <code>/etc/rc.local</code>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 写入开机执行命令</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>bash</span><span> </span><span>-c</span><span> </span><span>'echo "chown -R yunwei:yunwei /data" &gt;&gt; /etc/rc.d/rc.local'</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 给 rc.local 执行权限</span></div></div><div><div><div>5</div></div><div><span>sudo</span><span> </span><span>chmod</span><span> </span><span>+x</span><span> </span><span>/etc/rc.d/rc.local</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>查看当前用户 UID/GID：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>id</span><span> </span><span>yunwei</span></div></div><div><div><div>2</div></div><div><span># 输出：uid=1000(yunwei) gid=1000(yunwei) 组...</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section>
<section><h2>五、总结<a href="#五总结"><span>#</span></a></h2>

<table><thead><tr><th>步骤</th><th>关键命令</th><th>注意事项</th></tr></thead><tbody><tr><td>检查磁盘</td><td><code>df -h</code> / <code>lsblk</code> / <code>df -i</code></td><td>关注空间、inode 使用情况</td></tr><tr><td>分区</td><td><code>sudo fdisk /dev/sdb</code></td><td>确认设备名，输入 <code>g</code>、<code>n</code>、<code>w</code></td></tr><tr><td>格式化</td><td><code>sudo mkfs.xfs /dev/sdb1</code></td><td>麒麟推荐 XFS，不要格式化错盘</td></tr><tr><td>挂载测试</td><td><code>sudo mount /dev/sdb1 /data</code></td><td>先测试再写 fstab</td></tr><tr><td>配置开机</td><td><code>sudo vi /etc/fstab</code> + UUID</td><td><strong>必须用 UUID，不能用设备名</strong></td></tr><tr><td>校验</td><td><code>sudo mount -a</code></td><td>无输出才表示配置正确</td></tr><tr><td>权限设置</td><td><code>sudo chown -R yunwei:yunwei /data</code></td><td>MySQL 数据目录需特殊处理</td></tr></tbody></table><p>掌握了以上流程，面对大多数 Linux 服务器的磁盘挂载任务都能从容应对。如有 MySQL 数据迁移需求，可在挂载完成后进一步调整 datadir 配置。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/%E4%B8%80%E8%A1%8C%E5%91%BD%E4%BB%A4%E6%BF%80%E6%B4%BBjetbrains%E5%85%A8%E5%AE%B6%E6%A1%B6/</id>
      <title type="text">【工具】一行命令激活 JetBrains 全家桶，再也不用东奔西跑了</title>
      <published>2026-08-18T10:00:00.000Z</published>
      <updated>2026-08-18T10:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/%E4%B8%80%E8%A1%8C%E5%91%BD%E4%BB%A4%E6%BF%80%E6%B4%BBjetbrains%E5%85%A8%E5%AE%B6%E6%A1%B6/"/>
      <summary type="text">网上搜索 JetBrains 激活方法，不是过时就是各种引流，步骤繁琐还未必管用。本文介绍一个干净的方法：一条 PowerShell 命令搞定 JB 全家桶激活，包含 IntelliJ IDEA、PyCharm、GoLand 等所有产品，附详细步骤和注意事项。</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>为了激活 JetBrains 的产品，网上搜索了一大堆，有的方法过时，有的是各种引流，四五个操作步骤，最后还不一定管用。别再东奔西跑，各种引导下载、关注公众号了，看完这篇就够了。</p><p>这条命令支持 JetBrains 全家桶（IntelliJ IDEA、PyCharm、GoLand、WebStorm、CLion 等等），包含最新的 2025.x 版本，真正一行命令搞定。</p></section>
<section><h2>前置条件<a href="#前置条件"><span>#</span></a></h2><blockquote><p>需要提前科学上网，否则脚本无法访问激活服务。</p></blockquote></section>
<section><h2>第一步：下载安装 JetBrains 产品<a href="#第一步下载安装-jetbrains-产品"><span>#</span></a></h2><p>去官网下载你需要的产品，包括但不限于：</p><ul>
<li>IntelliJ IDEA</li>
<li>PyCharm</li>
<li>GoLand</li>
<li>WebStorm</li>
<li>CLion</li>
<li>DataGrip</li>
<li>Rider</li>
<li>… 以及全家桶其他产品</li>
</ul><p>下载完后正常安装即可。</p></section>
<section><h2>第二步：运行一次以生成配置文件<a href="#第二步运行一次以生成配置文件"><span>#</span></a></h2><p>安装完成后，<strong>一定要先运行一次</strong>，然后退出。</p><p>这一步的目的是让 JetBrains 在以下目录生成配置文件：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>C:\Users\你的用户名\AppData\Roaming\JetBrains\</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>注意：不同产品版本路径中可能有版本号，例如 <code>C:\Users\xxx\AppData\Roaming\JetBrains\IntelliJIdea2024.2\</code>，不用管具体版本，有配置文件就行。</p></blockquote></section>
<section><h2>第三步：执行激活命令<a href="#第三步执行激活命令"><span>#</span></a></h2><p>打开 <strong>PowerShell</strong>（不要用 CMD！）</p><p>以管理员身份运行 PowerShell，执行如下命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span><span>irm https:</span><span>//</span><span>ckey.run</span><span>/</span><span> | iex</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>命令解释：<code>irm</code> 是 <code>Invoke-RestMethod</code> 的别名，<code>iex</code> 是 <code>Invoke-Expression</code> 的别名，意思是下载并执行 ckey.run 上的脚本。</p></blockquote><p>执行后一路回车即可。执行过程中脚本会自动下载 ja-netfilter 相关组件并配置好激活环境。</p></section>
<section><h2>第四步：复制激活码<a href="#第四步复制激活码"><span>#</span></a></h2><p>命令执行完毕后会自动打开浏览器页面：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://ckey.run/</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>如果没自动打开，手动访问上面的地址即可。</p></blockquote><p>在页面上：</p><ol>
<li>点击你想激活的产品，或者直接点击左上角的<strong>通用版</strong></li>
<li>会弹出一个对话框，直接点<strong>确认</strong>（不想改什么的话）</li>
<li>确认后激活信息会自动复制到剪贴板</li>
</ol><p>然后回到你的 JetBrains IDE，选择 <strong>Activation code</strong> 方式激活，粘贴刚才复制的内容，点击 OK，看到绿色提示就说明激活成功了。</p></section>
<section><h2>第五步：配置防火墙（重要）<a href="#第五步配置防火墙重要"><span>#</span></a></h2><p>激活完成后，记得在 Windows 防火墙中禁止对应 IDE 进程访问网络，防止被检测：</p><ol>
<li>打开 <strong>Windows Defender 防火墙</strong></li>
<li>点击「高级设置」→「出站规则」→「新建规则」</li>
<li>选择「程序」→ 找到对应的 exe 文件（如 <code>idea64.exe</code>）</li>
<li>选择「阻止连接」→ 全选 → 命名后保存</li>
</ol><blockquote><p>这一步是为了保证激活的稳定性，建议做一下。</p></blockquote><hr /></section>
<section><h2>其他平台<a href="#其他平台"><span>#</span></a></h2><section><h3>macOS 用户<a href="#macos-用户"><span>#</span></a></h3><p>评论区有热心网友提供了 Mac 版本的激活方式：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>curl</span><span> </span><span>-L</span><span> </span><span>-o</span><span> </span><span>ckey.run</span><span> </span><span>ckey.run</span><span> &amp;&amp; </span><span>bash</span><span> </span><span>ckey.run</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>执行方式和 Windows 类似，打开终端粘贴执行即可。</p><hr /></section></section>
<section><h2>激活原理<a href="#激活原理"><span>#</span></a></h2><p>这个脚本底层使用的仍然是 <strong>ja-netfilter</strong>，版本是 <code>ja-netfilter 2022.2.0</code>。</p><p>下载的文件存放在以下目录，<strong>不要删除这个目录</strong>：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>C:\Users\Public\.jb_run\</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>脚本的作用就是把整个手动配置过程自动化了，本质上是一样的原理，只不过不用你自己去 GitHub 找 jar 包、改配置了。</p><hr /></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>整个流程其实就三步：</p><ol>
<li>下载安装 JetBrains 产品，运行一次</li>
<li>PowerShell 执行 <code>irm https://ckey.run/ | iex</code></li>
<li>打开网页复制激活码，粘贴到 IDE 里</li>
</ol><p>是不是比网上那些五六个步骤、各种下载引流的文章简洁多了？省下的时间够喝杯咖啡 ☕</p><p>有任何问题欢迎评论区交流~</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/tolaria-intro/</id>
      <title type="text">GitHub热门项目！Tolaria：本地优先的Markdown知识库，让AI直接读你的笔记！</title>
      <published>2026-08-04T00:00:00.000Z</published>
      <updated>2026-08-04T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/tolaria-intro/"/>
      <summary type="text">一款基于Tauri的跨平台桌面应用，用于管理Markdown知识库，支持Git版本控制、离线优先、AI集成，让Claude、Codex直接读取你的笔记，完全开源，文件完全归你所有！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！想让AI直接读你的笔记吗？<a href="#朋友们想让ai直接读你的笔记吗"><span>#</span></a></h2><p>做开发的朋友可能都有这种困扰：笔记散落在各个地方，AI找不到；想用AI处理知识，却不知道怎么组织；换个工具，数据就丢了…好家伙，今天给大家介绍一个神器——<strong>Tolaria</strong>！本地优先的Markdown知识库，Git版本控制，AI直接读你的笔记，完全开源，你的数据永远归你所有！</p></section>
<section><h2>📚 项目介绍<a href="#-项目介绍"><span>#</span></a></h2><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/08/ff40edd494d5435b907d1d8f90fc70d320260804154232919.png" alt="" />
<strong>Tolaria</strong> 是一款基于Tauri的跨平台桌面应用（macOS、Windows、Linux），用于管理Markdown知识库。它的核心理念是<strong>文件优先、Git优先、离线优先</strong>，让你的笔记以标准Markdown文件存储，不被任何工具锁定。更重要的是，它天生支持AI集成，让Claude Code、Codex CLI等AI工具可以直接读取你的笔记！</p><section><h3>核心特点<a href="#核心特点"><span>#</span></a></h3><ul>
<li>📑 <strong>文件优先</strong>：笔记是纯Markdown文件，可移植，用任何编辑器都能打开</li>
<li>🔌 <strong>Git优先</strong>：每个知识库都是Git仓库，完整版本历史，支持任意远程</li>
<li>🛜 <strong>离线优先</strong>：无需账号、订阅、云依赖，完全离线可用</li>
<li>🔬 <strong>开源免费</strong>：AGPL-3.0协议，代码完全公开</li>
<li>📋 <strong>标准格式</strong>：Markdown+YAML Frontmatter，无专有格式</li>
<li>🔍 <strong>类型导航</strong>：类型是导航辅助，不是强制约束</li>
<li>🪄 <strong>AI优先</strong>：内置MCP Server，Claude Code、Codex CLI直接读笔记</li>
<li>⌨️ <strong>键盘优先</strong>：为键盘用户设计，命令面板操作流畅</li>
<li>💪 <strong>实战驱动</strong>：作者自己用它管理10000+笔记，每个功能都解决真实问题</li>
</ul></section><section><h3>设计原则<a href="#设计原则"><span>#</span></a></h3>

<table><thead><tr><th>原则</th><th>说明</th></tr></thead><tbody><tr><td>文件优先</td><td>纯Markdown，任何编辑器都能打开</td></tr><tr><td>Git优先</td><td>完整版本历史，零锁定</td></tr><tr><td>离线优先</td><td>无账号、无订阅、无云依赖</td></tr><tr><td>开源</td><td>免费开源，AGPL-3.0协议</td></tr><tr><td>标准格式</td><td>Markdown+YAML，无专有格式</td></tr><tr><td>AI优先</td><td>内置MCP，AI直接读笔记</td></tr><tr><td>键盘优先</td><td>为Power用户设计</td></tr></tbody></table></section></section>
<section><h2>🚀 安装方式<a href="#-安装方式"><span>#</span></a></h2><section><h3>方式一：Homebrew（macOS）<a href="#方式一homebrewmacos"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>brew</span><span> </span><span>install</span><span> </span><span>--cask</span><span> </span><span>tolaria</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>方式二：官网下载<a href="#方式二官网下载"><span>#</span></a></h3><p>访问 <a href="https://refactoringhq.github.io/tolaria/download/" target="_blank">下载页面</a> 下载对应版本：</p><ul>
<li>macOS：<code>.dmg</code> 文件</li>
<li>Windows：<code>.exe</code> 安装包（已签名）</li>
<li>Linux：<code>.AppImage</code> 或 <code>.deb</code> 文件</li>
</ul></section></section>
<section><h2>🎯 使用指南<a href="#-使用指南"><span>#</span></a></h2><section><h3>第一次启动<a href="#第一次启动"><span>#</span></a></h3><p>首次打开Tolaria时，会提示克隆<a href="https://github.com/refactoringhq/tolaria-getting-started" target="_blank">入门知识库</a>，包含应用的完整使用教程。</p></section><section><h3>创建知识库（Vault）<a href="#创建知识库vault"><span>#</span></a></h3><ol>
<li>打开Tolaria，点击「<strong>新建知识库</strong>」</li>
<li>选择存储位置（本地目录或Git仓库）</li>
<li>填写知识库名称</li>
<li>点击「<strong>创建</strong>」，Tolaria会自动初始化Git仓库</li>
</ol></section><section><h3>创建笔记<a href="#创建笔记"><span>#</span></a></h3><ol>
<li>点击「<strong>新建笔记</strong>」或使用快捷键</li>
<li>使用Markdown语法编写内容</li>
<li>添加YAML Frontmatter（可选）：
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>笔记标题</span></div></div><div><div><div>3</div></div><div><span>date</span><span>: </span><span>2026-08-04</span></div></div><div><div><div>4</div></div><div><span>type</span><span>: </span><span>article</span></div></div><div><div><div>5</div></div><div><span>tags</span><span>: [</span><span>标签1</span><span>, </span><span>标签2</span><span>]</span></div></div><div><div><div>6</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>保存笔记，Tolaria自动Git提交</li>
</ol></section><section><h3>使用Git同步<a href="#使用git同步"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 添加远程仓库</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>/path/to/your/vault</span></div></div><div><div><div>3</div></div><div><span>git</span><span> </span><span>remote</span><span> </span><span>add</span><span> </span><span>origin</span><span> </span><span>https://github.com/user/your-vault.git</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># 推送</span></div></div><div><div><div>6</div></div><div><span>git</span><span> </span><span>push</span><span> </span><span>-u</span><span> </span><span>origin</span><span> </span><span>main</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span># 其他设备克隆</span></div></div><div><div><div>9</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/user/your-vault.git</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>AI集成（重点）<a href="#ai集成重点"><span>#</span></a></h3><p>Tolaria内置了MCP Server，让AI工具可以直接读取你的笔记：</p><section><h4>配置Claude Code<a href="#配置claude-code"><span>#</span></a></h4><p>在Claude Code中配置MCP Server：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"mcpServers"</span><span>: {</span></div></div><div><div><div>3</div></div><div><span>    </span><span>"tolaria"</span><span>: {</span></div></div><div><div><div>4</div></div><div><span>      </span><span>"command"</span><span>: </span><span>"node"</span><span>,</span></div></div><div><div><div>5</div></div><div><span>      </span><span>"args"</span><span>: [</span><span>"/path/to/tolaria-mcp-server"</span><span>]</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>8</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>配置Codex CLI<a href="#配置codex-cli"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 在Codex CLI配置中添加MCP Server</span></div></div><div><div><div>2</div></div><div><span>codex</span><span> </span><span>configure</span><span> </span><span>add</span><span> </span><span>mcp</span><span> </span><span>tolaria</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>--command</span><span> </span><span>node</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>--args</span><span> </span><span>"/path/to/tolaria-mcp-server"</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>使用AGENTS文件<a href="#使用agents文件"><span>#</span></a></h4><p>Tolaria会为每个知识库生成<code>AGENTS.md</code>文件，告诉AI如何组织和读取笔记。你可以在AI工具中引用这个文件，让AI更好地理解你的知识库结构。</p></section></section><section><h3>快捷键使用<a href="#快捷键使用"><span>#</span></a></h3>

<table><thead><tr><th>功能</th><th>macOS</th><th>Windows/Linux</th></tr></thead><tbody><tr><td>命令面板</td><td>Cmd+K</td><td>Ctrl+K</td></tr><tr><td>新建笔记</td><td>Cmd+N</td><td>Ctrl+N</td></tr><tr><td>保存笔记</td><td>Cmd+S</td><td>Ctrl+S</td></tr><tr><td>全局搜索</td><td>Cmd+Shift+F</td><td>Ctrl+Shift+F</td></tr><tr><td>切换知识库</td><td>Cmd+1/2/3</td><td>Ctrl+1/2/3</td></tr></tbody></table></section></section>
<section><h2>💡 使用场景<a href="#-使用场景"><span>#</span></a></h2><section><h3>个人第二大脑<a href="#个人第二大脑"><span>#</span></a></h3><p>用Tolaria管理你的个人知识库，记录想法、笔记、文章。通过Git同步，在多设备间无缝切换。配合AI功能，让AI成为你的知识助手。</p></section><section><h3>公司文档管理<a href="#公司文档管理"><span>#</span></a></h3><p>将公司文档组织成Markdown知识库，让AI工具可以直接读取和分析。团队成员可以通过Git协作编辑，版本历史完整可追溯。</p></section><section><h3>AI助手记忆存储<a href="#ai助手记忆存储"><span>#</span></a></h3><p>为OpenClaw、Claude Code等AI助手提供记忆存储和程序知识库。AI可以直接读取你的笔记，更好地理解上下文。</p></section><section><h3>技术写作与研究<a href="#技术写作与研究"><span>#</span></a></h3><p>用Tolaria管理技术笔记、研究文档。类型系统帮助你按项目、主题、状态分类组织笔记。</p></section><section><h3>日记与个人发展<a href="#日记与个人发展"><span>#</span></a></h3><p>记录每日想法、反思、成长。通过搜索和筛选功能快速找到历史笔记。</p></section></section>
<section><h2>📊 对比其他工具<a href="#-对比其他工具"><span>#</span></a></h2>

<table><thead><tr><th>功能</th><th>Tolaria</th><th>Obsidian</th><th>Notion</th><th>Logseq</th></tr></thead><tbody><tr><td><strong>文件优先</strong></td><td>✅</td><td>✅</td><td>❌ 云端</td><td>✅</td></tr><tr><td><strong>Git集成</strong></td><td>✅ 内置</td><td>⚠️ 插件</td><td>❌</td><td>⚠️ 插件</td></tr><tr><td><strong>AI集成</strong></td><td>✅ MCP内置</td><td>⚠️ 插件</td><td>✅</td><td>❌</td></tr><tr><td><strong>离线使用</strong></td><td>✅</td><td>✅</td><td>❌</td><td>✅</td></tr><tr><td><strong>开源</strong></td><td>✅ AGPL-3.0</td><td>✅</td><td>❌</td><td>✅</td></tr><tr><td><strong>桌面应用</strong></td><td>✅ Tauri</td><td>✅ Electron</td><td>✅ Web</td><td>✅ Electron</td></tr><tr><td><strong>跨平台</strong></td><td>✅</td><td>✅</td><td>✅</td><td>✅</td></tr></tbody></table></section>
<section><h2>📝 我的使用感受<a href="#-我的使用感受"><span>#</span></a></h2><p>Tolaria是一款非常有思想的知识管理工具！作者是<a href="https://refactoring.fm/" target="_blank">Refactoring</a>的Luca Ronin，他自己用它管理10000+笔记，每个功能都解决了真实的痛点。</p><p>最让我惊喜的是<strong>文件优先</strong>的设计理念。你的笔记就是标准的Markdown文件，任何编辑器都能打开，完全没有锁定。配合Git版本控制，历史版本完整可追溯，数据真正属于你。</p><p>AI集成功能非常实用！内置的MCP Server让Claude Code可以直接读取你的笔记，AI不再是”智障”，而是真正理解你的知识库。AGENTS.md文件也让AI更容易理解你的知识库结构。</p><p>键盘优先的设计也很棒，命令面板操作流畅，快捷键覆盖全面，适合Power用户。</p></section>
<section><h2>🎯 总结<a href="#-总结"><span>#</span></a></h2><p>Tolaria是一款非常优秀的本地优先知识库工具，<strong>完全免费、开源</strong>（AGPL-3.0）。文件优先、Git优先、离线优先、AI优先…设计理念先进，功能实用。如果你想让AI直接读你的笔记，Tolaria绝对值得一试！</p></section>
<section><h2>📌 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>: <a href="https://github.com/refactoringhq/tolaria" target="_blank">https://github.com/refactoringhq/tolaria</a></p><p><strong>下载页面</strong>: <a href="https://refactoringhq.github.io/tolaria/download/" target="_blank">https://refactoringhq.github.io/tolaria/download/</a></p><p><strong>官方文档</strong>: <a href="https://refactoringhq.github.io/tolaria/" target="_blank">https://refactoringhq.github.io/tolaria/</a></p><p><strong>入门知识库</strong>: <a href="https://github.com/refactoringhq/tolaria-getting-started" target="_blank">https://github.com/refactoringhq/tolaria-getting-started</a></p><p><strong>推荐阅读</strong>:</p><ul>
<li><a href="https://mp.weixin.qq.com/s/MYUk0G9eosnYX5a_Etl_PA?token=971541566&amp;lang=zh_CN" target="_blank">GitHub热门项目！OmniGet：一个App下载1800+网站，课程、视频、音乐全搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/3atWsj1GmVG6Q5mfLM7Tzg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！yantr：自托管应用商店，不占用系统资源，130+应用一键部署</a></li>
<li><a href="https://mp.weixin.qq.com/s/tESfza_v76eAVFoS4dnjgg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！BentoPDF：浏览器端隐私优先的PDF工具箱，50+工具一键搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/tm9H33eCtmQCSDoGclENkA?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！PakePlus：网页秒变桌面应用</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/eJi-6JgP_qKF1ZkGwncKIw?token=1716983517&amp;lang=zh_CN" target="_blank">【OCR工具推荐其一】Umi-OCR：图片文字识别，截图、批量、PDF全搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/omniget-intro-2/</id>
      <title type="text">GitHub热门项目！OmniGet：一个App下载1800+网站，课程、视频、音乐全搞定！</title>
      <published>2026-07-28T00:00:00.000Z</published>
      <updated>2026-07-28T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/omniget-intro-2/"/>
      <summary type="text">一款免费开源的桌面应用，支持从1800+网站下载在线课程、视频、音频、音乐和书籍，内置播放器、阅读器、音乐库，一键热键下载，无需命令行，GPL-3.0开源，跨平台支持！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！下载视频、课程的工具太分散了？<a href="#朋友们下载视频课程的工具太分散了"><span>#</span></a></h2><p>做自媒体、学网课的朋友应该都有这种困扰：下载YouTube用一个工具，下载Bilibili用另一个，下载Udemy课程又要找专门的脚本…每个工具都要单独配置，每个网站都要单独适配。更麻烦的是，好多工具只能用命令行，对小白用户极不友好！好家伙，今天给大家介绍一个神器——<strong>OmniGet</strong>！一个App搞定1800+网站，在线课程、视频、音乐、书籍全支持，内置播放器和阅读器，一键热键下载，完全开源免费！</p></section>
<section><h2>📚 项目介绍<a href="#-项目介绍"><span>#</span></a></h2><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/7786ee728ccd496f9ec65e2761b5558420260728143441570.png" alt="" />
<strong>OmniGet</strong> 是一款免费开源的桌面应用，支持Windows、macOS和Linux。它可以从1800+网站下载在线课程、视频、音频、音乐和书籍，下载的内容可以在App内直接播放和阅读。无需命令行，无需Python，无需配置，文件完全保存在本地。</p><section><h3>核心特点<a href="#核心特点"><span>#</span></a></h3><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/45e0c3432c314fefbb50ef6da7d3a69920260728143519605.png" alt="" /></p><ul>
<li>🎓 <strong>在线课程下载</strong>：支持Udemy、Hotmart、Kiwify、Gumroad、Teachable、Kajabi、Skool、Wondrium、Thinkific、Rocketseat等</li>
<li>🎬 <strong>视频音频下载</strong>：YouTube、Instagram、TikTok、Twitter/X、Reddit、Twitch、Pinterest、Vimeo、Bluesky、Bilibili</li>
<li>🇨🇳 <strong>亚洲平台支持</strong>：抖音、小红书、快手、优酷、爱奇艺、腾讯视频、芒果TV</li>
<li>🖼️ <strong>图片画廊</strong>：DeviantArt、Pixiv、ArtStation、Flickr、Tumblr、Imgur相册等</li>
<li>📦 <strong>文件传输</strong>：支持.torrent和磁力链接，支持P2P直传</li>
<li>⌨️ <strong>一键热键</strong>：Ctrl+Shift+D（Mac: Cmd+Shift+D），复制链接按热键即可下载</li>
<li>🎵 <strong>内置播放器</strong>：视频、音频、课程直接播放，支持字幕和笔记</li>
<li>📖 <strong>内置阅读器</strong>：PDF、EPUB、CBZ漫画，支持高亮、书签、专注模式</li>
<li>🎵 <strong>音乐库管理</strong>：MP3、FLAC、M4A等，同步歌词，均衡器</li>
<li>🔌 <strong>插件系统</strong>：课程、学习、Telegram、转换等插件自动安装更新</li>
</ul></section><section><h3>下载能力<a href="#下载能力"><span>#</span></a></h3>

<table><thead><tr><th>分类</th><th>支持平台</th></tr></thead><tbody><tr><td>在线课程</td><td>Hotmart、Udemy、Kiwify、Gumroad、Teachable、Kajabi、Skool、Wondrium、Thinkific、Rocketseat</td></tr><tr><td>视频音频</td><td>YouTube、Instagram、TikTok、Twitter/X、Reddit、Twitch、Pinterest、Vimeo、Bluesky、Bilibili</td></tr><tr><td>Bilibili深度</td><td>4K、HDR、杜比视界、Hi-Res无损、杜比全景声、弹幕、NFO</td></tr><tr><td>亚洲平台</td><td>抖音、小红书、快手、优酷、爱奇艺、腾讯视频、芒果TV</td></tr><tr><td>图片画廊</td><td>DeviantArt、Pixiv、ArtStation、Flickr、Tumblr、Kemono等</td></tr></tbody></table></section></section>
<section><h2>🚀 安装方式<a href="#-安装方式"><span>#</span></a></h2><section><h3>方式一：官网下载（推荐）<a href="#方式一官网下载推荐"><span>#</span></a></h3><p>访问 <a href="https://github.com/tonhowtf/omniget/releases" target="_blank">GitHub Releases</a> 下载最新版本：</p><p><strong>Windows</strong>：下载<code>.exe</code>文件，双击即可运行（便携版，无需安装）</p><p><strong>macOS</strong>：打开<code>.dmg</code>，将OmniGet拖入Applications文件夹</p><p><strong>Linux</strong>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Flatpak安装（推荐）</span></div></div><div><div><div>2</div></div><div><span>flatpak</span><span> </span><span>install</span><span> </span><span>wtf.tonho.omniget</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 或下载AppImage直接运行</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>首次启动说明<a href="#首次启动说明"><span>#</span></a></h3><p>由于OmniGet是开源软件，未购买代码签名证书，首次启动时系统可能会警告，这是正常现象：</p><p><strong>macOS</strong>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 打开终端，运行以下两条命令（仅需一次）</span></div></div><div><div><div>2</div></div><div><span>xattr</span><span> </span><span>-cr</span><span> </span><span>/Applications/omniget.app</span></div></div><div><div><div>3</div></div><div><span>codesign</span><span> </span><span>--force</span><span> </span><span>--deep</span><span> </span><span>--sign</span><span> </span><span>-</span><span> </span><span>/Applications/omniget.app</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>Windows</strong>：点击”更多信息”→“仍要运行”即可</p></section></section>
<section><h2>🎯 使用指南<a href="#-使用指南"><span>#</span></a></h2><section><h3>一键热键下载（最常用）<a href="#一键热键下载最常用"><span>#</span></a></h3><ol>
<li>复制任意链接（YouTube视频、Tweet、Discord消息、歌曲、磁力链接等）</li>
<li>按下全局热键 <strong><code>Ctrl+Shift+D</code></strong>（Mac: <strong><code>Cmd+Shift+D</code></strong>）</li>
<li>OmniGet自动读取剪贴板，后台下载</li>
<li>文件下载完成后自动保存到指定文件夹</li>
</ol><blockquote><p>💡 小技巧：在任何应用中都可以使用热键，浏览网页、聊天、阅读时随时下载</p></blockquote></section><section><h3>手动输入下载<a href="#手动输入下载"><span>#</span></a></h3><p>如果想先预览再下载：</p><ol>
<li>打开OmniGet主界面</li>
<li>在搜索框中粘贴链接</li>
<li>查看预览和画质选项</li>
<li>点击下载按钮</li>
</ol></section><section><h3>Bilibili深度下载<a href="#bilibili深度下载"><span>#</span></a></h3><ol>
<li>打开OmniGet设置</li>
<li>登录Bilibili账号（可选，登录后解锁4K、HDR、Hi-Res无损等）</li>
<li>复制Bilibili视频链接</li>
<li>按下热键或粘贴到搜索框</li>
<li>选择画质和下载选项</li>
</ol><p><strong>支持的URL类型</strong>：UP主主页、番剧、课程、收藏夹、每周必看、稍后再看、历史记录、b23.tv短链</p></section><section><h3>批量下载<a href="#批量下载"><span>#</span></a></h3><p><strong>方式一：文件批量</strong></p><ol>
<li>将多个链接保存到文本文件中</li>
<li>在OmniGet中选择”批量导入”</li>
<li>选择文本文件，开始批量下载</li>
</ol><p><strong>方式二：博主主页批量</strong></p><ol>
<li>复制博主主页链接</li>
<li>粘贴到OmniGet搜索框</li>
<li>选择批量下载所有作品</li>
</ol></section><section><h3>下载课程并观看<a href="#下载课程并观看"><span>#</span></a></h3><ol>
<li>复制Udemy/Hotmart等课程链接</li>
<li>粘贴到OmniGet，下载完整课程</li>
<li>下载完成后，在OmniGet内直接播放</li>
<li>支持断点续播，从上次停止的地方继续</li>
<li>可以添加笔记，笔记会跳转到对应时间点</li>
<li>支持侧边栏查看课程附件PDF
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/621205071dda419fbdf6af1ea2b17ac220260728143054272.png" alt="" /></li>
</ol></section><section><h3>阅读书籍<a href="#阅读书籍"><span>#</span></a></h3><ol>
<li>将PDF/EPUB/CBZ漫画文件拖入OmniGet</li>
<li>OmniGet自动提取封面、标题、作者</li>
<li>支持高亮、书签、专注模式</li>
<li>支持纸质阅读主题，护眼舒适
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/d818831a828241d58b076df5c768839520260728143126118.png" alt="" /></li>
</ol></section><section><h3>音乐库管理<a href="#音乐库管理"><span>#</span></a></h3><ol>
<li>指向本地音乐文件夹</li>
<li>以iTunes风格展示：专辑封面、艺术家目录、播放队列</li>
<li>支持MP3、FLAC、M4A、OGG、Opus等格式</li>
<li>同步歌词，随歌曲滚动</li>
<li>连接Spotify、SoundCloud、YouTube Music、Qobuz、Last.fm</li>
<li>内置均衡器，多种预设
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/d4c76fda2f854d98bfbc548269f31dcc20260728143157000.png" alt="" /></li>
</ol></section></section>
<section><h2>💡 使用场景<a href="#-使用场景"><span>#</span></a></h2><section><h3>学生党：在线课程下载<a href="#学生党在线课程下载"><span>#</span></a></h3><p>下载Udemy、Hotmart等在线课程，在App内观看，支持笔记和断点续播。再也不用担心课程下架找不到资源了！</p></section><section><h3>自媒体创作者：素材收集<a href="#自媒体创作者素材收集"><span>#</span></a></h3><p>从YouTube、Bilibili、抖音等平台收集素材，批量下载，快速获取内容。支持4K、HDR等高质量下载。</p></section><section><h3>音乐爱好者：音乐库管理<a href="#音乐爱好者音乐库管理"><span>#</span></a></h3><p>管理本地音乐，同步歌词，连接流媒体平台。一个App搞定所有音乐需求。</p></section><section><h3>书籍爱好者：电子书阅读<a href="#书籍爱好者电子书阅读"><span>#</span></a></h3><p>将PDF、EPUB导入OmniGet，统一阅读体验。支持高亮、书签、专注模式。</p></section><section><h3>研究者：资料收集<a href="#研究者资料收集"><span>#</span></a></h3><p>从Reddit、Twitter/X、学术平台下载资料，批量保存，方便后续研究。</p></section></section>
<section><h2>📝 我的使用感受<a href="#-我的使用感受"><span>#</span></a></h2><p>OmniGet真的是一款让人惊艳的工具！以前下载视频、课程、音乐要用好几个工具，现在一个OmniGet全搞定！</p><p>最让我惊喜的是一键热键功能，复制链接按个热键就下载了，完全不用打开窗口，太方便了！而且下载速度很快，进度条和剩余时间显示准确。</p><p>内置的播放器和阅读器也很强大，下载的课程可以直接在App内观看，笔记功能也很实用。音乐库的同步歌词和均衡器功能也很贴心。</p><p>Bilibili的深度支持让我非常满意，登录后可以下载4K画质，还有弹幕功能，简直完美！</p></section>
<section><h2>🎯 总结<a href="#-总结"><span>#</span></a></h2><p>OmniGet是一款非常强大的全能下载工具，<strong>完全免费、开源</strong>（GPL-3.0）。1800+网站支持、在线课程下载、内置播放器/阅读器/音乐库、一键热键、批量下载…功能强大到让你挑花眼！如果你经常需要下载视频、课程、音乐、书籍，OmniGet绝对值得一试！</p></section>
<section><h2>📌 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>: <a href="https://github.com/tonhowtf/omniget" target="_blank">https://github.com/tonhowtf/omniget</a></p><p><strong>推荐阅读</strong>:</p><ul>
<li><a href="https://mp.weixin.qq.com/s/s6Sr-XEzkZku-K79h-8hRw?token=1716983517&amp;lang=zh_CN" target="_blank">Windows越用越卡？这个开源工具，一键瘦身、优化、自定义全搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/3atWsj1GmVG6Q5mfLM7Tzg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！yantr：自托管应用商店，不占用系统资源，130+应用一键部署</a></li>
<li><a href="https://mp.weixin.qq.com/s/tESfza_v76eAVFoS4dnjgg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！BentoPDF：浏览器端隐私优先的PDF工具箱，50+工具一键搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/tm9H33eCtmQCSDoGclENkA?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！PakePlus：网页秒变桌面应用</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/eJi-6JgP_qKF1ZkGwncKIw?token=1716983517&amp;lang=zh_CN" target="_blank">【OCR工具推荐其一】Umi-OCR：图片文字识别，截图、批量、PDF全搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/docker/hubproxy-intro/</id>
      <title type="text">GitHub热门项目！HubProxy：Docker+GitHub加速神器，一个服务搞定所有镜像拉取！</title>
      <published>2026-07-14T00:00:00.000Z</published>
      <updated>2026-07-14T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/docker/hubproxy-intro/"/>
      <summary type="text">一款轻量级Docker和GitHub加速代理服务器，支持Docker镜像加速（Docker Hub、GHCR、Quay）、GitHub文件加速、离线镜像下载、Hugging Face模型加速，智能限流保护，完全自托管，一个服务搞定所有加速需求！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！Docker镜像拉取太慢？GitHub下载不了？<a href="#朋友们docker镜像拉取太慢github下载不了"><span>#</span></a></h2><p>做开发的朋友应该都遇到过这种情况：拉取Docker镜像半天不动，GitHub Release下载超时，Hugging Face模型下载失败…换了各种免费加速服务，要么不稳定，要么限流。好家伙，今天给大家介绍一个神器——<strong>HubProxy</strong>！一个服务搞定Docker镜像加速、GitHub文件加速、离线镜像下载，完全自托管，再也不用担心依赖第三方服务了！</p></section>
<section><h2>📚 项目介绍<a href="#-项目介绍"><span>#</span></a></h2><p><strong>HubProxy</strong> 是一个轻量级、高性能的多功能代理服务，基于Go语言开发，单二进制文件运行，资源占用极低。它提供Docker镜像加速、GitHub文件加速、离线镜像下载、在线搜索Docker镜像等功能，支持Docker Hub、GHCR、Quay等多个镜像仓库，是开发人员必备的加速工具！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/f2602b40b6d74bc7bde01058ef27a2fd20260714162433694.png" alt="" /></p><section><h3>核心特点<a href="#核心特点"><span>#</span></a></h3><ul>
<li>🐳 <strong>Docker镜像加速</strong>：支持Docker Hub、GHCR、Quay、gcr.io、registry.k8s.io等多个镜像仓库，流式传输优化拉取速度</li>
<li>📁 <strong>GitHub文件加速</strong>：加速GitHub Release、Raw文件下载，支持api.github.com，脚本嵌套加速</li>
<li>📦 <strong>离线镜像包</strong>：支持下载离线镜像包，流式传输加防抖设计，方便离线部署</li>
<li>🤖 <strong>AI模型库支持</strong>：支持Hugging Face模型下载加速，训练大模型不再愁</li>
<li>🛡️ <strong>智能限流</strong>：IP限流保护，防止滥用，支持白名单和黑名单</li>
<li>🔍 <strong>镜像搜索</strong>：在线搜索Docker镜像，快速找到需要的镜像</li>
<li>⚡ <strong>轻量高效</strong>：基于Go语言，单二进制文件运行，资源占用低</li>
<li>🔧 <strong>统一配置</strong>：统一配置管理，便于维护</li>
<li>🛡️ <strong>完全自托管</strong>：避免依赖免费第三方服务的不稳定性</li>
<li>🚀 <strong>多服务统一加速</strong>：单个程序即可统一加速Docker、GitHub、Hugging Face等多种服务</li>
</ul></section></section>
<section><h2>🚀 部署方式<a href="#-部署方式"><span>#</span></a></h2><section><h3>方式一：Docker部署（推荐）<a href="#方式一docker部署推荐"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>--name</span><span> </span><span>hubproxy</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>-p</span><span> </span><span>5000:5000</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>--restart</span><span> </span><span>always</span><span> </span><span>\</span></div></div><div><div><div>5</div></div><div><span>  </span><span>ghcr.io/sky22333/hubproxy</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>方式二：Docker Compose<a href="#方式二docker-compose"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>version</span><span>: </span><span>'3.8'</span></div></div><div><div><div>2</div></div><div><span>services</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>hubproxy</span><span>:</span></div></div><div><div><div>4</div></div><div><span>    </span><span>image</span><span>: </span><span>ghcr.io/sky22333/hubproxy</span></div></div><div><div><div>5</div></div><div><span>    </span><span>container_name</span><span>: </span><span>hubproxy</span></div></div><div><div><div>6</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>"5000:5000"</span></div></div><div><div><div>8</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>- </span><span>SERVER_PORT=5000</span></div></div><div><div><div>10</div></div><div><span><span>      </span></span><span>- </span><span>ENABLE_FRONTEND=true</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>- </span><span>IP_WHITELIST=127.0.0.1,192.168.1.0/24</span></div></div><div><div><div>12</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span>- </span><span>./config:/etc/hubproxy</span></div></div><div><div><div>14</div></div><div><span>    </span><span>restart</span><span>: </span><span>always</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>方式三：脚本安装<a href="#方式三脚本安装"><span>#</span></a></h3><p>自动识别系统与架构，从GitHub Releases下载对应的安装包：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>curl</span><span> </span><span>-fsSL</span><span> </span><span>https://raw.githubusercontent.com/sky22333/hubproxy/main/install.sh</span><span> | </span><span>sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>安装完成后，服务会自动启动。</p></section></section>
<section><h2>🎯 使用指南<a href="#-使用指南"><span>#</span></a></h2><section><h3>Docker镜像加速<a href="#docker镜像加速"><span>#</span></a></h3><p><strong>方式一：直接使用加速地址</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 原命令</span></div></div><div><div><div>2</div></div><div><span>docker</span><span> </span><span>pull</span><span> </span><span>nginx</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 使用加速</span></div></div><div><div><div>5</div></div><div><span>docker</span><span> </span><span>pull</span><span> </span><span>yourdomain.com/nginx</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># GHCR加速</span></div></div><div><div><div>8</div></div><div><span>docker</span><span> </span><span>pull</span><span> </span><span>yourdomain.com/ghcr.io/sky22333/hubproxy</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式二：配置为全局镜像加速</strong></p><p>编辑 <code>/etc/docker/daemon.json</code> 文件：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"registry-mirrors"</span><span>: [</span></div></div><div><div><div>3</div></div><div><span>    </span><span>"https://yourdomain.com"</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>]</span></div></div><div><div><div>5</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>保存后重启Docker服务：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>systemctl</span><span> </span><span>restart</span><span> </span><span>docker</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>GitHub文件加速<a href="#github文件加速"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 原链接</span></div></div><div><div><div>2</div></div><div><span>https://github.com/user/repo/releases/download/v1.0.0/file.tar.gz</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 加速链接</span></div></div><div><div><div>5</div></div><div><span>https://yourdomain.com/https://github.com/user/repo/releases/download/v1.0.0/file.tar.gz</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 加速下载仓库</span></div></div><div><div><div>8</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://yourdomain.com/https://github.com/sky22333/hubproxy.git</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Hugging Face模型加速<a href="#hugging-face模型加速"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 原链接</span></div></div><div><div><div>2</div></div><div><span>https://huggingface.co/user/model/resolve/main/model.bin</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 加速链接</span></div></div><div><div><div>5</div></div><div><span>https://yourdomain.com/https://huggingface.co/user/model/resolve/main/model.bin</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>离线镜像下载<a href="#离线镜像下载"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 下载单个镜像</span></div></div><div><div><div>2</div></div><div><span>curl</span><span> </span><span>-X</span><span> </span><span>POST</span><span> </span><span>http://yourdomain.com/api/download</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>-H</span><span> </span><span>"Content-Type: application/json"</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>-d</span><span> </span><span>'{"images": ["nginx:latest", "ubuntu:22.04"]}'</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span># 下载多个镜像</span></div></div><div><div><div>7</div></div><div><span>curl</span><span> </span><span>-X</span><span> </span><span>POST</span><span> </span><span>http://yourdomain.com/api/download</span><span> </span><span>\</span></div></div><div><div><div>8</div></div><div><span>  </span><span>-H</span><span> </span><span>"Content-Type: application/json"</span><span> </span><span>\</span></div></div><div><div><div>9</div></div><div><span>  </span><span>-d</span><span> </span><span>'{"images": ["ghcr.io/sky22333/hubproxy:latest", "redis:alpine"]}'</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>镜像搜索<a href="#镜像搜索"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 搜索镜像</span></div></div><div><div><div>2</div></div><div><span>curl</span><span> </span><span>http://yourdomain.com/api/search?q=nginx</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 搜索结果示例</span></div></div><div><div><div>5</div></div><div><span>{</span></div></div><div><div><div>6</div></div><div><span>  </span><span>"results"</span><span>:</span><span> [</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>8</div></div><div><span>      </span><span>"name"</span><span>:</span><span> </span><span>"nginx",</span></div></div><div><div><div>9</div></div><div><span>      </span><span>"description"</span><span>:</span><span> </span><span>"Official build of Nginx.",</span></div></div><div><div><div>10</div></div><div><span>      </span><span>"stars"</span><span>:</span><span> </span><span>18000,</span></div></div><div><div><div>11</div></div><div><span>      </span><span>"pulls"</span><span>:</span><span> </span><span>1000000000</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>13</div></div><div><span><span>  </span></span><span>]</span></div></div><div><div><div>14</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>📊 对比其他方案<a href="#-对比其他方案"><span>#</span></a></h2>

<table><thead><tr><th>功能</th><th>HubProxy</th><th>免费第三方加速</th><th>Cloudflare Workers</th></tr></thead><tbody><tr><td><strong>Docker镜像加速</strong></td><td>✅ 多仓库支持</td><td>✅ 部分支持</td><td>❌</td></tr><tr><td><strong>GitHub文件加速</strong></td><td>✅</td><td>✅</td><td>✅</td></tr><tr><td><strong>离线镜像下载</strong></td><td>✅</td><td>❌</td><td>❌</td></tr><tr><td><strong>AI模型加速</strong></td><td>✅</td><td>❌</td><td>❌</td></tr><tr><td><strong>智能限流</strong></td><td>✅</td><td>❌</td><td>❌</td></tr><tr><td><strong>仓库审计</strong></td><td>✅</td><td>❌</td><td>❌</td></tr><tr><td><strong>完全自托管</strong></td><td>✅</td><td>❌</td><td>❌</td></tr><tr><td><strong>稳定性</strong></td><td>✅ 自建可控</td><td>❌ 不稳定</td><td>⚠️ 限流</td></tr></tbody></table></section>
<section><h2>💡 使用场景<a href="#-使用场景"><span>#</span></a></h2><section><h3>开发团队：统一加速服务<a href="#开发团队统一加速服务"><span>#</span></a></h3><p>在团队中部署一个HubProxy服务，所有成员共享使用。无需每个人都配置不同的加速地址，统一管理，方便维护。同时智能限流保护服务不被滥用。</p></section><section><h3>CI/CD流水线：加速构建过程<a href="#cicd流水线加速构建过程"><span>#</span></a></h3><p>在CI/CD流水线中使用HubProxy加速Docker镜像拉取和GitHub资源下载，大幅缩短构建时间，提升开发效率。</p></section><section><h3>离线部署：下载离线镜像包<a href="#离线部署下载离线镜像包"><span>#</span></a></h3><p>在无法访问外网的环境中，可以先使用HubProxy下载离线镜像包，然后传输到目标环境进行部署。</p></section><section><h3>AI训练：加速模型下载<a href="#ai训练加速模型下载"><span>#</span></a></h3><p>训练大模型时，从Hugging Face下载模型文件经常失败。使用HubProxy加速下载，提高下载成功率。</p></section><section><h3>个人开发者：摆脱加速依赖<a href="#个人开发者摆脱加速依赖"><span>#</span></a></h3><p>作为个人开发者，不再依赖不稳定的免费第三方加速服务，自己部署一个稳定可靠的加速服务。</p></section></section>
<section><h2>📝 我的使用感受<a href="#-我的使用感受"><span>#</span></a></h2><p>部署HubProxy后，我再也没有遇到过Docker镜像拉取失败的问题了！以前拉取ghcr.io的镜像经常超时，现在秒速完成。GitHub Release下载也快了很多，特别是下载大文件的时候。</p><p>最让我惊喜的是离线镜像下载功能，有时候需要在没有外网的环境部署，这个功能简直太实用了！</p><p>配置也很简单，一行Docker命令就能启动，默认配置已经很好用了。如果需要自定义，修改config.toml文件即可。</p></section>
<section><h2>🎯 总结<a href="#-总结"><span>#</span></a></h2><p>HubProxy是一款非常强大的加速代理服务，<strong>完全免费、开源</strong>。Docker镜像加速、GitHub文件加速、离线镜像下载、AI模型加速…一个服务搞定所有加速需求！如果你是开发人员、运维人员，或者经常遇到镜像拉取慢、文件下载失败的问题，HubProxy绝对值得一试！</p></section>
<section><h2>📌 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>: <a href="https://github.com/sky22333/hubproxy" target="_blank">https://github.com/sky22333/hubproxy</a></p><p><strong>Docker镜像</strong>: <code>ghcr.io/sky22333/hubproxy</code></p><p><strong>推荐阅读</strong>:</p><ul>
<li><a href="https://mp.weixin.qq.com/s/s6Sr-XEzkZku-K79h-8hRw?token=1716983517&amp;lang=zh_CN" target="_blank">Windows越用越卡？这个开源工具，一键瘦身、优化、自定义全搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/3atWsj1GmVG6Q5mfLM7Tzg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！yantr：自托管应用商店，不占用系统资源，130+应用一键部署</a></li>
<li><a href="https://mp.weixin.qq.com/s/tESfza_v76eAVFoS4dnjgg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！BentoPDF：浏览器端隐私优先的PDF工具箱，50+工具一键搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/tm9H33eCtmQCSDoGclENkA?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！PakePlus：网页秒变桌面应用</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/eJi-6JgP_qKF1ZkGwncKIw?token=1716983517&amp;lang=zh_CN" target="_blank">【OCR工具推荐其一】Umi-OCR：图片文字识别，截图、批量、PDF全搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/ai/omniroute-intro/</id>
      <title type="text">GitHub热门项目！OmniRoute：一个端点连接237个AI服务商，每月16亿免费Token！</title>
      <published>2026-07-08T00:00:00.000Z</published>
      <updated>2026-07-08T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/ai/omniroute-intro/"/>
      <summary type="text">一款开源AI网关项目，一个端点连接237个AI服务商（90+免费），支持自动故障转移、RTK+Caveman压缩节省15-95%Token、每月约16亿免费Token，兼容Claude Code、Cursor、Copilot等所有编码工具！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！AI接口总断连？Token不够用？<a href="#朋友们ai接口总断连token不够用"><span>#</span></a></h2><p>做开发的朋友应该都遇到过这种情况：用着用着AI接口突然断了，要么是额度用完了，要么是服务商限流了。换一个服务商又要重新配置，太麻烦了！好家伙，今天给大家介绍一个神器——<strong>OmniRoute</strong>！一个端点连接237个AI服务商，自动故障转移，每月16亿免费Token，让你再也不用担心接口断连！</p></section>
<section><h2>📚 项目介绍<a href="#-项目介绍"><span>#</span></a></h2><p><strong>OmniRoute</strong> 是一个开源的AI网关项目，一个端点就能连接237个AI服务商（90+免费），支持自动故障转移、Token压缩、成本优化等功能。它就像一个AI接口的路由器，智能选择最合适的服务商，让你的AI应用永不中断！最重要的是，它兼容Claude Code、Cursor、Copilot等所有编码工具，只需配置一次就能全部使用！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/b0de48e6d8914d828ae137d01b47b10620260708140430439.png" alt="" /></p><section><h3>核心特点<a href="#核心特点"><span>#</span></a></h3><ul>
<li>🌐 <strong>237个AI服务商</strong>：一个端点连接OpenAI、Claude、Gemini、DeepSeek、阿里Qwen等237个服务商</li>
<li>🆓 <strong>90+免费服务商</strong>：11个永久免费（Kiro、Qoder、Pollinations、LongCat等），无需信用卡</li>
<li>🔄 <strong>自动故障转移</strong>：4层自动降级（订阅→API→便宜→免费），毫秒级切换，零停机
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/a9b84c3b43624fda9b1154bc9b74787f20260708170044770.png" alt="" /></li>
<li>🗜️ <strong>Token压缩</strong>：RTK + Caveman压缩技术，节省15-95%的Token（工具密集型会话平均节省89%）
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/8645685679b64430bbb1350ca5769c1420260708170137662.png" alt="" /></li>
<li>💰 <strong>成本优化路由</strong>：自动选择最便宜的可用模型，最大化订阅额度</li>
<li>🔌 <strong>兼容所有工具</strong>：Claude Code、Cursor、Cline、Copilot、Antigravity等16+编码工具
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/e314aea13b49466ca4189ac7c81358a520260708165924773.png" alt="" /></li>
<li>🔒 <strong>生产级安全</strong>：熔断机制、TLS隐身、MCP（87个工具）、A2A、内存管理、防护栏、评估
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/6827d92ecdd44ce6aa2a5ce0eb39ea4c20260708170159654.png" alt="" /></li>
<li>📊 <strong>免费Token仪表盘</strong>：实时显示每月约16亿免费Token的使用情况
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/12b89b8841ed4557bacf059a0f50413d20260708170235176.png" alt="" /></li>
<li>🌍 <strong>全球访问</strong>：3层代理 + TLS指纹隐身，任何国家都能使用AI
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/350bea279aa84af284c56f8dd756044120260708170217682.png" alt="" /></li>
<li>📱 <strong>多种部署方式</strong>：Docker、Docker Compose、Electron桌面应用、Fly.io
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/b0d17dc905e941a1ad5ffcb454223ba920260708165950857.png" alt="" /></li>
</ul></section></section>
<section><h2>🚀 使用指南<a href="#-使用指南"><span>#</span></a></h2><section><h3>安装方式<a href="#安装方式"><span>#</span></a></h3><p><strong>方式一：Docker快速启动</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-p</span><span> </span><span>20128:20128</span><span> </span><span>diegosouzapw/omniroute:latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式二：Electron桌面应用</strong></p><p>从GitHub Releases页面下载桌面客户端，双击安装即可使用。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/62e920d88f07403ea2eff290496424a320260708170554504.png" alt="" /></p></section><section><h3>配置方式<a href="#配置方式"><span>#</span></a></h3><p>在 <code>.env</code> 文件中配置服务商API密钥：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># OpenAI</span></div></div><div><div><div>2</div></div><div><span>OPENAI_API_KEY</span><span>=</span><span>your-key</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># Claude</span></div></div><div><div><div>5</div></div><div><span>ANTHROPIC_API_KEY</span><span>=</span><span>your-key</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># Gemini</span></div></div><div><div><div>8</div></div><div><span>GEMINI_API_KEY</span><span>=</span><span>your-key</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># DeepSeek</span></div></div><div><div><div>11</div></div><div><span>DEEPSEEK_API_KEY</span><span>=</span><span>your-key</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># 更多服务商...</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>使用方式<a href="#使用方式"><span>#</span></a></h3><p>配置完成后，所有AI工具只需指向一个端点：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># OpenAI兼容端点</span></div></div><div><div><div>2</div></div><div><span>http://localhost:20128/v1</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># Claude兼容端点</span></div></div><div><div><div>5</div></div><div><span>http://localhost:20128/v1/claude</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在IDE或CLI中配置这个端点，所有编码工具都能使用！</p></section><section><h3>路由策略<a href="#路由策略"><span>#</span></a></h3><p>OmniRoute支持17种路由策略：</p><ul>
<li><strong>成本优先</strong>：自动选择最便宜的可用模型</li>
<li><strong>性能优先</strong>：选择响应最快的模型</li>
<li><strong>质量优先</strong>：选择最高质量的模型</li>
<li><strong>自动故障转移</strong>：依次尝试订阅→API→便宜→免费</li>
<li><strong>轮询</strong>：按顺序轮询所有可用服务商</li>
</ul></section></section>
<section><h2>💡 使用场景<a href="#-使用场景"><span>#</span></a></h2><section><h3>AI应用开发者：永不中断的AI服务<a href="#ai应用开发者永不中断的ai服务"><span>#</span></a></h3><p>作为AI应用开发者，你再也不用担心某个服务商限流或断连。OmniRoute会自动切换到其他可用服务商，保证你的应用永不中断。同时，成本优化路由会选择最便宜的模型，大幅降低API费用。</p></section><section><h3>编码工具用户：一次配置，全部使用<a href="#编码工具用户一次配置全部使用"><span>#</span></a></h3><p>如果你同时使用Claude Code、Cursor、Copilot等多种编码工具，每个工具都需要配置不同的API密钥，非常麻烦。现在只需配置OmniRoute的端点，所有工具都能使用，还能享受自动故障转移和Token压缩。</p></section><section><h3>AI研究人员：访问所有模型<a href="#ai研究人员访问所有模型"><span>#</span></a></h3><p>作为AI研究人员，你需要对比不同模型的效果。OmniRoute让你通过一个端点访问237个服务商的500+模型，无需分别注册和配置。</p></section><section><h3>团队协作：统一管理AI资源<a href="#团队协作统一管理ai资源"><span>#</span></a></h3><p>在团队中，不同成员可能使用不同的AI服务商。OmniRoute提供统一的管理界面，管理员可以集中管理所有API密钥，设置访问权限，追踪Token使用情况。</p></section><section><h3>全球用户：突破地域限制<a href="#全球用户突破地域限制"><span>#</span></a></h3><p>如果你所在的国家无法访问某些AI服务商，OmniRoute的3层代理和TLS指纹隐身功能可以帮你突破限制，从任何地方使用AI服务。</p></section></section>
<section><h2>📝 我的使用感受<a href="#-我的使用感受"><span>#</span></a></h2><p>以前用OpenAI的时候，经常遇到限流的问题，代码写到一半突然断了，特别烦人。现在OmniRoute会自动切换到其他服务商，几乎感觉不到中断！</p><p>而且<strong>Token压缩</strong>也很实用。我用Claude Code写代码的时候，工具输出的git diff、grep结果、日志等内容特别多，特别费Token。现在经过压缩后，平均能节省89%的Token，API费用大幅降低！</p><p>唯一需要注意的是，首次配置需要添加一些服务商的API密钥，但配置一次后就不用管了，非常省心。</p></section>
<section><h2>🎯 总结<a href="#-总结"><span>#</span></a></h2><p>OmniRoute是一款非常强大的AI网关项目，<strong>完全免费、开源</strong>。237个AI服务商、自动故障转移、Token压缩、成本优化…功能强大到让你挑花眼。如果你是AI应用开发者、编码工具用户、AI研究人员，或者经常遇到AI接口断连的问题，OmniRoute绝对值得一试！</p></section>
<section><h2>📌 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>: <a href="https://github.com/diegosouzapw/OmniRoute" target="_blank">https://github.com/diegosouzapw/OmniRoute</a></p><p><strong>官方网站</strong>: <a href="https://omniroute.online/" target="_blank">https://omniroute.online/</a></p><p><strong>推荐阅读</strong>:</p><ul>
<li><a href="https://mp.weixin.qq.com/s/s6Sr-XEzkZku-K79h-8hRw?token=1716983517&amp;lang=zh_CN" target="_blank">Windows越用越卡？这个开源工具，一键瘦身、优化、自定义全搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/3atWsj1GmVG6Q5mfLM7Tzg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！yantr：自托管应用商店，不占用系统资源，130+应用一键部署</a></li>
<li><a href="https://mp.weixin.qq.com/s/tESfza_v76eAVFoS4dnjgg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！BentoPDF：浏览器端隐私优先的PDF工具箱，50+工具一键搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/tm9H33eCtmQCSDoGclENkA?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！PakePlus：网页秒变桌面应用</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/eJi-6JgP_qKF1ZkGwncKIw?token=1716983517&amp;lang=zh_CN" target="_blank">【OCR工具推荐其一】Umi-OCR：图片文字识别，截图、批量、PDF全搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/playwright-intro/</id>
      <title type="text">网页测试太难？微软Playwright：一套API搞定三大浏览器，自动等待超智能</title>
      <published>2026-07-08T00:00:00.000Z</published>
      <updated>2026-07-08T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/playwright-intro/"/>
      <summary type="text">微软出品的开源网页自动化框架，支持Chromium、Firefox、WebKit三大浏览器，提供Playwright Test测试框架、MCP服务器、CLI工具等多种使用方式。自动等待、定位器、测试隔离、追踪等特性让网页测试和自动化变得简单高效！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！网页测试和自动化太难了？<a href="#朋友们网页测试和自动化太难了"><span>#</span></a></h2><p>做前端开发的朋友应该都遇到过这种情况：每次改完代码，都要手动打开浏览器测试各种场景，费时费力。或者想写个脚本自动化处理网页内容，结果被各种等待和定位问题折腾得死去活来。好家伙，今天给大家介绍一个神器——<strong>Playwright</strong>！微软出品，支持三大浏览器，自动等待、智能定位，让网页测试和自动化变得超级简单！</p></section>
<section><h2>📚 项目介绍<a href="#-项目介绍"><span>#</span></a></h2><p><strong>Playwright</strong> 是微软开发的一款开源网页自动化框架，支持 Chromium、Firefox、WebKit 三大浏览器，只需一套 API 就能在所有浏览器上运行。它不仅可以用来做端到端测试，还能用来做网页自动化、爬虫、PDF生成等。最重要的是，它支持 AI 代理集成，让 AI 可以直接控制浏览器！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/048b7a5c8ed94f9cb1f9e6836e531b2320260708085420200.png" alt="" /></p><section><h3>核心特点<a href="#核心特点"><span>#</span></a></h3><ul>
<li>🎭 <strong>跨浏览器支持</strong>：一套API支持Chromium、Firefox、WebKit，真正的跨浏览器测试</li>
<li>⏱️ <strong>自动等待</strong>：不需要写 <code>sleep()</code>，自动等待元素可交互后再操作</li>
<li>🎯 <strong>智能定位器</strong>：支持按角色、标签、占位符、测试ID等多种方式定位元素</li>
<li>🔒 <strong>测试隔离</strong>：每个测试在独立的浏览器上下文运行，互不干扰</li>
<li>📋 <strong>追踪功能</strong>：测试失败时自动生成追踪文件，包含完整的执行记录</li>
<li>🚀 <strong>并行执行</strong>：默认并行运行所有测试，大幅提升效率</li>
<li>🤖 <strong>AI代理集成</strong>：支持MCP协议和CLI工具，AI可以直接控制浏览器</li>
<li>📱 <strong>移动端模拟</strong>：支持模拟各种移动设备，测试响应式网站</li>
<li>🌐 <strong>网络拦截</strong>：可以拦截和修改网络请求，方便测试各种场景</li>
<li>📝 <strong>多语言支持</strong>：支持TypeScript、Python、.NET、Java四种语言</li>
</ul></section></section>
<section><h2>🚀 使用指南<a href="#-使用指南"><span>#</span></a></h2><section><h3>安装方式<a href="#安装方式"><span>#</span></a></h3><p><strong>方式一：Playwright Test（端到端测试）</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 初始化项目</span></div></div><div><div><div>2</div></div><div><span>npm</span><span> </span><span>init</span><span> </span><span>playwright@latest</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 安装依赖</span></div></div><div><div><div>5</div></div><div><span>npm</span><span> </span><span>i</span><span> </span><span>-D</span><span> </span><span>@playwright/test</span></div></div><div><div><div>6</div></div><div><span>npx</span><span> </span><span>playwright</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式二：Playwright Library（自动化脚本）</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>i</span><span> </span><span>playwright</span></div></div><div><div><div>2</div></div><div><span>npx</span><span> </span><span>playwright</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式三：Playwright MCP（AI代理）</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 在MCP配置中添加</span></div></div><div><div><div>2</div></div><div><span>npx</span><span> </span><span>@playwright/mcp@latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式四：Playwright CLI（命令行工具）</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>-g</span><span> </span><span>@playwright/cli@latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>核心功能使用<a href="#核心功能使用"><span>#</span></a></h3><section><h4>1. 编写端到端测试<a href="#1-编写端到端测试"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> { </span><span>test</span><span>, </span><span>expect</span><span> } </span><span>from</span><span> </span><span>'@playwright/test'</span><span>;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>test</span><span>(</span><span>'has title'</span><span>, </span><span>async</span><span><span> ({ </span><span>page</span><span> }) </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>4</div></div><div><span>  </span><span>await</span><span><span> </span><span>page</span><span>.</span></span><span>goto</span><span>(</span><span>'https://playwright.dev/'</span><span>);</span></div></div><div><div><div>5</div></div><div><span>  </span><span>await</span><span> </span><span>expect</span><span><span>(</span><span>page</span><span>).</span></span><span>toHaveTitle</span><span>(</span><span>/Playwright/</span><span>);</span></div></div><div><div><div>6</div></div><div><span>});</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span>test</span><span>(</span><span>'get started link'</span><span>, </span><span>async</span><span><span> ({ </span><span>page</span><span> }) </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>9</div></div><div><span>  </span><span>await</span><span><span> </span><span>page</span><span>.</span></span><span>goto</span><span>(</span><span>'https://playwright.dev/'</span><span>);</span></div></div><div><div><div>10</div></div><div><span>  </span><span>await</span><span><span> </span><span>page</span><span>.</span></span><span>getByRole</span><span>(</span><span>'link'</span><span>, { </span><span>name</span><span>:</span><span> </span><span>'Get started'</span><span> }).</span><span>click</span><span>();</span></div></div><div><div><div>11</div></div><div><span>  </span><span>await</span><span> </span><span>expect</span><span><span>(</span><span>page</span><span>.</span></span><span>getByRole</span><span>(</span><span>'heading'</span><span>, { </span><span>name</span><span>:</span><span> </span><span>'Installation'</span><span> })).</span><span>toBeVisible</span><span>();</span></div></div><div><div><div>12</div></div><div><span>});</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>2. 运行测试<a href="#2-运行测试"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npx</span><span> </span><span>playwright</span><span> </span><span>test</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>3. 自动生成测试代码<a href="#3-自动生成测试代码"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npx</span><span> </span><span>playwright</span><span> </span><span>codegen</span><span> </span><span>https://example.com</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>4. 网页自动化脚本<a href="#4-网页自动化脚本"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> { </span><span>chromium</span><span> } </span><span>from</span><span> </span><span>'playwright'</span><span>;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>const</span><span> </span><span>browser</span><span> </span><span>=</span><span> </span><span>await</span><span><span> </span><span>chromium</span><span>.</span></span><span>launch</span><span>();</span></div></div><div><div><div>4</div></div><div><span>const</span><span> </span><span>page</span><span> </span><span>=</span><span> </span><span>await</span><span><span> </span><span>browser</span><span>.</span></span><span>newPage</span><span>();</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>// 截图</span></div></div><div><div><div>7</div></div><div><span>await</span><span><span> </span><span>page</span><span>.</span></span><span>goto</span><span>(</span><span>'https://playwright.dev/'</span><span>);</span></div></div><div><div><div>8</div></div><div><span>await</span><span><span> </span><span>page</span><span>.</span></span><span>screenshot</span><span>({ </span><span>path</span><span>:</span><span> </span><span>'screenshot.png'</span><span> });</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>// 生成PDF</span></div></div><div><div><div>11</div></div><div><span>await</span><span><span> </span><span>page</span><span>.</span></span><span>pdf</span><span>({ </span><span>path</span><span>:</span><span> </span><span>'page.pdf'</span><span>, </span><span>format</span><span>:</span><span> </span><span>'A4'</span><span> });</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>// 模拟移动端</span></div></div><div><div><div>14</div></div><div><span>const</span><span> </span><span>context</span><span> </span><span>=</span><span> </span><span>await</span><span><span> </span><span>browser</span><span>.</span></span><span>newContext</span><span>({</span></div></div><div><div><div>15</div></div><div><span>  </span><span>viewport</span><span>:</span><span> { </span><span>width</span><span>:</span><span> </span><span>375</span><span>, </span><span>height</span><span>:</span><span> </span><span>812</span><span> }</span></div></div><div><div><div>16</div></div><div><span>});</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>await</span><span><span> </span><span>browser</span><span>.</span></span><span>close</span><span>();</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>5. 网络拦截<a href="#5-网络拦截"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>await</span><span><span> </span><span>page</span><span>.</span></span><span>route</span><span>(</span><span>'**/*.{png,jpg,jpeg}'</span><span><span>, </span><span>route</span><span> </span></span><span>=&gt;</span><span><span> </span><span>route</span><span>.</span></span><span>abort</span><span>());</span></div></div><div><div><div>2</div></div><div><span>await</span><span><span> </span><span>page</span><span>.</span></span><span>goto</span><span>(</span><span>'https://playwright.dev/'</span><span>);</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>6. 保存登录状态<a href="#6-保存登录状态"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>// 登录后保存状态</span></div></div><div><div><div>2</div></div><div><span>await</span><span><span> </span><span>page</span><span>.</span></span><span>context</span><span>().</span><span>storageState</span><span>({ </span><span>path</span><span>:</span><span> </span><span>'auth.json'</span><span> });</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>// 在其他测试中复用</span></div></div><div><div><div>5</div></div><div><span><span>test</span><span>.</span></span><span>use</span><span>({ </span><span>storageState</span><span>:</span><span> </span><span>'auth.json'</span><span> });</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section>
<section><h2>💡 使用场景<a href="#-使用场景"><span>#</span></a></h2><section><h3>端到端测试：覆盖全流程用户操作<a href="#端到端测试覆盖全流程用户操作"><span>#</span></a></h3><p>无论是电商网站的登录注册、商品搜索、购物车结算、支付下单，还是企业系统的表单填写、权限验证、文件上传下载、多标签页切换，Playwright都能像真人一样完整模拟用户操作流程。自动等待元素加载、智能定位、测试隔离等特性，让测试代码简洁可靠，真正实现全链路自动化测试。</p></section><section><h3>AI Agent 浏览器操控：让AI直接”看”网页<a href="#ai-agent-浏览器操控让ai直接看网页"><span>#</span></a></h3><p>作为Claude Code、Cursor、Gemini等主流AI编程工具的默认浏览器后端，Playwright通过MCP协议让大模型直接操控网页。AI不再需要通过截图识别页面内容，而是通过结构化的可访问性树直接获取页面信息，精准点击按钮、填写表单、浏览内容，Token消耗极低，操作更加准确高效。</p></section><section><h3>网页数据采集：轻松突破各种限制<a href="#网页数据采集轻松突破各种限制"><span>#</span></a></h3><p>对于JavaScript渲染的SPA页面、需要无限滚动加载的列表、带有动态参数签名的接口，传统爬虫往往束手无策。而Playwright使用真实浏览器渲染页面，自带浏览器指纹，能轻松绕过大部分反爬机制。配合登录态复用、网络拦截等功能，可批量完成数据采集、截图归档、PDF生成等任务。</p></section><section><h3>视觉回归测试：自动捕捉UI变化<a href="#视觉回归测试自动捕捉ui变化"><span>#</span></a></h3><p>在CI/CD流程中集成Playwright的视觉对比功能，每次代码提交后自动对比页面截图。无论是像素级别的细微差异，还是整体布局的变化，都能被精确捕捉，确保UI始终符合设计规范，避免意外的视觉回归问题。</p></section><section><h3>性能分析：深度洞察前端瓶颈<a href="#性能分析深度洞察前端瓶颈"><span>#</span></a></h3><p>通过Playwright的追踪功能，可以获取完整的网络请求瀑布图、Core Web Vitals指标、长任务耗时、内存占用等详细数据。这些数据现成可用，无需额外配置，帮助开发者快速定位性能瓶颈，进行前端性能优化。</p></section></section>
<section><h2>📝 我的使用感受<a href="#-我的使用感受"><span>#</span></a></h2><p>让我惊喜的是它的<strong>自动等待</strong>功能。以前用Selenium的时候，经常遇到元素还没加载出来就执行操作的问题，需要手动加各种等待。现在Playwright会自动等待元素可交互，代码简洁多了！</p><p>而且<strong>智能定位器</strong>也很好用。<code>page.getByRole('button', { name: 'Submit' })</code> 这种方式比用CSS选择器更稳定，页面结构变化时不容易失效。</p><p>另外，<strong>追踪功能</strong>在调试测试失败时非常有用。测试失败后生成的trace文件，可以看到每一步的操作、DOM快照、网络请求，调试起来事半功倍。</p><p>唯一需要注意的是，Playwright的文档虽然很详细，但内容比较多，需要花点时间学习。不过一旦掌握，效率提升非常明显。</p></section>
<section><h2>🎯 总结<a href="#-总结"><span>#</span></a></h2><p>Playwright是一款非常强大的网页自动化框架，<strong>微软出品、完全免费、开源</strong>。跨浏览器支持、自动等待、智能定位器、测试隔离、AI代理集成…功能强大到让你挑花眼。如果你是前端开发者、测试工程师，或者需要做网页自动化，Playwright绝对值得一试！</p></section>
<section><h2>📌 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>: <a href="https://github.com/microsoft/playwright" target="_blank">https://github.com/microsoft/playwright</a></p><p><strong>官方文档</strong>: <a href="https://playwright.dev/" target="_blank">https://playwright.dev/</a></p><p><strong>推荐阅读</strong>:</p><ul>
<li><a href="https://mp.weixin.qq.com/s/s6Sr-XEzkZku-K79h-8hRw?token=1716983517&amp;lang=zh_CN" target="_blank">Windows越用越卡？这个开源工具，一键瘦身、优化、自定义全搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/3atWsj1GmVG6Q5mfLM7Tzg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！yantr：自托管应用商店，不占用系统资源，130+应用一键部署</a></li>
<li><a href="https://mp.weixin.qq.com/s/tESfza_v76eAVFoS4dnjgg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！BentoPDF：浏览器端隐私优先的PDF工具箱，50+工具一键搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/tm9H33eCtmQCSDoGclENkA?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！PakePlus：网页秒变桌面应用</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/eJi-6JgP_qKF1ZkGwncKIw?token=1716983517&amp;lang=zh_CN" target="_blank">【OCR工具推荐其一】Umi-OCR：图片文字识别，截图、批量、PDF全搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/douyin-downloader-intro/</id>
      <title type="text">喜欢的博主突然下架视频？这个开源工具，一键备份所有精彩内容！</title>
      <published>2026-07-06T00:00:00.000Z</published>
      <updated>2026-07-06T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/douyin-downloader-intro/"/>
      <summary type="text">一款完全免费开源的抖音视频下载工具，支持单个视频、图片笔记、合集、音乐、收藏、用户主页批量下载，无水印优先，最高质量选择，还支持直播录制和评论采集。支持CLI命令行和REST API，适合备份喜欢的博主内容！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！喜欢的博主突然下架视频怎么办？<a href="#朋友们喜欢的博主突然下架视频怎么办"><span>#</span></a></h2><p>你有没有遇到过这种情况：关注了一个特别喜欢的博主，他的视频质量超高，你想着有空再慢慢看。结果某天打开抖音，发现他的视频全部下架了，或者账号直接注销了！好家伙，那些精彩内容再也找不到了，悔得肠子都青了！</p><p>今天给大家介绍一个神器——<strong>douyin-downloader</strong>！它能一键备份喜欢的博主的所有视频，再也不用担心视频下架了！</p></section>
<section><h2>📚 项目介绍<a href="#-项目介绍"><span>#</span></a></h2><p><strong>douyin-downloader</strong> 是一个完全免费开源的抖音视频下载工具，支持Windows、macOS、Linux三大平台。它就像一个视频备份工厂，从单个视频到整个用户主页，从直播录制到评论采集，全都能搞定！最重要的是，它支持<strong>无水印下载</strong>和<strong>最高质量选择</strong>，备份的视频和原版一样清晰！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/76175da8c3d84ac7b6bae8a3f3cedee020260706152154834.png" alt="" /></p><section><h3>核心特点<a href="#核心特点"><span>#</span></a></h3><ul>
<li>🎥 <strong>单个视频下载</strong>：支持抖音视频链接、图片笔记、合集、音乐下载</li>
<li>👤 <strong>用户主页批量下载</strong>：一键下载博主的所有作品、喜欢的视频、合集、音乐
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/0c8a4a8d0724441f8d9a8a4b5aca983320260706153640508.png" alt="" /></li>
<li>❤️ <strong>收藏备份</strong>：登录后备份你的收藏夹内容</li>
<li>📺 <strong>直播录制</strong>：支持录制抖音直播，自动保存为FLV/HLS格式</li>
<li>💬 <strong>评论采集</strong>：下载视频的评论和回复，保存为JSON文件
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/908cfe7fc785427183b7a42cb7d838c220260706153706919.png" alt="" /></li>
<li>🔍 <strong>热门搜索</strong>：获取抖音热搜榜，关键词搜索视频</li>
<li>🚀 <strong>无水印优先</strong>：自动选择无水印视频源</li>
<li>🎯 <strong>最高质量</strong>：自动选择最高码率的视频和图片
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/bda16b75811e44cdb8531c5766922e0820260706153728979.png" alt="" /></li>
<li>📊 <strong>去重机制</strong>：SQLite数据库+本地文件双重去重，避免重复下载</li>
<li>🔄 <strong>增量下载</strong>：只下载新增内容，适合定期备份</li>
<li>⚡ <strong>REST API</strong>：支持作为服务运行，方便集成到其他系统
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/c9ae688c36334ecebc83734be083cb1320260706153746781.png" alt="" /></li>
<li>🔔 <strong>通知推送</strong>：下载完成后推送通知到Bark、Telegram、企业微信等
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/5e79b33ef6fe46a7974628b1201e510b20260706153757531.png" alt="" /></li>
</ul></section></section>
<section><h2>🚀 使用指南<a href="#-使用指南"><span>#</span></a></h2><section><h3>安装方式<a href="#安装方式"><span>#</span></a></h3><p><strong>方式一：下载桌面客户端（推荐）</strong></p><p>项目提供了桌面客户端 <strong>Douzy</strong>，直接下载即可使用，无需配置Python环境：</p><ol>
<li>访问 GitHub Releases 页面：<a href="https://github.com/jiji262/douyin-downloader/releases" target="_blank">https://github.com/jiji262/douyin-downloader/releases</a></li>
<li>根据系统选择对应的安装包（Windows/macOS/Linux）</li>
<li>下载并安装，双击打开即可使用</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/2d4e91b0244e4ddc8aef4e9d0105653020260706153616660.png" alt="" /></p><blockquote><p>💡 提示：桌面客户端支持粘贴链接开始下载、同步关注列表、可视化追踪下载进度</p></blockquote><p><strong>方式二：源码安装（开发者）</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 克隆项目</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/jiji262/douyin-downloader.git</span></div></div><div><div><div>3</div></div><div><span>cd</span><span> </span><span>douyin-downloader</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># 安装依赖</span></div></div><div><div><div>6</div></div><div><span>pip</span><span> </span><span>install</span><span> </span><span>-r</span><span> </span><span>requirements.txt</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span># 安装浏览器依赖（用于浏览器回退）</span></div></div><div><div><div>9</div></div><div><span>pip</span><span> </span><span>install</span><span> </span><span>playwright</span></div></div><div><div><div>10</div></div><div><span>python</span><span> </span><span>-m</span><span> </span><span>playwright</span><span> </span><span>install</span><span> </span><span>chromium</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式三：Docker部署</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>build</span><span> </span><span>-t</span><span> </span><span>douyin-downloader</span><span> </span><span>.</span></div></div><div><div><div>2</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-v</span><span> $(</span><span>pwd</span><span>)</span><span>/config.yml:/app/config.yml</span><span> </span><span>-v</span><span> $(</span><span>pwd</span><span>)</span><span>/Downloaded:/app/Downloaded</span><span> </span><span>douyin-downloader</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>获取Cookie<a href="#获取cookie"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>python</span><span> </span><span>-m</span><span> </span><span>tools.cookie_fetcher</span><span> </span><span>--config</span><span> </span><span>config.yml</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>运行后会自动打开浏览器，登录抖音后按回车键，Cookie会自动保存到配置文件中。</p></section><section><h3>配置文件示例<a href="#配置文件示例"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>link</span><span>:</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>- </span><span>https://www.douyin.com/user/MS4wLjABAAAAxxxx</span></div></div><div><div><div>3</div></div><div><span>mode</span><span>:</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>- </span><span>post</span></div></div><div><div><div>5</div></div><div><span>number</span><span>:</span></div></div><div><div><div>6</div></div><div><span>  </span><span>post</span><span>: </span><span>0</span><span>  </span><span># 0表示下载全部</span></div></div><div><div><div>7</div></div><div><span>thread</span><span>: </span><span>5</span></div></div><div><div><div>8</div></div><div><span>retry_times</span><span>: </span><span>3</span></div></div><div><div><div>9</div></div><div><span>database</span><span>: </span><span>true</span></div></div><div><div><div>10</div></div><div><span>database_path</span><span>: </span><span>dy_downloader.db</span></div></div><div><div><div>11</div></div><div><span>cookies</span><span>:</span></div></div><div><div><div>12</div></div><div><span>  </span><span>ttwid</span><span>: </span><span>YOUR_TTWID</span></div></div><div><div><div>13</div></div><div><span>  </span><span>odin_tt</span><span>: </span><span>YOUR_ODIN_TT</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>核心功能使用<a href="#核心功能使用"><span>#</span></a></h3><section><h4>1. 下载单个视频<a href="#1-下载单个视频"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>python</span><span> </span><span>run.py</span><span> </span><span>-c</span><span> </span><span>config.yml</span><span> </span><span>-u</span><span> </span><span>"https://www.douyin.com/video/7604129988555574538"</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>2. 批量下载博主所有作品<a href="#2-批量下载博主所有作品"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>python</span><span> </span><span>run.py</span><span> </span><span>-c</span><span> </span><span>config.yml</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>-u</span><span> </span><span>"https://www.douyin.com/user/MS4wLjABAAAAxxxx"</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>-m</span><span> </span><span>post</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>-n</span><span> </span><span>0</span><span>  </span><span># 0表示下载全部</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>3. 下载博主的喜欢列表<a href="#3-下载博主的喜欢列表"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>python</span><span> </span><span>run.py</span><span> </span><span>-c</span><span> </span><span>config.yml</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>-u</span><span> </span><span>"https://www.douyin.com/user/MS4wLjABAAAAxxxx"</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>-m</span><span> </span><span>like</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>-n</span><span> </span><span>0</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>4. 备份收藏夹<a href="#4-备份收藏夹"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>python</span><span> </span><span>run.py</span><span> </span><span>-c</span><span> </span><span>config.yml</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>-u</span><span> </span><span>"https://www.douyin.com/user/self?showTab=favorite_collection"</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>-m</span><span> </span><span>collect</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>-n</span><span> </span><span>0</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>5. 录制直播<a href="#5-录制直播"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>python</span><span> </span><span>run.py</span><span> </span><span>-c</span><span> </span><span>config.yml</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>-u</span><span> </span><span>"https://live.douyin.com/123456789"</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>6. 增量下载（只下载新增内容）<a href="#6-增量下载只下载新增内容"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 在config.yml中添加</span></div></div><div><div><div>2</div></div><div><span>increase</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>post</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>like</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>database</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section>
<section><h2>📊 对比其他方案<a href="#-对比其他方案"><span>#</span></a></h2>

<table><thead><tr><th>功能</th><th>douyin-downloader</th><th>在线下载网站</th><th>抖音自带保存</th><th>其他下载工具</th></tr></thead><tbody><tr><td><strong>免费</strong></td><td>✅</td><td>✅</td><td>✅</td><td>部分</td></tr><tr><td><strong>无水印下载</strong></td><td>✅</td><td>✅</td><td>❌</td><td>部分</td></tr><tr><td><strong>批量下载</strong></td><td>✅</td><td>❌</td><td>❌</td><td>部分</td></tr><tr><td><strong>直播录制</strong></td><td>✅</td><td>❌</td><td>❌</td><td>❌</td></tr><tr><td><strong>评论采集</strong></td><td>✅</td><td>❌</td><td>❌</td><td>❌</td></tr><tr><td><strong>增量下载</strong></td><td>✅</td><td>❌</td><td>❌</td><td>❌</td></tr><tr><td><strong>去重机制</strong></td><td>✅</td><td>❌</td><td>❌</td><td>❌</td></tr><tr><td><strong>REST API</strong></td><td>✅</td><td>❌</td><td>❌</td><td>❌</td></tr><tr><td><strong>开源</strong></td><td>✅</td><td>❌</td><td>❌</td><td>❌</td></tr></tbody></table></section>
<section><h2>💡 使用场景<a href="#-使用场景"><span>#</span></a></h2><section><h3>场景一：备份喜欢的博主内容<a href="#场景一备份喜欢的博主内容"><span>#</span></a></h3><p>关注了一个优质博主，担心他的视频下架？一键批量下载他的所有作品，永久保存。</p></section><section><h3>场景二：备份自己的收藏夹<a href="#场景二备份自己的收藏夹"><span>#</span></a></h3><p>收藏了很多精彩视频，怕抖音清理或者自己误删？定期备份收藏夹内容。</p></section><section><h3>场景三：直播录制<a href="#场景三直播录制"><span>#</span></a></h3><p>喜欢的主播开播了，没时间看？用录制功能自动保存直播内容，有空再看。</p></section><section><h3>场景四：数据分析<a href="#场景四数据分析"><span>#</span></a></h3><p>想研究某个领域的热门视频？用关键词搜索和评论采集功能，获取数据进行分析。</p></section><section><h3>场景五：批量下载合集<a href="#场景五批量下载合集"><span>#</span></a></h3><p>看到一个精彩的视频合集？一键下载整个合集，离线慢慢看。</p></section></section>
<section><h2>📝 我的使用感受<a href="#-我的使用感受"><span>#</span></a></h2><p>我关注了几个优质博主，设置了增量下载，每天自动运行一次，只下载新增的视频。这样既不会重复下载浪费空间，也不会错过任何新内容。</p><p>而且<strong>去重机制</strong>也很实用。有时候同一个视频会出现在不同的合集中，douyin-downloader会自动跳过已经下载过的视频，非常智能。</p><p>唯一需要注意的是，抖音的API可能会有变化，需要定期更新Cookie。不过项目更新很及时，基本不会有太大问题。</p></section>
<section><h2>🎯 总结<a href="#-总结"><span>#</span></a></h2><p>douyin-downloader是一款非常强大的抖音视频下载工具，<strong>完全免费、开源</strong>。批量下载、增量更新、去重机制、直播录制、评论采集…功能强大到让你挑花眼。如果你经常刷抖音，又担心喜欢的内容下架，douyin-downloader绝对值得一试！</p></section>
<section><h2>📌 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>: <a href="https://github.com/jiji262/douyin-downloader" target="_blank">https://github.com/jiji262/douyin-downloader</a></p><p><strong>下载地址</strong>: <a href="https://github.com/jiji262/douyin-downloader/releases" target="_blank">https://github.com/jiji262/douyin-downloader/releases</a></p><p><strong>推荐阅读</strong>:</p><ul>
<li><a href="https://mp.weixin.qq.com/s/s6Sr-XEzkZku-K79h-8hRw?token=1716983517&amp;lang=zh_CN" target="_blank">Windows越用越卡？这个开源工具，一键瘦身、优化、自定义全搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/3atWsj1GmVG6Q5mfLM7Tzg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！yantr：自托管应用商店，不占用系统资源，130+应用一键部署</a></li>
<li><a href="https://mp.weixin.qq.com/s/tESfza_v76eAVFoS4dnjgg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！BentoPDF：浏览器端隐私优先的PDF工具箱，50+工具一键搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/tm9H33eCtmQCSDoGclENkA?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！PakePlus：网页秒变桌面应用</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/eJi-6JgP_qKF1ZkGwncKIw?token=1716983517&amp;lang=zh_CN" target="_blank">【OCR工具推荐其一】Umi-OCR：图片文字识别，截图、批量、PDF全搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/ai/pyvideotrans-intro/</id>
      <title type="text">做自媒体的看过来！这个工具一键完成视频翻译、字幕生成、AI配音</title>
      <published>2026-07-02T00:00:00.000Z</published>
      <updated>2026-07-02T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/ai/pyvideotrans-intro/"/>
      <summary type="text">一款完全免费开源的AI视频翻译工具，支持语音识别、字幕翻译、多角色配音、语音克隆全流程。支持30+在线API和本地模型（Faster-Whisper、Ollama等），Windows一键运行，Linux/macOS源码部署，适合自媒体创作者和视频翻译工作者！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！视频翻译太麻烦？<a href="#朋友们视频翻译太麻烦"><span>#</span></a></h2><p>做自媒体的朋友应该都遇到过这种情况：想把外国视频翻译成中文，或者给视频配音、加字幕，要么收费贵，要么效果差。好家伙，今天给大家介绍一个开源神器——<strong>pyVideoTrans</strong>！它能一键完成语音识别→字幕翻译→AI配音→视频合成，全程自动化，效果还特别好！</p></section>
<section><h2>📚 项目介绍<a href="#-项目介绍"><span>#</span></a></h2><p><strong>pyVideoTrans</strong> 是一个完全免费开源的AI视频翻译工具，支持Windows、macOS、Linux三大平台。它就像一个视频翻译工厂，从语音识别到字幕翻译，再到AI配音和视频合成，一站式搞定！最重要的是，它支持多种本地模型，没有网络也能工作！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/507489fad2744dafbf607b2959ba121f20260702163852214.png" alt="" /></p><section><h3>核心特点<a href="#核心特点"><span>#</span></a></h3><ul>
<li>🎥 <strong>全自动视频翻译</strong>：一键完成语音识别→字幕翻译→AI配音→视频合成</li>
<li>🎙️ <strong>音频转录</strong>：批量将音频/视频转换为SRT字幕，支持角色区分（Speaker Diarization）</li>
<li>🗣️ <strong>多角色AI配音</strong>：为不同说话者分配不同的AI语音</li>
<li>🧬 <strong>语音克隆</strong>：集成F5-TTS、CosyVoice、GPT-SoVITS等模型，零样本克隆语音</li>
<li>🧠 <strong>强大模型支持</strong>：
<ul>
<li><strong>ASR</strong>：Faster-Whisper（本地）、OpenAI Whisper、阿里Qwen、火山引擎、Azure、Google等</li>
<li><strong>翻译</strong>：DeepSeek、ChatGPT、Claude、Gemini、MiniMax、Ollama（本地）等</li>
<li><strong>TTS</strong>：Edge-TTS（免费）、OpenAI、Azure、ChatTTS、F5-TTS、CosyVoice等</li>
</ul>
</li>
<li>🖥️ <strong>交互式编辑</strong>：支持在识别、翻译、配音各阶段暂停手动校对，确保准确性</li>
<li>🛠️ <strong>实用工具包</strong>：人声分离、视频/字幕合并、音视频对齐、字幕匹配等辅助工具</li>
<li>💻 <strong>命令行支持</strong>：支持无界面运行，方便服务器部署或批量处理</li>
</ul></section></section>
<section><h2>🚀 使用指南<a href="#-使用指南"><span>#</span></a></h2><section><h3>安装方式<a href="#安装方式"><span>#</span></a></h3><p><strong>方式一：Windows一键运行（推荐）</strong></p><ol>
<li>从GitHub Releases页面下载最新预打包版本</li>
<li>解压到无空格无中文的路径（如 <code>D:\pyVideoTrans</code>）</li>
<li>双击 <code>sp.exe</code> 启动</li>
</ol><blockquote><p>💡 提示：如需GPU加速，需安装 CUDA 12.8 和 cuDNN 9.11</p></blockquote><p><strong>方式二：源码部署（macOS/Linux/Windows开发者）</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 安装uv包管理工具</span></div></div><div><div><div>2</div></div><div><span>curl</span><span> </span><span>-LsSf</span><span> </span><span>https://astral.sh/uv/install.sh</span><span> | </span><span>sh</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 克隆项目</span></div></div><div><div><div>5</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/jianchang512/pyvideotrans.git</span></div></div><div><div><div>6</div></div><div><span>cd</span><span> </span><span>pyvideotrans</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span># 安装依赖</span></div></div><div><div><div>9</div></div><div><span>uv</span><span> </span><span>sync</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span># 启动GUI</span></div></div><div><div><div>12</div></div><div><span>uv</span><span> </span><span>run</span><span> </span><span>sp.py</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>核心功能使用<a href="#核心功能使用"><span>#</span></a></h3><section><h4>1. 全自动视频翻译<a href="#1-全自动视频翻译"><span>#</span></a></h4><ul>
<li>导入视频文件</li>
<li>设置源语言和目标语言</li>
<li>选择ASR、翻译、TTS模型</li>
<li>点击开始，自动完成语音识别→字幕翻译→AI配音→视频合成
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/88099cf53be644818e33340f2e2f2a2220260702164047677.png" alt="" /></li>
</ul></section><section><h4>2. 音频转字幕<a href="#2-音频转字幕"><span>#</span></a></h4><ul>
<li>导入音频/视频文件</li>
<li>选择ASR模型（推荐Faster-Whisper）</li>
<li>点击开始，生成SRT字幕文件</li>
<li>支持角色区分（Speaker Diarization）
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/7b9b74f82dbb470d8b8a73c5c07fa69220260702163939269.png" alt="" /></li>
</ul></section><section><h4>3. 多角色配音<a href="#3-多角色配音"><span>#</span></a></h4><ul>
<li>在字幕编辑界面为不同说话者分配不同角色</li>
<li>为每个角色选择不同的TTS语音</li>
<li>点击配音，生成多角色配音的视频
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/806416d7aac445a5bb311247792af95720260702164000814.png" alt="" /></li>
</ul></section><section><h4>4. 语音克隆<a href="#4-语音克隆"><span>#</span></a></h4><ul>
<li>导入参考音频（目标人物的语音）</li>
<li>选择语音克隆模型（F5-TTS、CosyVoice、GPT-SoVITS）</li>
<li>生成与参考语音相似的配音
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/07/2e48c69802454b8e8fead4ab4e7e2c6820260702164028731.png" alt="" /></li>
</ul></section><section><h4>5. 命令行批量处理<a href="#5-命令行批量处理"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 视频翻译</span></div></div><div><div><div>2</div></div><div><span>uv</span><span> </span><span>run</span><span> </span><span>cli.py</span><span> </span><span>--task</span><span> </span><span>vtv</span><span> </span><span>--name</span><span> </span><span>"./video.mp4"</span><span> </span><span>--source_language_code</span><span> </span><span>zh</span><span> </span><span>--target_language_code</span><span> </span><span>en</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 音频转字幕</span></div></div><div><div><div>5</div></div><div><span>uv</span><span> </span><span>run</span><span> </span><span>cli.py</span><span> </span><span>--task</span><span> </span><span>stt</span><span> </span><span>--name</span><span> </span><span>"./audio.wav"</span><span> </span><span>--model_name</span><span> </span><span>large-v3</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section>
<section><h2>📝 我的使用感受<a href="#-我的使用感受"><span>#</span></a></h2><p>用了pyVideoTrans一段时间，最让我惊喜的是它的<strong>全自动视频翻译</strong>功能。以前翻译一个视频，要先用Whisper转字幕，再手动翻译，然后找配音软件，最后用PR合成，整个流程要花好几个小时。现在pyVideoTrans一键搞定，效率直接提升10倍！</p><p>而且<strong>语音克隆</strong>功能也很强大。我用一段1分钟的参考音频，就能克隆出和目标人物非常相似的声音，配音效果几乎可以以假乱真。</p><p>唯一需要注意的是，本地模型需要一定的GPU资源。如果没有高端显卡，可以选择在线API，效果同样很好。</p></section>
<section><h2>🎯 总结<a href="#-总结"><span>#</span></a></h2><p>pyVideoTrans是一款非常强大的AI视频翻译工具，<strong>完全免费、开源</strong>。全自动视频翻译、多角色配音、语音克隆、批量处理…功能强大到让你挑花眼。如果你是自媒体创作者、视频翻译工作者，或者经常需要处理视频字幕和配音，pyVideoTrans绝对值得一试！</p></section>
<section><h2>📌 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>: <a href="https://github.com/jianchang512/pyvideotrans" target="_blank">https://github.com/jianchang512/pyvideotrans</a></p><p><strong>官方文档</strong>: <a href="https://pyvideotrans.com/" target="_blank">https://pyvideotrans.com/</a></p><p><strong>推荐阅读</strong>:</p><ul>
<li><a href="https://mp.weixin.qq.com/s/s6Sr-XEzkZku-K79h-8hRw?token=1716983517&amp;lang=zh_CN" target="_blank">Windows越用越卡？这个开源工具，一键瘦身、优化、自定义全搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/3atWsj1GmVG6Q5mfLM7Tzg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！yantr：自托管应用商店，不占用系统资源，130+应用一键部署</a></li>
<li><a href="https://mp.weixin.qq.com/s/tESfza_v76eAVFoS4dnjgg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！BentoPDF：浏览器端隐私优先的PDF工具箱，50+工具一键搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/tm9H33eCtmQCSDoGclENkA?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！PakePlus：网页秒变桌面应用</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/eJi-6JgP_qKF1ZkGwncKIw?token=1716983517&amp;lang=zh_CN" target="_blank">【OCR工具推荐其一】Umi-OCR：图片文字识别，截图、批量、PDF全搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/pot-intro/</id>
      <title type="text">【OCR工具推荐其二】Pot：翻译+OCR二合一神器，划词翻译、截图识别全覆盖</title>
      <published>2026-06-25T00:00:00.000Z</published>
      <updated>2026-06-25T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/pot-intro/"/>
      <summary type="text">一款支持翻译和OCR二合一的开源桌面工具，截图OCR识别、划词翻译、截图翻译多功能集于一身。支持多语言识别、离线OCR引擎、多翻译接口、语音合成和生词本导出，Windows/Mac/Linux全平台免费使用，插件丰富可扩展！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！还在为截图文字提取发愁吗？<a href="#朋友们还在为截图文字提取发愁吗"><span>#</span></a></h2><p>在上一篇【其一】中，我给大家介绍了 <strong>Umi-OCR</strong>，它非常适合批量处理图片和 PDF 识别。不过今天要给大家介绍另一个选择——<strong>Pot（派了个萌的翻译器）</strong>！</p><p>它不仅支持截图 OCR，还支持划词翻译、截图翻译，简直是翻译和 OCR 的二合一神器！而且更重要的是，Pot 支持<strong>离线 OCR 引擎</strong>，不用联网也能识别图片文字！</p><p>如果你觉得 Umi-OCR 用起来不错，那 Pot 绝对值得一试。这两个工具配合使用：<strong>日常截图 OCR 和翻译用 Pot，需要批量处理或 PDF 识别时用 Umi-OCR</strong>，效率直接翻倍！</p></section>
<section><h2>📚 项目介绍<a href="#-项目介绍"><span>#</span></a></h2><p><strong>Pot</strong> 是一个完全免费开源的跨平台划词翻译和 OCR 软件，支持 Windows、macOS、Linux 三大平台。它最大的特点是<strong>翻译+OCR 二合一</strong>，一个软件搞定两种需求，再也不用在多个软件之间来回切换了。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/7fc3c53e134946a39bed2cc52de5d98820260625143000155.png" alt="" /></p><section><h3>核心特点<a href="#核心特点"><span>#</span></a></h3><ul>
<li>📷 <strong>截图 OCR 识别</strong>：截图框选即可识别文字，支持多种离线 OCR 引擎</li>
<li>🌐 <strong>划词翻译</strong>：选中文字即翻译，支持 50+ 翻译接口</li>
<li>🖼️ <strong>截图翻译</strong>：截图后自动识别文字并翻译</li>
<li>🔊 <strong>语音合成</strong>：支持 TTS，看单词还能听发音</li>
<li>📖 <strong>生词本功能</strong>：支持导出到 Anki、欧路词典、有道、扇贝</li>
<li>🔌 <strong>插件系统</strong>：丰富的插件生态，可扩展更多功能</li>
<li>💻 <strong>全平台支持</strong>：Windows、macOS、Linux 统统支持</li>
<li>🆓 <strong>完全免费</strong>：开源免费，没有广告，没有会员</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/b5ebf46c00fd41ee9dbf9bb674d345d020260625143231297.png" alt="" /></p></section><section><h3>支持的 OCR 接口<a href="#支持的-ocr-接口"><span>#</span></a></h3><p>Pot 支持多种 OCR 接口，既有系统自带的离线引擎，也有第三方在线服务：</p><p><strong>系统自带离线 OCR（推荐）</strong>：</p><ul>
<li><strong>Windows</strong>：Windows.Media.OCR（系统自带，无需额外安装）</li>
<li><strong>macOS</strong>：Apple Vision Framework（系统自带，无需额外安装）</li>
<li><strong>Linux</strong>：Tesseract OCR（需单独安装）</li>
</ul><p><strong>跨平台离线 OCR 插件</strong>：</p><ul>
<li><strong>Rapid OCR</strong>：高性能离线 OCR 引擎，识别速度快，准确率高</li>
<li><strong>Paddle OCR</strong>：轻量级离线 OCR 引擎，支持多语言识别</li>
</ul><p><strong>在线 OCR 服务</strong>：</p><ul>
<li><strong>百度 OCR</strong>：国内主流 OCR 服务，识别准确率高</li>
<li><strong>腾讯 OCR</strong>：腾讯云提供的 OCR 服务</li>
<li><strong>火山 OCR</strong>：字节跳动的 OCR 服务</li>
<li><strong>讯飞 OCR</strong>：科大讯飞的 OCR 服务</li>
<li><strong>Simple LaTeX</strong>：专门用于数学公式识别</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/731bab4ca3234fb79c58319bfc91cca020260625144753685.png" alt="" /></p><blockquote><p>💡 <strong>使用建议</strong>：日常使用推荐配置 Rapid OCR 或 Paddle OCR 插件，识别速度快且完全离线，不用担心网络问题！</p></blockquote></section><section><h3>支持的翻译接口（50+）<a href="#支持的翻译接口50"><span>#</span></a></h3><p><strong>AI大模型接口</strong>：</p><ul>
<li>OpenAI（GPT系列）</li>
<li>智谱 AI（GLM系列）</li>
<li>Google Gemini</li>
<li>Ollama（离线可用）</li>
</ul><p><strong>国内翻译接口</strong>：</p><ul>
<li>百度翻译、腾讯翻译君、阿里翻译</li>
<li>彩云小译、火山翻译、有道翻译</li>
<li>腾讯交互翻译、小牛翻译</li>
</ul><p><strong>国际翻译接口</strong>：</p><ul>
<li>DeepL、Google翻译、Bing翻译</li>
<li>Yandex、Lingva</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/372369d772eb4bc88e83bc7bcaefae2020260625143327900.png" alt="" /></p></section></section>
<section><h2>💻 安装指南<a href="#-安装指南"><span>#</span></a></h2><section><h3>Windows 系统<a href="#windows-系统"><span>#</span></a></h3><p><strong>方式一：Winget 安装（推荐）</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>winget install Pylogmon.pot</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式二：手动安装</strong></p><ol>
<li>进入 <a href="https://github.com/pot-app/pot-desktop/releases/latest" target="_blank">Release 页面</a> 下载最新安装包</li>
<li>下载对应的 <code>pot_{version}_x64-setup.exe</code></li>
<li>双击安装即可</li>
</ol><p><strong>注意</strong>：如果启动后没有界面，请确保已安装 WebView2，运行库。</p></section><section><h3>macOS 系统<a href="#macos-系统"><span>#</span></a></h3><p><strong>方式一：Homebrew 安装（推荐）</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 添加 tap</span></div></div><div><div><div>2</div></div><div><span>brew</span><span> </span><span>tap</span><span> </span><span>pot-app/homebrew-tap</span></div></div><div><div><div>3</div></div><div><span># 安装 pot</span></div></div><div><div><div>4</div></div><div><span>brew</span><span> </span><span>install</span><span> </span><span>--cask</span><span> </span><span>pot</span></div></div><div><div><div>5</div></div><div><span># 更新</span></div></div><div><div><div>6</div></div><div><span>brew</span><span> </span><span>upgrade</span><span> </span><span>--cask</span><span> </span><span>pot</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式二：手动安装</strong></p><ol>
<li>从 <a href="https://github.com/pot-app/pot-desktop/releases/latest" target="_blank">Release 页面</a> 下载 <code>pot_{version}_aarch64.dmg</code>（M1）或 <code>pot_{version}_x64.dmg</code>（Intel）</li>
<li>双击后将 pot 拖入 Applications 文件夹即可</li>
</ol></section><section><h3>Linux 系统<a href="#linux-系统"><span>#</span></a></h3><p><strong>Debian/Ubuntu：</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>apt-get</span><span> </span><span>install</span><span> </span><span>./pot_{version}_amd64.deb</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>Arch/Manjaro：</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>yay</span><span> </span><span>-S</span><span> </span><span>pot-translation</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>Flatpak：</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>flatpak</span><span> </span><span>install</span><span> </span><span>flathub</span><span> </span><span>com.pot_app.pot</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>🚀 使用指南<a href="#-使用指南"><span>#</span></a></h2><section><h3>基础配置<a href="#基础配置"><span>#</span></a></h3><ol>
<li><strong>首次启动</strong>：安装完成后打开 Pot，进行基础配置</li>
<li><strong>添加 OCR 接口</strong>：设置 -&gt; 服务设置 -&gt; 添加识别服务（推荐配置 Rapid OCR 或 Paddle OCR）</li>
<li><strong>添加翻译接口</strong>：设置 -&gt; 服务设置 -&gt; 添加翻译服务</li>
<li><strong>配置快捷键</strong>：设置 -&gt; 快捷键，设置截图 OCR、划词翻译和截图翻译的快捷键</li>
</ol></section><section><h3>核心功能使用<a href="#核心功能使用"><span>#</span></a></h3><section><h4>1. 截图 OCR 识别（最常用）<a href="#1-截图-ocr-识别最常用"><span>#</span></a></h4><ul>
<li>按下截图 OCR 快捷键</li>
<li>框选需要识别的区域</li>
<li>自动识别并显示文字结果</li>
<li>可复制或发送到翻译</li>
</ul></section><section><h4>2. 截图翻译<a href="#2-截图翻译"><span>#</span></a></h4><ul>
<li>按下截图翻译快捷键</li>
<li>框选需要翻译的区域</li>
<li>自动识别文字并翻译</li>
</ul></section><section><h4>3. 划词翻译<a href="#3-划词翻译"><span>#</span></a></h4><ul>
<li>选中需要翻译的文本</li>
<li>按下划词翻译快捷键</li>
<li>弹出翻译窗口，显示翻译结果</li>
</ul></section><section><h4>4. 剪切板监听模式<a href="#4-剪切板监听模式"><span>#</span></a></h4><ul>
<li>点击翻译面板左上角图标启动剪切板监听</li>
<li>复制文字即可自动翻译</li>
</ul></section></section><section><h3>OCR 接口配置<a href="#ocr-接口配置"><span>#</span></a></h3><p>Pot 支持多种 OCR 接口：</p><p><strong>离线 OCR（推荐）</strong>：</p><ul>
<li>Windows：系统自带 OCR（Windows.Media.OCR）</li>
<li>macOS：Apple Vision Framework</li>
<li>Linux：Tesseract OCR</li>
<li>Rapid OCR（跨平台离线插件）</li>
<li>Paddle OCR（跨平台离线插件）</li>
</ul><p><strong>在线 OCR</strong>：</p><ul>
<li>百度 OCR、腾讯 OCR、火山 OCR</li>
<li>讯飞 OCR、Simple LaTeX（公式识别）</li>
</ul></section><section><h3>生词本功能<a href="#生词本功能"><span>#</span></a></h3><p>Pot 支持将单词导出到多个生词本应用：</p><ul>
<li><strong>Anki</strong>：著名的间隔重复记忆软件</li>
<li><strong>欧路词典</strong>：专业的词典软件</li>
<li><strong>有道词典</strong>：国内知名词典</li>
<li><strong>扇贝</strong>：支持扇贝单词</li>
</ul></section></section>
<section><h2>🔌 插件系统<a href="#-插件系统"><span>#</span></a></h2><p>Pot 的插件系统非常强大，可以扩展更多功能：</p><section><h3>常用插件<a href="#常用插件"><span>#</span></a></h3><ul>
<li><strong>ECDICT 插件</strong>：离线英英词典</li>
<li><strong>Tatoeba 插件</strong>：例句查询</li>
<li><strong>Lingva 插件</strong>：Privacy-respecting翻译</li>
<li><strong>Rapid OCR 插件</strong>：高性能离线OCR</li>
<li><strong>Paddle OCR 插件</strong>：轻量级离线OCR</li>
</ul></section><section><h3>安装插件<a href="#安装插件"><span>#</span></a></h3><ol>
<li>访问 <a href="https://pot-app.com/plugin.html" target="_blank">Plugin List</a> 查找需要的插件</li>
<li>下载 <code>.potext</code> 文件</li>
<li>在 偏好设置 -&gt; 服务设置 -&gt; 添加外部插件 -&gt; 安装外部插件</li>
<li>选择下载的 <code>.potext</code> 文件即可</li>
</ol></section></section>
<section><h2>📊 对比其他方案<a href="#-对比其他方案"><span>#</span></a></h2>

<table><thead><tr><th>功能</th><th>Pot</th><th>Umi-OCR</th><th>天若OCR</th><th>白描</th></tr></thead><tbody><tr><td><strong>免费</strong></td><td>✅</td><td>✅</td><td>✅</td><td>付费</td></tr><tr><td><strong>截图OCR</strong></td><td>✅</td><td>✅</td><td>✅</td><td>✅</td></tr><tr><td><strong>划词翻译</strong></td><td>✅</td><td>❌</td><td>❌</td><td>❌</td></tr><tr><td><strong>离线OCR</strong></td><td>✅</td><td>✅</td><td>✅</td><td>❌</td></tr><tr><td><strong>批量OCR</strong></td><td>❌</td><td>✅</td><td>❌</td><td>✅</td></tr><tr><td><strong>PDF识别</strong></td><td>❌</td><td>✅</td><td>❌</td><td>✅</td></tr><tr><td><strong>翻译功能</strong></td><td>✅ 50+接口</td><td>❌</td><td>❌</td><td>❌</td></tr><tr><td><strong>跨平台</strong></td><td>✅ Win/Mac/Linux</td><td>✅ Win/Linux</td><td>✅ Win</td><td>✅</td></tr></tbody></table><blockquote><p>💡 <strong>小结</strong>：如果你主要用 OCR 功能，Umi-OCR 更适合批量处理；如果你需要 OCR+翻译二合一，Pot 是更好的选择！</p></blockquote></section>
<section><h2>💡 使用场景<a href="#-使用场景"><span>#</span></a></h2><section><h3>场景一：截图识别外语文档<a href="#场景一截图识别外语文档"><span>#</span></a></h3><p>遇到 PDF 或者图片中的外语文本，直接截图识别，还能一键翻译。</p></section><section><h3>场景二：阅读外文网页<a href="#场景二阅读外文网页"><span>#</span></a></h3><p>浏览外文网站时，遇到不懂的单词，划词翻译，还能保存到生词本复习。</p></section><section><h3>场景三：截图翻译外国网站<a href="#场景三截图翻译外国网站"><span>#</span></a></h3><p>遇到全是外语的网站，截图翻译，秒懂内容。</p></section><section><h3>场景四：离线环境 OCR<a href="#场景四离线环境-ocr"><span>#</span></a></h3><p>配置 Rapid OCR 或 Paddle OCR 引擎，没有网络也能识别图片文字。</p></section><section><h3>场景五：多翻译接口切换<a href="#场景五多翻译接口切换"><span>#</span></a></h3><p>一个翻译接口被限速了？没关系，换一个继续用，再也不用担心翻译中断。</p></section></section>
<section><h2>📝 我的使用感受<a href="#-我的使用感受"><span>#</span></a></h2><p>如果你用过 Umi-OCR，可能会觉得 Pot 的 OCR 功能没有它强大（比如不支持批量处理和 PDF 识别）。但 Pot 的优势在于<strong>翻译功能</strong>，划词翻译、截图翻译、多接口并行…这些 Umi-OCR 都没有。所以我的建议是：<strong>两个工具配合使用</strong>，日常截图 OCR 用 Pot，需要批量处理或 PDF 识别时用 Umi-OCR，效率拉满！</p></section>
<section><h2>🎯 总结<a href="#-总结"><span>#</span></a></h2><p>Pot 是一款<strong>翻译+OCR 二合一</strong>的开源工具，完全免费、开源、跨平台。截图 OCR 识别、划词翻译、截图翻译、离线引擎、多翻译接口…功能丰富到让你挑花眼。如果你需要一款既能 OCR 又能翻译的工具，Pot 绝对值得一试！配合 Umi-OCR 使用，OCR 需求全搞定！</p><p><strong>推荐阅读</strong>:</p><ul>
<li><a href="https://mp.weixin.qq.com/s/3atWsj1GmVG6Q5mfLM7Tzg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！yantr：自托管应用商店，不占用系统资源，130+应用一键部署</a></li>
<li><a href="https://mp.weixin.qq.com/s/tESfza_v76eAVFoS4dnjgg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！BentoPDF：浏览器端隐私优先的PDF工具箱，50+工具一键搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/tm9H33eCtmQCSDoGclENkA?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！PakePlus：网页秒变桌面应用</a></li>
<li><a href="https://mp.weixin.qq.com/s/1W0KIPzAXGLXjl7jyEsYEA?token=1837315026&amp;lang=zh_CN" target="_blank">服务器到期宕机？域名过期被抢注？这个工具帮你守住所有服务</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/umi-ocr-intro/</id>
      <title type="text">【OCR工具推荐其一】Umi-OCR：图片文字识别，截图、批量、PDF全搞定</title>
      <published>2026-06-25T00:00:00.000Z</published>
      <updated>2026-06-25T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/umi-ocr-intro/"/>
      <summary type="text">一款完全免费开源的离线OCR工具，支持截图识别、批量OCR、PDF扫描件转可搜索文档、二维码识别及公式提取。解压即用无需网络，所有数据本地处理更安全，支持多语言识别和多种输出格式，适合 Windows 和 Linux 系统使用！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！遇到图片里的文字想复制？<a href="#朋友们遇到图片里的文字想复制"><span>#</span></a></h2><p>你是不是经常遇到这些困扰：</p><ul>
<li><strong>图片文字无法复制</strong>：看到截图里的重要文字，却无法直接复制</li>
<li><strong>在线OCR不安全</strong>：上传敏感图片到第三方网站，担心数据泄露</li>
<li><strong>批量处理太麻烦</strong>：需要识别几十张图片，一张一张处理太累</li>
<li><strong>PDF扫描件无法搜索</strong>：扫描版PDF无法检索内容，翻页找信息太耗时</li>
<li><strong>公式无法提取</strong>：文档里的数学公式，想复制出来却无能为力</li>
<li><strong>需要网络才能用</strong>：离线环境下无法使用OCR工具</li>
</ul><p>今天我要给大家分享一个 GitHub 上的宝藏项目——<strong>Umi-OCR</strong>！这是一款完全免费开源的离线OCR软件，支持截图识别、批量OCR、PDF识别、二维码、公式识别，解压即用，无需网络！</p></section>
<section><h2>✨ 什么是 Umi-OCR？<a href="#-什么是-umi-ocr"><span>#</span></a></h2><p>Umi-OCR 是一款<strong>免费、开源、可批量的离线OCR软件</strong>，适用于 Windows7 x64 和 Linux x64。它内置高效率的离线OCR引擎，支持多种语言识别，无需网络即可运行。</p><p><strong>核心特点</strong>：</p><ul>
<li>🆓 <strong>完全免费</strong>：所有代码开源，无任何隐藏费用</li>
<li>🔌 <strong>离线运行</strong>：无需网络，所有识别在本地完成</li>
<li>📦 <strong>解压即用</strong>：无需安装，解压后即可使用</li>
<li>🚀 <strong>高效识别</strong>：内置多种OCR引擎，识别速度快、准确率高</li>
<li>✂️ <strong>截图OCR</strong>：快捷键唤起截图，一键识别图片中的文字</li>
<li>📷 <strong>批量OCR</strong>：支持批量导入图片，一次性识别几百张</li>
<li>📄 <strong>PDF识别</strong>：从PDF扫描件中提取文本，生成可搜索PDF</li>
<li>📐 <strong>公式识别</strong>：支持数学公式识别</li>
<li>📱 <strong>二维码</strong>：支持扫码和生成二维码</li>
<li>🖥️ <strong>命令行调用</strong>：支持脚本自动化处理</li>
<li>🌐 <strong>HTTP接口</strong>：支持外部程序调用</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/f04668a3287b4849846a5c5ee140d8bd20260625111529935.png" alt="" /></p></section>
<section><h2>🎯 核心功能<a href="#-核心功能"><span>#</span></a></h2><section><h3>1. 截图OCR<a href="#1-截图ocr"><span>#</span></a></h3><p>截图OCR是Umi-OCR最常用的功能，只需按下快捷键即可唤起截图，识别图中的文字：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- 快捷键唤起截图（默认Ctrl+Shift+A）</span></div></div><div><div><div>2</div></div><div><span>- 左侧图片预览栏，可直接划选复制</span></div></div><div><div><div>3</div></div><div><span>- 右侧识别记录栏，可编辑文字，支持多选复制</span></div></div><div><div><div>4</div></div><div><span>- 支持粘贴图片进行识别</span></div></div><div><div><div>5</div></div><div><span>- 支持公式识别</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/2fd37aa519624e47ae5e7f434dda3be920260625134711443.png" alt="" /></p><p><strong>文本后处理</strong>：支持多种排版解析方案，自动识别多栏布局，按正确顺序输出文字：</p><ul>
<li>多栏-按自然段换行</li>
<li>多栏-总是换行</li>
<li>多栏-无换行</li>
<li>单栏-按自然段换行</li>
<li>单栏-保留缩进（适合代码截图）</li>
<li>不做处理
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/1ceda5355f224f09a2857d9c9d3e0a0820260625134748821.png" alt="" /></li>
</ul></section><section><h3>2. 批量OCR<a href="#2-批量ocr"><span>#</span></a></h3><p>批量OCR功能可以一次性导入大量图片进行识别：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- 支持格式：jpg, jpeg, png, webp, bmp, tif等</span></div></div><div><div><div>2</div></div><div><span>- 输出格式：txt, jsonl, md, csv(Excel)</span></div></div><div><div><div>3</div></div><div><span>- 支持文本后处理，整理排版和顺序</span></div></div><div><div><div>4</div></div><div><span>- 无数量上限，可一次性导入几百张</span></div></div><div><div><div>5</div></div><div><span>- 支持任务完成后自动关机/待机</span></div></div><div><div><div>6</div></div><div><span>- 支持处理超大长图</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/61c49eb095e34bcd8b9bbcb69e2916ff20260625134850316.png" alt="" />
<strong>忽略区域</strong>：可以排除图片中不想要的文字，比如水印、LOGO等：</p><ul>
<li>在批量识别页右栏设置中进入忽略区域编辑器</li>
<li>按住右键绘制矩形框，框内的文字将被忽略</li>
<li>适合处理带有水印的批量图片</li>
</ul></section><section><h3>3. 文档识别<a href="#3-文档识别"><span>#</span></a></h3><p>文档识别功能可以处理PDF等文档格式：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- 支持格式：pdf, xps, epub, mobi, fb2, cbz</span></div></div><div><div><div>2</div></div><div><span>- 对扫描件进行OCR，提取原有文本</span></div></div><div><div><div>3</div></div><div><span>- 可输出为双层可搜索PDF</span></div></div><div><div><div>4</div></div><div><span>- 支持设定忽略区域，排除页眉页脚</span></div></div><div><div><div>5</div></div><div><span>- 支持任务完成后自动关机/休眠</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/e8af88009fe040e892e66d890874116720260625134938433.png" alt="" /></p></section><section><h3>4. 二维码<a href="#4-二维码"><span>#</span></a></h3><p>二维码功能支持扫码和生成：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>扫码：</span></div></div><div><div><div>2</div></div><div><span>- 截图/粘贴/拖入图片，读取二维码、条形码</span></div></div><div><div><div>3</div></div><div><span>- 支持一图多码</span></div></div><div><div><div>4</div></div><div><span>- 支持19种协议（QRCode、DataMatrix、PDF417等）</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>生成码：</span></div></div><div><div><div>7</div></div><div><span>- 输入文本，生成二维码图片</span></div></div><div><div><div>8</div></div><div><span>- 支持19种协议和纠错等级</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/b75c2c33c6fb43f0b8a0a5e52ac93c5c20260625135013265.png" alt="" /></p></section><section><h3>5. 全局设置<a href="#5-全局设置"><span>#</span></a></h3><p>全局设置可以调整软件的各种参数：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- 一键添加快捷方式或设置开机自启</span></div></div><div><div><div>2</div></div><div><span>- 更改界面语言（支持繁中、英语、日语等）</span></div></div><div><div><div>3</div></div><div><span>- 切换界面主题（多个亮/暗主题）</span></div></div><div><div><div>4</div></div><div><span>- 调整界面文字大小和字体</span></div></div><div><div><div>5</div></div><div><span>- 切换OCR插件</span></div></div><div><div><div>6</div></div><div><span>- 调整渲染器（解决截屏闪烁、UI错位问题）</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/f9ee9d3ca2cc45a9b2d7a2b33e1ba0c420260625135057548.png" alt="" /></p></section></section>
<section><h2>🚀 安装方式<a href="#-安装方式"><span>#</span></a></h2><section><h3>方式一：下载压缩包（推荐）<a href="#方式一下载压缩包推荐"><span>#</span></a></h3><ol>
<li>访问 GitHub 发布页面：<a href="https://github.com/hiroi-sora/Umi-OCR/releases/latest" target="_blank">https://github.com/hiroi-sora/Umi-OCR/releases/latest</a></li>
<li>下载 <code>.7z</code> 压缩包或 <code>.7z.exe</code> 自解压包</li>
<li>解压后点击 <code>Umi-OCR.exe</code> 即可启动</li>
</ol><p><strong>国内下载地址</strong>（蓝奏云，免注册/无限速）：
<a href="https://hiroi-sora.lanzoul.com/s/umi-ocr" target="_blank">https://hiroi-sora.lanzoul.com/s/umi-ocr</a></p></section><section><h3>方式二：Scoop 安装（Windows）<a href="#方式二scoop-安装windows"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 添加 extras 桶</span></div></div><div><div><div>2</div></div><div><span>scoop</span><span> </span><span>bucket</span><span> </span><span>add</span><span> </span><span>extras</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 安装 Umi-OCR（Rapid-OCR引擎，兼容性好）</span></div></div><div><div><div>5</div></div><div><span>scoop</span><span> </span><span>install</span><span> </span><span>extras/umi-ocr</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 或安装 Paddle-OCR 引擎版本（速度稍快）</span></div></div><div><div><div>8</div></div><div><span>scoop</span><span> </span><span>install</span><span> </span><span>extras/umi-ocr-paddle</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>方式三：Linux 安装<a href="#方式三linux-安装"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 下载压缩包</span></div></div><div><div><div>2</div></div><div><span>wget</span><span> </span><span>https://github.com/hiroi-sora/Umi-OCR/releases/latest/download/Umi-OCR-linux-x64.7z</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 解压</span></div></div><div><div><div>5</div></div><div><span>7z</span><span> </span><span>x</span><span> </span><span>Umi-OCR-linux-x64.7z</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 运行</span></div></div><div><div><div>8</div></div><div><span>./Umi-OCR/umi-ocr.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>📝 使用场景<a href="#-使用场景"><span>#</span></a></h2><section><h3>场景一：截图识别文字<a href="#场景一截图识别文字"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>操作步骤：</span></div></div><div><div><div>2</div></div><div><span>1. 按下 Ctrl+Shift+A 唤起截图</span></div></div><div><div><div>3</div></div><div><span>2. 框选需要识别的区域</span></div></div><div><div><div>4</div></div><div><span>3. 识别结果自动显示在右侧</span></div></div><div><div><div>5</div></div><div><span>4. 复制识别结果即可</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>适用场景：</span></div></div><div><div><div>8</div></div><div><span>- 复制网页上无法选中的文字</span></div></div><div><div><div>9</div></div><div><span>- 识别PDF中的文字</span></div></div><div><div><div>10</div></div><div><span>- 提取截图中的关键信息</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>场景二：批量处理图片<a href="#场景二批量处理图片"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>操作步骤：</span></div></div><div><div><div>2</div></div><div><span>1. 切换到"批量OCR"标签页</span></div></div><div><div><div>3</div></div><div><span>2. 导入需要识别的图片</span></div></div><div><div><div>4</div></div><div><span>3. 设置忽略区域（如有水印）</span></div></div><div><div><div>5</div></div><div><span>4. 选择输出格式</span></div></div><div><div><div>6</div></div><div><span>5. 点击开始识别</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span>适用场景：</span></div></div><div><div><div>9</div></div><div><span>- 处理大量扫描件</span></div></div><div><div><div>10</div></div><div><span>- 识别图片库中的文字</span></div></div><div><div><div>11</div></div><div><span>- 批量提取截图内容</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>场景三：PDF识别<a href="#场景三pdf识别"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>操作步骤：</span></div></div><div><div><div>2</div></div><div><span>1. 切换到"文档识别"标签页</span></div></div><div><div><div>3</div></div><div><span>2. 导入PDF文件</span></div></div><div><div><div>4</div></div><div><span>3. 设置输出格式（txt或双层PDF）</span></div></div><div><div><div>5</div></div><div><span>4. 点击开始识别</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>适用场景：</span></div></div><div><div><div>8</div></div><div><span>- 将扫描版PDF转为可搜索PDF</span></div></div><div><div><div>9</div></div><div><span>- 提取PDF中的文字内容</span></div></div><div><div><div>10</div></div><div><span>- 批量处理PDF文档</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>场景四：二维码处理<a href="#场景四二维码处理"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>扫码：</span></div></div><div><div><div>2</div></div><div><span>1. 切换到"二维码"标签页</span></div></div><div><div><div>3</div></div><div><span>2. 粘贴或拖入包含二维码的图片</span></div></div><div><div><div>4</div></div><div><span>3. 自动识别并显示结果</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>生成码：</span></div></div><div><div><div>7</div></div><div><span>1. 切换到"二维码"标签页</span></div></div><div><div><div>8</div></div><div><span>2. 输入要生成的文本</span></div></div><div><div><div>9</div></div><div><span>3. 选择协议和纠错等级</span></div></div><div><div><div>10</div></div><div><span>4. 生成二维码图片</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>适用场景：</span></div></div><div><div><div>13</div></div><div><span>- 识别商品包装上的二维码</span></div></div><div><div><div>14</div></div><div><span>- 生成分享链接二维码</span></div></div><div><div><div>15</div></div><div><span>- 批量生成二维码</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>场景五：命令行调用<a href="#场景五命令行调用"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 截图识别</span></div></div><div><div><div>2</div></div><div><span>Umi-OCR.exe</span><span> </span><span>--clipboard</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 识别单张图片</span></div></div><div><div><div>5</div></div><div><span>Umi-OCR.exe</span><span> </span><span>--img</span><span> </span><span>"C:\test.png"</span><span> </span><span>--out</span><span> </span><span>"C:\result.txt"</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 批量识别</span></div></div><div><div><div>8</div></div><div><span>Umi-OCR.exe</span><span> </span><span>--img</span><span> </span><span>"C:\images"</span><span> </span><span>--out</span><span> </span><span>"C:\result"</span><span> </span><span>--format</span><span> </span><span>md</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 识别PDF</span></div></div><div><div><div>11</div></div><div><span>Umi-OCR.exe</span><span> </span><span>--pdf</span><span> </span><span>"C:\test.pdf"</span><span> </span><span>--out</span><span> </span><span>"C:\result.txt"</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># 二维码识别</span></div></div><div><div><div>14</div></div><div><span>Umi-OCR.exe</span><span> </span><span>--qr</span><span> </span><span>"C:\qrcode.png"</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>🌐 HTTP接口调用<a href="#-http接口调用"><span>#</span></a></h2><p>除了命令行，Umi-OCR还支持HTTP接口调用，方便开发者集成到自己的应用中。</p><section><h3>启用HTTP服务<a href="#启用http服务"><span>#</span></a></h3><p>在全局设置页中勾选<strong>高级</strong>，确保HTTP服务已开启（默认开启）。如果需要允许局域网访问，请将主机切换到<strong>任何可用地址</strong>。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/56f1696c32fe4e429355dcdca8b5e54a20260625140239358.png" alt="" /></p></section><section><h3>API调用示例<a href="#api调用示例"><span>#</span></a></h3><p><strong>图片OCR识别（Base64方式）</strong>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>curl</span><span> </span><span>-X</span><span> </span><span>POST</span><span> </span><span>http://localhost:10101/api/ocr</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>-H</span><span> </span><span>"Content-Type: application/json"</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>-d</span><span> </span><span>'{"image": "base64编码的图片数据"}'</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>二维码识别</strong>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>curl</span><span> </span><span>-X</span><span> </span><span>POST</span><span> </span><span>http://localhost:10101/api/qrcode</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>-H</span><span> </span><span>"Content-Type: application/json"</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>-d</span><span> </span><span>'{"image": "base64编码的图片数据"}'</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>PDF文档识别</strong>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>curl</span><span> </span><span>-X</span><span> </span><span>POST</span><span> </span><span>http://localhost:10101/api/doc</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>-H</span><span> </span><span>"Content-Type: application/json"</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>-d</span><span> </span><span>'{"files": ["base64编码的PDF数据"], "outputFormat": "txt"}'</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>获取OCR参数</strong>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>curl</span><span> </span><span>http://localhost:10101/api/ocr/get_options</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>注意事项<a href="#注意事项"><span>#</span></a></h3><ul>
<li>关闭软件时，如果仍有用户未断开HTTP连接，可能导致关闭不完全，需进任务管理器强制结束进程</li>
<li>并发支持较差，尽量不要并发调用</li>
<li>长时间大批量连续调用时，可能出现连接拒绝报错，重新发起请求即可</li>
</ul></section></section>
<section><h2>📊 对比其他方案<a href="#-对比其他方案"><span>#</span></a></h2>

<table><thead><tr><th>方案</th><th>离线</th><th>免费</th><th>批量处理</th><th>PDF识别</th><th>二维码</th><th>公式识别</th><th>命令行</th></tr></thead><tbody><tr><td><strong>Umi-OCR</strong></td><td>✅</td><td>✅</td><td>✅</td><td>✅</td><td>✅</td><td>✅</td><td>✅</td></tr><tr><td><strong>在线OCR工具</strong></td><td>❌</td><td>✅/付费</td><td>❌</td><td>✅</td><td>❌</td><td>❌</td><td>❌</td></tr><tr><td><strong>天若OCR</strong></td><td>✅</td><td>✅</td><td>❌</td><td>❌</td><td>❌</td><td>❌</td><td>❌</td></tr><tr><td><strong>白描</strong></td><td>❌</td><td>付费</td><td>✅</td><td>✅</td><td>✅</td><td>❌</td><td>❌</td></tr><tr><td><strong>Adobe Acrobat</strong></td><td>✅</td><td>付费</td><td>✅</td><td>✅</td><td>❌</td><td>✅</td><td>❌</td></tr></tbody></table></section>
<section><h2>📜 开源协议<a href="#-开源协议"><span>#</span></a></h2><p>Umi-OCR 采用 <strong>Apache-2.0</strong> 开源协议，完全免费使用。</p></section>
<section><h2>📝 总结<a href="#-总结"><span>#</span></a></h2><p>Umi-OCR 是一款功能强大的免费离线OCR软件，特别适合需要处理大量图片文字、PDF扫描件的用户。它支持截图识别、批量OCR、PDF识别、二维码、公式识别等多种功能，所有处理都在本地完成，无需网络，数据安全有保障。无论是学生、上班族还是开发者，都能从中受益。如果你经常需要识别图片中的文字，这个工具绝对值得一试！</p></section>
<section><h2>🌟 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub 地址</strong>: <a href="https://github.com/hiroi-sora/Umi-OCR" target="_blank">https://github.com/hiroi-sora/Umi-OCR</a></p><p><strong>发布页面</strong>: <a href="https://github.com/hiroi-sora/Umi-OCR/releases/latest" target="_blank">https://github.com/hiroi-sora/Umi-OCR/releases/latest</a></p><p><strong>国内下载</strong>: <a href="https://hiroi-sora.lanzoul.com/s/umi-ocr" target="_blank">https://hiroi-sora.lanzoul.com/s/umi-ocr</a></p><p><strong>插件库</strong>: <a href="https://github.com/hiroi-sora/Umi-OCR_plugins" target="_blank">https://github.com/hiroi-sora/Umi-OCR_plugins</a></p><p><strong>命令行手册</strong>: <a href="https://github.com/hiroi-sora/Umi-OCR/blob/main/docs/README_CLI.md" target="_blank">https://github.com/hiroi-sora/Umi-OCR/blob/main/docs/README_CLI.md</a></p><p><strong>HTTP接口手册</strong>: <a href="https://github.com/hiroi-sora/Umi-OCR/blob/main/docs/http/README.md" target="_blank">https://github.com/hiroi-sora/Umi-OCR/blob/main/docs/http/README.md</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p></section>
<section><h2>🎉 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你最常用的OCR功能是什么？在使用过程中遇到过什么问题？欢迎在评论区和我交流分享！</p><p>我会定期分享更多好用的工具，记得关注我哦！</p><hr /><p><strong>推荐阅读</strong>:</p><ul>
<li><a href="https://mp.weixin.qq.com/s/3atWsj1GmVG6Q5mfLM7Tzg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！yantr：自托管应用商店，不占用系统资源，130+应用一键部署</a></li>
<li><a href="https://mp.weixin.qq.com/s/tESfza_v76eAVFoS4dnjgg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！BentoPDF：浏览器端隐私优先的PDF工具箱，50+工具一键搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/tm9H33eCtmQCSDoGclENkA?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！PakePlus：网页秒变桌面应用</a></li>
<li><a href="https://mp.weixin.qq.com/s/1W0KIPzAXGLXjl7jyEsYEA?token=1837315026&amp;lang=zh_CN" target="_blank">服务器到期宕机？域名过期被抢注？这个工具帮你守住所有服务</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/docker/penpot-intro/</id>
      <title type="text">Figma太贵？这个开源设计平台，支持自托管，设计即代码</title>
      <published>2026-06-24T00:00:00.000Z</published>
      <updated>2026-06-24T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/docker/penpot-intro/"/>
      <summary type="text">面向团队的开源设计平台，支持实时协作、设计即代码、设计令牌、MCP服务器，可自建部署，完全免费开源！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！设计工具太贵还被绑定？<a href="#朋友们设计工具太贵还被绑定"><span>#</span></a></h2><p>你是不是经常遇到这些困扰：</p><ul>
<li><strong>Figma太贵</strong>：团队协作需要付费，而且价格越来越高</li>
<li><strong>数据不安全</strong>：设计稿存放在第三方云端，担心数据泄露</li>
<li><strong>设计开发脱节</strong>：设计师设计的效果，开发还原不出来</li>
<li><strong>无法自托管</strong>：想在公司内网部署，却没有合适的方案</li>
<li><strong>设计系统难维护</strong>：设计令牌、组件库难以统一管理</li>
<li><strong>AI集成困难</strong>：想让AI参与设计流程，却没有合适的接口</li>
</ul><p>今天我要给大家分享一个 GitHub 上的宝藏项目——<strong>Penpot</strong>！这是一款面向团队的开源设计平台，支持实时协作、设计即代码、设计令牌、MCP服务器，可自建部署，完全免费开源！</p></section>
<section><h2>✨ 什么是 Penpot？<a href="#-什么是-penpot"><span>#</span></a></h2><p>Penpot 是一款<strong>面向团队的开源设计平台</strong>，专为大规模构建数字产品而设计。它的核心优势在于让您<strong>完全拥有设计基础设施的所有权</strong>，基于开源技术构建，支持自托管部署，让团队完全控制设计环境，满足严格的合规和治理要求。</p><p><strong>核心特点</strong>：</p><ul>
<li>🔓 <strong>开源免费</strong>：完全开源，无任何隐藏费用</li>
<li>🏠 <strong>支持自托管</strong>：可部署在自己的服务器上，数据完全自主可控</li>
<li>🎨 <strong>设计即代码</strong>：设计以代码形式表达，开发者可以直接理解和使用</li>
<li>🔄 <strong>实时协作</strong>：多人实时协作设计，支持团队协作</li>
<li>🎯 <strong>设计令牌</strong>：原生设计令牌支持，确保设计一致性</li>
<li>🔌 <strong>MCP服务器</strong>：支持设计和代码之间的双向工作流</li>
<li>📡 <strong>开放API</strong>：强大的开放API和插件系统，支持自动化和AI工作流</li>
<li>📱 <strong>响应式设计</strong>：支持 CSS Grid 和 Flex Layout，设计响应式界面</li>
<li>🌐 <strong>开放标准</strong>：支持 SVG、CSS、HTML、JSON 等开放标准</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/62c1d53335e84cfda17e62ee13a3b2cb20260624154307534.png" alt="" /></p></section>
<section><h2>🎯 核心功能<a href="#-核心功能"><span>#</span></a></h2><section><h3>1. 实时协作设计<a href="#1-实时协作设计"><span>#</span></a></h3><p>Penpot 支持多人实时协作，团队成员可以同时编辑同一个设计文件：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- 多人实时编辑</span></div></div><div><div><div>2</div></div><div><span>- 实时光标显示</span></div></div><div><div><div>3</div></div><div><span>- 评论和标注</span></div></div><div><div><div>4</div></div><div><span>- 版本历史</span></div></div><div><div><div>5</div></div><div><span>- 设计评审</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/a107574c826a458c8daa4d21b505669620260624155333737.png" alt="" /></p></section><section><h3>2. 设计即代码<a href="#2-设计即代码"><span>#</span></a></h3><p>Penpot 最大的特色之一就是设计以代码形式表达，这让开发者可以直接理解和使用设计：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- 设计以 JSON 格式存储</span></div></div><div><div><div>2</div></div><div><span>- 支持 SVG、CSS、HTML 导出</span></div></div><div><div><div>3</div></div><div><span>- Inspect 模式提供即时代码访问</span></div></div><div><div><div>4</div></div><div><span>- 设计可以直接转换为代码</span></div></div><div><div><div>5</div></div><div><span>- 开发者可以轻松理解设计意图</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/6f5ac371efe5482b8f866e007cab401120260624160038610.png" alt="" /></p></section><section><h3>3. 设计令牌（Design Tokens）<a href="#3-设计令牌design-tokens"><span>#</span></a></h3><p>原生设计令牌支持，提供设计和开发之间的单一事实来源：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- 原生设计令牌支持</span></div></div><div><div><div>2</div></div><div><span>- 确保设计一致性</span></div></div><div><div><div>3</div></div><div><span>- 简化设计系统管理</span></div></div><div><div><div>4</div></div><div><span>- 支持复杂设计系统</span></div></div><div><div><div>5</div></div><div><span>- 设计和开发共享同一来源</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/07f7f1f901654fdeaf8462120b55f8f120260624160113230.png" alt="" /></p></section><section><h3>4. MCP 服务器<a href="#4-mcp-服务器"><span>#</span></a></h3><p>MCP（Model Context Protocol）服务器实现设计和代码之间的双向工作流：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- 支持设计到代码的转换</span></div></div><div><div><div>2</div></div><div><span>- 支持代码到设计的更新</span></div></div><div><div><div>3</div></div><div><span>- AI可以读取和理解设计</span></div></div><div><div><div>4</div></div><div><span>- 实现自动化工作流</span></div></div><div><div><div>5</div></div><div><span>- 集成现有工具和系统</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/dae83f63958f4f3b9d966ae898d96a8f20260624160148568.png" alt="" /></p></section><section><h3>5. 响应式设计<a href="#5-响应式设计"><span>#</span></a></h3><p>支持 CSS Grid 和 Flex Layout，从一开始就设计出像真实代码一样响应的界面：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- CSS Grid 布局支持</span></div></div><div><div><div>2</div></div><div><span>- Flex Layout 支持</span></div></div><div><div><div>3</div></div><div><span>- 响应式断点设置</span></div></div><div><div><div>4</div></div><div><span>- 设计真实的响应式界面</span></div></div><div><div><div>5</div></div><div><span>- 从设计到代码无缝转换</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/f69780a148204a93bc685c761d5e5eac20260624160242962.png" alt="" /></p></section></section>
<section><h2>🚀 部署方式<a href="#-部署方式"><span>#</span></a></h2><section><h3>方式一：使用 SAAS 版本<a href="#方式一使用-saas-版本"><span>#</span></a></h3><p>直接访问 <a href="https://design.penpot.app%EF%BC%8C%E6%97%A0%E9%9C%80%E9%83%A8%E7%BD%B2%EF%BC%8C%E7%AB%8B%E5%8D%B3%E4%BD%BF%E7%94%A8%E3%80%82" target="_blank">https://design.penpot.app，无需部署，立即使用。</a></p></section><section><h3>方式二：Docker 部署（推荐）<a href="#方式二docker-部署推荐"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 创建目录</span></div></div><div><div><div>2</div></div><div><span>mkdir</span><span> </span><span>penpot</span><span> &amp;&amp; </span><span>cd</span><span> </span><span>penpot</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 创建 docker-compose.yaml</span></div></div><div><div><div>5</div></div><div><span>curl</span><span> </span><span>-o</span><span> </span><span>docker-compose.yaml</span><span> </span><span>https://raw.githubusercontent.com/penpot/penpot/main/docker/images/docker-compose.yaml</span></div></div><div><div><div>6</div></div><div><span># 启动服务</span></div></div><div><div><div>7</div></div><div><span>docker</span><span> </span><span>compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># ============================== Penpot 配置说明 ==============================</span></div></div><div><div><div>2</div></div><div><span># 功能开关标识列表（可在PENPOT_FLAGS中按需增删）</span></div></div><div><div><div>3</div></div><div><span># demo-users: 内置演示账号</span></div></div><div><div><div>4</div></div><div><span># email-verification: 注册邮箱验证</span></div></div><div><div><div>5</div></div><div><span># log-emails: 打印邮件日志</span></div></div><div><div><div>6</div></div><div><span># log-invitation-tokens: 打印邀请链接Token日志</span></div></div><div><div><div>7</div></div><div><span># login-with-github: GitHub第三方登录</span></div></div><div><div><div>8</div></div><div><span># login-with-gitlab: GitLab第三方登录</span></div></div><div><div><div>9</div></div><div><span># login-with-google: Google第三方登录</span></div></div><div><div><div>10</div></div><div><span># login-with-ldap: LDAP登录</span></div></div><div><div><div>11</div></div><div><span># login-with-oidc: OIDC统一身份登录</span></div></div><div><div><div>12</div></div><div><span># login-with-password: 账号密码登录</span></div></div><div><div><div>13</div></div><div><span># prepl-server: 开启调试PREPL服务</span></div></div><div><div><div>14</div></div><div><span># registration: 允许自助注册账号</span></div></div><div><div><div>15</div></div><div><span># secure-session-cookies: 会话Cookie启用安全加密（公网部署必须开启）</span></div></div><div><div><div>16</div></div><div><span># smtp: 启用邮件发送服务</span></div></div><div><div><div>17</div></div><div><span># smtp-debug: SMTP通信调试日志</span></div></div><div><div><div>18</div></div><div><span># telemetry: 匿名使用数据上报</span></div></div><div><div><div>19</div></div><div><span># webhooks: WebHook回调能力</span></div></div><div><div><div>20</div></div><div><span># 官方完整配置文档：https://help.penpot.app/technical-guide/configuration/#penpot-configuration</span></div></div><div><div><div>21</div></div><div><span># 安全警告：公网对外部署务必删除 disable-secure-session-cookies、disable-email-verification 关闭项</span></div></div><div><div><div>22</div></div><div><span># ============================================================================</span></div></div><div><div><div>23</div></div><div>
</div></div><div><div><div>24</div></div><div><span># 全局功能开关配置</span></div></div><div><div><div>25</div></div><div><span>x-flags</span><span>: </span><span>&amp;</span><span>penpot-flags</span></div></div><div><div><div>26</div></div><div><span>  </span><span>PENPOT_FLAGS</span><span>: </span><span>disable-email-verification enable-smtp enable-prepl-server disable-secure-session-cookies enable-mcp</span></div></div><div><div><div>27</div></div><div>
</div></div><div><div><div>28</div></div><div><span># Penpot前端访问公网地址</span></div></div><div><div><div>29</div></div><div><span>x-uri</span><span>: </span><span>&amp;</span><span>penpot-public-uri</span></div></div><div><div><div>30</div></div><div><span>  </span><span>PENPOT_PUBLIC_URI</span><span>: </span><span>http://localhost:9001</span></div></div><div><div><div>31</div></div><div>
</div></div><div><div><div>32</div></div><div><span># HTTP请求体大小限制（上传大设计文件使用）</span></div></div><div><div><div>33</div></div><div><span>x-body-size</span><span>: </span><span>&amp;</span><span>penpot-http-body-size</span></div></div><div><div><div>34</div></div><div><span>  </span><span># 最大单请求Body上限</span></div></div><div><div><div>35</div></div><div><span>  </span><span>PENPOT_HTTP_SERVER_MAX_BODY_SIZE</span><span>: </span><span>367001600</span></div></div><div><div><div>36</div></div><div><span>  </span><span># 兼容旧版变量（已废弃，仅做向下兼容保留）</span></div></div><div><div><div>37</div></div><div><span>  </span><span>PENPOT_HTTP_SERVER_MAX_MULTIPART_BODY_SIZE</span><span>: </span><span>367001600</span></div></div><div><div><div>38</div></div><div>
</div></div><div><div><div>39</div></div><div><span># Penpot主密钥，用于会话、邀请链接等子密钥派生</span></div></div><div><div><div>40</div></div><div><span># 推荐使用512位Base64随机字符串生成，生成命令：python3 -c "import secrets; print(secrets.token_urlsafe(64))"</span></div></div><div><div><div>41</div></div><div><span>x-secret-key</span><span>: </span><span>&amp;</span><span>penpot-secret-key</span></div></div><div><div><div>42</div></div><div><span>  </span><span>PENPOT_SECRET_KEY</span><span>: </span><span>change-this-insecure-key</span></div></div><div><div><div>43</div></div><div>
</div></div><div><div><div>44</div></div><div><span># 自定义Docker网络，所有服务互通</span></div></div><div><div><div>45</div></div><div><span>networks</span><span>:</span></div></div><div><div><div>46</div></div><div><span>  </span><span>penpot</span><span>:</span></div></div><div><div><div>47</div></div><div>
</div></div><div><div><div>48</div></div><div><span># 持久化数据卷</span></div></div><div><div><div>49</div></div><div><span>volumes</span><span>:</span></div></div><div><div><div>50</div></div><div><span>  </span><span>penpot_postgres_v15</span><span>:  </span><span># PostgreSQL数据库存储卷</span></div></div><div><div><div>51</div></div><div><span>  </span><span>penpot_assets</span><span>:         </span><span># 上传素材、设计文件存储卷</span></div></div><div><div><div>52</div></div><div>
</div></div><div><div><div>53</div></div><div><span>services</span><span>:</span></div></div><div><div><div>54</div></div><div><span>  </span><span># 前端页面服务，用户访问入口</span></div></div><div><div><div>55</div></div><div><span>  </span><span>penpot-frontend</span><span>:</span></div></div><div><div><div>56</div></div><div><span>    </span><span>image</span><span>: </span><span>"penpotapp/frontend:${PENPOT_VERSION:-2.16}"</span></div></div><div><div><div>57</div></div><div><span>    </span><span>restart</span><span>: </span><span>always</span></div></div><div><div><div>58</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>59</div></div><div><span><span>      </span></span><span>- </span><span>9001:8080</span></div></div><div><div><div>60</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>61</div></div><div><span><span>      </span></span><span>- </span><span>penpot_assets:/opt/data/assets</span></div></div><div><div><div>62</div></div><div><span>    </span><span># 依赖服务启动完成后再启动前端</span></div></div><div><div><div>63</div></div><div><span>    </span><span>depends_on</span><span>:</span></div></div><div><div><div>64</div></div><div><span><span>      </span></span><span>- </span><span>penpot-backend</span></div></div><div><div><div>65</div></div><div><span><span>      </span></span><span>- </span><span>penpot-exporter</span></div></div><div><div><div>66</div></div><div><span><span>      </span></span><span>- </span><span>penpot-mcp</span></div></div><div><div><div>67</div></div><div><span>    </span><span>networks</span><span>:</span></div></div><div><div><div>68</div></div><div><span><span>      </span></span><span>- </span><span>penpot</span></div></div><div><div><div>69</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>70</div></div><div><span>      </span><span>&lt;&lt;</span><span> : [</span><span>*</span><span>penpot-flags</span><span>, </span><span>*</span><span>penpot-http-body-size</span><span>, </span><span>*</span><span>penpot-public-uri</span><span>]</span></div></div><div><div><div>71</div></div><div>
</div></div><div><div><div>72</div></div><div><span>  </span><span># Penpot后端核心业务服务</span></div></div><div><div><div>73</div></div><div><span>  </span><span>penpot-backend</span><span>:</span></div></div><div><div><div>74</div></div><div><span>    </span><span>image</span><span>: </span><span>"penpotapp/backend:${PENPOT_VERSION:-2.16}"</span></div></div><div><div><div>75</div></div><div><span>    </span><span>restart</span><span>: </span><span>always</span></div></div><div><div><div>76</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>77</div></div><div><span><span>      </span></span><span>- </span><span>penpot_assets:/opt/data/assets</span></div></div><div><div><div>78</div></div><div><span>    </span><span># 等待数据库、缓存健康就绪再启动</span></div></div><div><div><div>79</div></div><div><span>    </span><span>depends_on</span><span>:</span></div></div><div><div><div>80</div></div><div><span>      </span><span>penpot-postgres</span><span>:</span></div></div><div><div><div>81</div></div><div><span>        </span><span>condition</span><span>: </span><span>service_healthy</span></div></div><div><div><div>82</div></div><div><span>      </span><span>penpot-valkey</span><span>:</span></div></div><div><div><div>83</div></div><div><span>        </span><span>condition</span><span>: </span><span>service_healthy</span></div></div><div><div><div>84</div></div><div><span>    </span><span>networks</span><span>:</span></div></div><div><div><div>85</div></div><div><span><span>      </span></span><span>- </span><span>penpot</span></div></div><div><div><div>86</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>87</div></div><div><span>      </span><span>&lt;&lt;</span><span> : [</span><span>*</span><span>penpot-flags</span><span>, </span><span>*</span><span>penpot-public-uri</span><span>, </span><span>*</span><span>penpot-http-body-size</span><span>, </span><span>*</span><span>penpot-secret-key</span><span>]</span></div></div><div><div><div>88</div></div><div><span>      </span><span># PostgreSQL数据库连接配置</span></div></div><div><div><div>89</div></div><div><span>      </span><span>PENPOT_DATABASE_URI</span><span>: </span><span>postgresql://penpot-postgres/penpot</span></div></div><div><div><div>90</div></div><div><span>      </span><span>PENPOT_DATABASE_USERNAME</span><span>: </span><span>penpot</span></div></div><div><div><div>91</div></div><div><span>      </span><span>PENPOT_DATABASE_PASSWORD</span><span>: </span><span>penpot</span></div></div><div><div><div>92</div></div><div><span>      </span><span># Valkey缓存（原Redis），用于WebSocket实时通知</span></div></div><div><div><div>93</div></div><div><span>      </span><span>PENPOT_REDIS_URI</span><span>: </span><span>redis://penpot-valkey/0</span></div></div><div><div><div>94</div></div><div><span>      </span><span># 文件存储配置：本地文件系统模式</span></div></div><div><div><div>95</div></div><div><span>      </span><span>PENPOT_OBJECTS_STORAGE_BACKEND</span><span>: </span><span>fs</span></div></div><div><div><div>96</div></div><div><span>      </span><span>PENPOT_OBJECTS_STORAGE_FS_DIRECTORY</span><span>: </span><span>/opt/data/assets</span></div></div><div><div><div>97</div></div><div><span>      </span><span># 匿名使用数据上报</span></div></div><div><div><div>98</div></div><div><span>      </span><span>PENPOT_TELEMETRY_ENABLED</span><span>: </span><span>"true"</span></div></div><div><div><div>99</div></div><div><span>      </span><span>PENPOT_TELEMETRY_REFERER</span><span>: </span><span>compose</span></div></div><div><div><div>100</div></div><div><span>      </span><span># SMTP邮件发送配置（当前使用内置邮件捕获容器）</span></div></div><div><div><div>101</div></div><div><span>      </span><span>PENPOT_SMTP_DEFAULT_FROM</span><span>: </span><span>no-reply@example.com</span></div></div><div><div><div>102</div></div><div><span>      </span><span>PENPOT_SMTP_DEFAULT_REPLY_TO</span><span>: </span><span>no-reply@example.com</span></div></div><div><div><div>103</div></div><div><span>      </span><span>PENPOT_SMTP_HOST</span><span>: </span><span>penpot-mailcatch</span></div></div><div><div><div>104</div></div><div><span>      </span><span>PENPOT_SMTP_PORT</span><span>: </span><span>1025</span></div></div><div><div><div>105</div></div><div><span>      </span><span>PENPOT_SMTP_USERNAME</span><span>:</span></div></div><div><div><div>106</div></div><div><span>      </span><span>PENPOT_SMTP_PASSWORD</span><span>:</span></div></div><div><div><div>107</div></div><div><span>      </span><span>PENPOT_SMTP_TLS</span><span>: </span><span>"false"</span></div></div><div><div><div>108</div></div><div><span>      </span><span>PENPOT_SMTP_SSL</span><span>: </span><span>"false"</span></div></div><div><div><div>109</div></div><div>
</div></div><div><div><div>110</div></div><div><span>  </span><span># MCP服务扩展组件</span></div></div><div><div><div>111</div></div><div><span>  </span><span>penpot-mcp</span><span>:</span></div></div><div><div><div>112</div></div><div><span>    </span><span>image</span><span>: </span><span>"penpotapp/mcp:${PENPOT_VERSION:-2.16}"</span></div></div><div><div><div>113</div></div><div><span>    </span><span>restart</span><span>: </span><span>always</span></div></div><div><div><div>114</div></div><div><span>    </span><span>networks</span><span>:</span></div></div><div><div><div>115</div></div><div><span><span>      </span></span><span>- </span><span>penpot</span></div></div><div><div><div>116</div></div><div>
</div></div><div><div><div>117</div></div><div><span>  </span><span># 图纸导出服务（生成图片/PDF等导出能力）</span></div></div><div><div><div>118</div></div><div><span>  </span><span>penpot-exporter</span><span>:</span></div></div><div><div><div>119</div></div><div><span>    </span><span>image</span><span>: </span><span>"penpotapp/exporter:${PENPOT_VERSION:-2.16}"</span></div></div><div><div><div>120</div></div><div><span>    </span><span>restart</span><span>: </span><span>always</span></div></div><div><div><div>121</div></div><div><span>    </span><span>depends_on</span><span>:</span></div></div><div><div><div>122</div></div><div><span>      </span><span>penpot-valkey</span><span>:</span></div></div><div><div><div>123</div></div><div><span>        </span><span>condition</span><span>: </span><span>service_healthy</span></div></div><div><div><div>124</div></div><div><span>    </span><span>networks</span><span>:</span></div></div><div><div><div>125</div></div><div><span><span>      </span></span><span>- </span><span>penpot</span></div></div><div><div><div>126</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>127</div></div><div><span>      </span><span>&lt;&lt;</span><span> : [</span><span>*</span><span>penpot-secret-key</span><span>]</span></div></div><div><div><div>128</div></div><div><span>      </span><span># 内部网络访问前端地址，用于渲染导出</span></div></div><div><div><div>129</div></div><div><span>      </span><span>PENPOT_PUBLIC_URI</span><span>: </span><span>http://penpot-frontend:8080</span></div></div><div><div><div>130</div></div><div><span>      </span><span># 连接Valkey缓存</span></div></div><div><div><div>131</div></div><div><span>      </span><span>PENPOT_REDIS_URI</span><span>: </span><span>redis://penpot-valkey/0</span></div></div><div><div><div>132</div></div><div>
</div></div><div><div><div>133</div></div><div><span>  </span><span># PostgreSQL 数据库存储业务数据</span></div></div><div><div><div>134</div></div><div><span>  </span><span>penpot-postgres</span><span>:</span></div></div><div><div><div>135</div></div><div><span>    </span><span>image</span><span>: </span><span>"postgres:15"</span></div></div><div><div><div>136</div></div><div><span>    </span><span>restart</span><span>: </span><span>always</span></div></div><div><div><div>137</div></div><div><span>    </span><span>stop_signal</span><span>: </span><span>SIGINT</span></div></div><div><div><div>138</div></div><div><span>    </span><span># 数据库健康检测，等待就绪再提供服务</span></div></div><div><div><div>139</div></div><div><span>    </span><span>healthcheck</span><span>:</span></div></div><div><div><div>140</div></div><div><span>      </span><span>test</span><span>: [</span><span>"CMD-SHELL"</span><span>, </span><span>"pg_isready -U penpot"</span><span>]</span></div></div><div><div><div>141</div></div><div><span>      </span><span>interval</span><span>: </span><span>2s</span></div></div><div><div><div>142</div></div><div><span>      </span><span>timeout</span><span>: </span><span>10s</span></div></div><div><div><div>143</div></div><div><span>      </span><span>retries</span><span>: </span><span>5</span></div></div><div><div><div>144</div></div><div><span>      </span><span>start_period</span><span>: </span><span>2s</span></div></div><div><div><div>145</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>146</div></div><div><span><span>      </span></span><span>- </span><span>penpot_postgres_v15:/var/lib/postgresql/data</span></div></div><div><div><div>147</div></div><div><span>    </span><span>networks</span><span>:</span></div></div><div><div><div>148</div></div><div><span><span>      </span></span><span>- </span><span>penpot</span></div></div><div><div><div>149</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>150</div></div><div><span><span>      </span></span><span>- </span><span>POSTGRES_INITDB_ARGS=--data-checksums</span></div></div><div><div><div>151</div></div><div><span><span>      </span></span><span>- </span><span>POSTGRES_DB=penpot</span></div></div><div><div><div>152</div></div><div><span><span>      </span></span><span>- </span><span>POSTGRES_USER=penpot</span></div></div><div><div><div>153</div></div><div><span><span>      </span></span><span>- </span><span>POSTGRES_PASSWORD=penpot</span></div></div><div><div><div>154</div></div><div>
</div></div><div><div><div>155</div></div><div><span>  </span><span># Valkey缓存服务（兼容Redis协议），实时消息、会话缓存</span></div></div><div><div><div>156</div></div><div><span>  </span><span>penpot-valkey</span><span>:</span></div></div><div><div><div>157</div></div><div><span>    </span><span>image</span><span>: </span><span>valkey/valkey:8.1</span></div></div><div><div><div>158</div></div><div><span>    </span><span>restart</span><span>: </span><span>always</span></div></div><div><div><div>159</div></div><div><span>    </span><span># 缓存健康检测</span></div></div><div><div><div>160</div></div><div><span>    </span><span>healthcheck</span><span>:</span></div></div><div><div><div>161</div></div><div><span>      </span><span>test</span><span>: [</span><span>"CMD-SHELL"</span><span>, </span><span>"valkey-cli ping | grep PONG"</span><span>]</span></div></div><div><div><div>162</div></div><div><span>      </span><span>interval</span><span>: </span><span>1s</span></div></div><div><div><div>163</div></div><div><span>      </span><span>timeout</span><span>: </span><span>3s</span></div></div><div><div><div>164</div></div><div><span>      </span><span>retries</span><span>: </span><span>5</span></div></div><div><div><div>165</div></div><div><span>      </span><span>start_period</span><span>: </span><span>3s</span></div></div><div><div><div>166</div></div><div><span>    </span><span>networks</span><span>:</span></div></div><div><div><div>167</div></div><div><span><span>      </span></span><span>- </span><span>penpot</span></div></div><div><div><div>168</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>169</div></div><div><span>      </span><span># 限制最大内存及淘汰策略</span></div></div><div><div><div>170</div></div><div><span><span>      </span></span><span>- </span><span>VALKEY_EXTRA_FLAGS=--maxmemory 128mb --maxmemory-policy volatile-lfu</span></div></div><div><div><div>171</div></div><div>
</div></div><div><div><div>172</div></div><div><span>  </span><span># 测试用邮件捕获服务，接收所有系统发送邮件，1080端口网页查看</span></div></div><div><div><div>173</div></div><div><span>  </span><span># 生产环境请替换为真实SMTP服务器</span></div></div><div><div><div>174</div></div><div><span>  </span><span>penpot-mailcatch</span><span>:</span></div></div><div><div><div>175</div></div><div><span>    </span><span>image</span><span>: </span><span>sj26/mailcatcher:latest</span></div></div><div><div><div>176</div></div><div><span>    </span><span>restart</span><span>: </span><span>always</span></div></div><div><div><div>177</div></div><div><span>    </span><span>expose</span><span>:</span></div></div><div><div><div>178</div></div><div><span><span>      </span></span><span>- </span><span>'1025'</span></div></div><div><div><div>179</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>180</div></div><div><span><span>      </span></span><span>- </span><span>"1080:1080"</span></div></div><div><div><div>181</div></div><div><span>    </span><span>networks</span><span>:</span></div></div><div><div><div>182</div></div><div><span><span>      </span></span><span>- </span><span>penpot</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>访问 <code>http://localhost:9001</code> 即可使用。</p></section></section>
<section><h2>📝 使用指南<a href="#-使用指南"><span>#</span></a></h2><section><h3>快速开始<a href="#快速开始"><span>#</span></a></h3><ol>
<li>访问 Penpot（SAAS 版本或自建部署）</li>
<li>注册账户，创建团队</li>
<li>创建新项目</li>
<li>开始设计</li>
</ol></section><section><h3>设计流程<a href="#设计流程"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>1. 创建设计文件</span></div></div><div><div><div>2</div></div><div><span>2. 使用设计令牌定义样式</span></div></div><div><div><div>3</div></div><div><span>3. 创建组件和变体</span></div></div><div><div><div>4</div></div><div><span>4. 设计响应式界面</span></div></div><div><div><div>5</div></div><div><span>5. 团队协作评审</span></div></div><div><div><div>6</div></div><div><span>6. 导出代码（SVG/CSS/HTML）</span></div></div><div><div><div>7</div></div><div><span>7. 开发者实现</span></div></div><div><div><div>8</div></div><div><span>8. 通过 MCP 更新设计</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>开发者工作流<a href="#开发者工作流"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>1. 使用 Inspect 模式查看代码</span></div></div><div><div><div>2</div></div><div><span>2. 导出 SVG/CSS/HTML</span></div></div><div><div><div>3</div></div><div><span>3. 理解设计令牌</span></div></div><div><div><div>4</div></div><div><span>4. 实现设计</span></div></div><div><div><div>5</div></div><div><span>5. 通过 API 更新设计</span></div></div><div><div><div>6</div></div><div><span>6. 保持设计和代码同步</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>📊 对比其他方案<a href="#-对比其他方案"><span>#</span></a></h2>

<table><thead><tr><th>方案</th><th>开源</th><th>自托管</th><th>设计即代码</th><th>设计令牌</th><th>团队协作</th><th>成本</th></tr></thead><tbody><tr><td><strong>Penpot</strong></td><td>✅</td><td>✅</td><td>✅</td><td>✅</td><td>✅</td><td>🆓</td></tr><tr><td><strong>Figma</strong></td><td>❌</td><td>❌</td><td>❌</td><td>✅</td><td>✅</td><td>付费</td></tr><tr><td><strong>Sketch</strong></td><td>❌</td><td>❌</td><td>❌</td><td>✅</td><td>✅</td><td>付费</td></tr><tr><td><strong>Adobe XD</strong></td><td>❌</td><td>❌</td><td>❌</td><td>✅</td><td>✅</td><td>付费</td></tr><tr><td><strong>InVision</strong></td><td>❌</td><td>❌</td><td>❌</td><td>❌</td><td>✅</td><td>付费</td></tr></tbody></table></section>
<section><h2>📜 开源协议<a href="#-开源协议"><span>#</span></a></h2><p>Penpot 采用 <strong>MPL-2.0</strong>（Mozilla Public License 2.0）开源协议：</p><ul>
<li>可以免费使用、修改和分发</li>
<li>修改后的代码需要开源</li>
<li>适合商业和非商业用途</li>
</ul></section>
<section><h2>📝 总结<a href="#-总结"><span>#</span></a></h2><p>Penpot 是一款功能强大的开源设计平台，特别适合需要自托管部署、设计开发协作的团队。它支持实时协作、设计即代码、设计令牌、MCP服务器等核心功能，让设计和开发之间的工作流更加顺畅。无论是初创团队还是大型企业，都能从中受益。如果你正在寻找一个替代 Figma 的开源方案，或者需要在公司内网部署设计工具，Penpot 绝对值得一试！</p></section>
<section><h2>🌟 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>官方网站</strong>: <a href="https://penpot.app" target="_blank">https://penpot.app</a></p><p><strong>GitHub 地址</strong>: <a href="https://github.com/penpot/penpot" target="_blank">https://github.com/penpot/penpot</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p></section>
<section><h2>🎉 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你在团队协作设计中遇到过什么问题？最希望设计工具支持什么功能？欢迎在评论区和我交流分享！</p><p>我会定期分享更多好用的工具，记得关注我哦！</p><hr /><p><strong>推荐阅读</strong>:</p><ul>
<li><a href="https://mp.weixin.qq.com/s/3atWsj1GmVG6Q5mfLM7Tzg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！yantr：自托管应用商店，不占用系统资源，130+应用一键部署</a></li>
<li><a href="https://mp.weixin.qq.com/s/tESfza_v76eAVFoS4dnjgg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！BentoPDF：浏览器端隐私优先的PDF工具箱，50+工具一键搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/tm9H33eCtmQCSDoGclENkA?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！PakePlus：网页秒变桌面应用</a></li>
<li><a href="https://mp.weixin.qq.com/s/1W0KIPzAXGLXjl7jyEsYEA?token=1837315026&amp;lang=zh_CN" target="_blank">服务器到期宕机？域名过期被抢注？这个工具帮你守住所有服务</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/docker/yantr-intro/</id>
      <title type="text">GitHub热门项目！yantr：自托管应用商店，不占用系统资源，130+应用一键部署</title>
      <published>2026-06-23T00:00:00.000Z</published>
      <updated>2026-06-23T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/docker/yantr-intro/"/>
      <summary type="text">一个容器搞定所有服务！yantr作为应用而非操作系统运行，130+精选应用，一键部署，支持AI、媒体、下载、云存储、安全等多种类型</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！想自建家庭服务器却怕折腾？<a href="#朋友们想自建家庭服务器却怕折腾"><span>#</span></a></h2><p>你是不是经常遇到这些困扰：</p><ul>
<li><strong>Umbrel太笨重</strong>：要占用整台机器，安装后其他应用没法用</li>
<li><strong>Docker Compose太麻烦</strong>：每个应用都要写配置文件，记不住端口</li>
<li><strong>端口冲突头疼</strong>：多个应用争用端口，排查半天</li>
<li><strong>数据不好管理</strong>：应用数据散落在各处，备份恢复麻烦</li>
<li><strong>想装的应用太多</strong>：每次都要找镜像、写配置，太耗时</li>
</ul><p>今天我要给大家分享一个 GitHub 上的宝藏项目——<strong>yantr</strong>！这个自托管应用商店作为单个容器运行，不占用系统资源，支持 130+ 精选应用一键部署，让自建服务变得无比简单！</p></section>
<section><h2>✨ 什么是 yantr？<a href="#-什么是-yantr"><span>#</span></a></h2><p>yantr 是一个<strong>自托管的应用商店</strong>，它与您的操作系统<strong>并行运行</strong>，而不是替代它。它作为单个 Docker 容器运行在您已有的机器上——笔记本电脑、树莓派、旧 PC、家庭服务器都可以。您的主机保持不变，文件保持原位，yantr 只是管理 Docker stacks。</p><p><strong>核心特点</strong>：</p><ul>
<li>🐳 <strong>单容器运行</strong>：只需一个容器，无需数据库，无外部依赖</li>
<li>📦 <strong>130+ 精选应用</strong>：涵盖 AI、媒体、下载、云存储、安全等多个类别</li>
<li>⚡ <strong>一键部署</strong>：点击即可安装，无需手动编写配置</li>
<li>🔒 <strong>零系统足迹</strong>：从不写入主机，卸载后不留痕迹</li>
<li>🎯 <strong>完整环境控制</strong>：每个应用可自定义环境变量，支持重复部署</li>
<li>🚫 <strong>无依赖冲突</strong>：每个应用自带运行时，互不干扰</li>
<li>🌐 <strong>内置网络</strong>：端口冲突检测、Tailscale、Cloudflare Tunnel、Caddy HTTPS</li>
<li>📁 <strong>卷浏览器</strong>：从浏览器直接管理应用数据</li>
<li>🔌 <strong>REST API</strong>：所有操作都有 JSON 端点，支持脚本和 CLI</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/77a4343380de4f839dc598c21f5a8b5b20260623141308300.png" alt="" /></p></section>
<section><h2>🎯 130+ 应用分类<a href="#-130-应用分类"><span>#</span></a></h2><p>yantr 提供了丰富的应用目录，涵盖各种使用场景：</p><section><h3>🤖 AI &amp; Agents<a href="#-ai--agents"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- Open WebUI：开源 AI 聊天界面，支持多种模型</span></div></div><div><div><div>2</div></div><div><span>- Perplexica：AI 搜索聚合器</span></div></div><div><div><div>3</div></div><div><span>- Agent Zero：AI 智能代理</span></div></div><div><div><div>4</div></div><div><span>- Kokoro：AI 知识库助手</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>🎬 Media（媒体服务）<a href="#-media媒体服务"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- Jellyfin：开源媒体服务器</span></div></div><div><div><div>2</div></div><div><span>- Emby：媒体管理和播放</span></div></div><div><div><div>3</div></div><div><span>- Stremio：流媒体聚合器</span></div></div><div><div><div>4</div></div><div><span>- Swingmusic：轻量级音乐服务器</span></div></div><div><div><div>5</div></div><div><span>- Metube：YouTube 下载器</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>📥 Downloads（下载工具）<a href="#-downloads下载工具"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- qBittorrent：BT 下载客户端</span></div></div><div><div><div>2</div></div><div><span>- Radarr：电影自动下载管理</span></div></div><div><div><div>3</div></div><div><span>- Sonarr：电视剧自动下载管理</span></div></div><div><div><div>4</div></div><div><span>- Jackett：Tracker 聚合器</span></div></div><div><div><div>5</div></div><div><span>- Prowlarr：索引器管理器</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>☁️ Cloud &amp; Files（云存储）<a href="#️-cloud--files云存储"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- Nextcloud：私有云存储</span></div></div><div><div><div>2</div></div><div><span>- Seafile：文件同步共享</span></div></div><div><div><div>3</div></div><div><span>- Syncthing：点对点文件同步</span></div></div><div><div><div>4</div></div><div><span>- MinIO：对象存储</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>🔐 Security（安全工具）<a href="#-security安全工具"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- Vaultwarden：密码管理器</span></div></div><div><div><div>2</div></div><div><span>- AdGuard Home：广告拦截和 DNS</span></div></div><div><div><div>3</div></div><div><span>- Pi-hole：网络级广告拦截</span></div></div><div><div><div>4</div></div><div><span>- WireGuard：虚拟专用网络</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>🛠️ Dev Tools（开发工具）<a href="#️-dev-tools开发工具"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- Supabase：开源 Firebase 替代品</span></div></div><div><div><div>2</div></div><div><span>- PostgreSQL：关系型数据库</span></div></div><div><div><div>3</div></div><div><span>- MongoDB：文档数据库</span></div></div><div><div><div>4</div></div><div><span>- n8n：工作流自动化</span></div></div><div><div><div>5</div></div><div><span>- Gitea：自托管代码仓库</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>📡 Networking（网络工具）<a href="#-networking网络工具"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- Tailscale：零配置 VPN</span></div></div><div><div><div>2</div></div><div><span>- Cloudflare Tunnel：安全隧道</span></div></div><div><div><div>3</div></div><div><span>- Glances：系统监控</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>📝 Productivity（生产力工具）<a href="#-productivity生产力工具"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- Memos：极简笔记应用</span></div></div><div><div><div>2</div></div><div><span>- Wiki.js：现代化 Wiki</span></div></div><div><div><div>3</div></div><div><span>- Linkwarden：书签管理</span></div></div><div><div><div>4</div></div><div><span>- FreshRSS：RSS 阅读器</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>💰 Finance（财务工具）<a href="#-finance财务工具"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- Actual Budget：零基预算管理</span></div></div><div><div><div>2</div></div><div><span>- Ghostfolio：投资组合追踪</span></div></div><div><div><div>3</div></div><div><span>- Rotki：隐私优先的投资追踪</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>🚀 快速开始<a href="#-快速开始"><span>#</span></a></h2><section><h3>前置要求<a href="#前置要求"><span>#</span></a></h3><ul>
<li><strong>Docker</strong>：需要安装 Docker</li>
<li><strong>Linux 主机</strong>：推荐使用 Linux（macOS/Windows 需要特殊配置）</li>
</ul></section><section><h3>一键部署<a href="#一键部署"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>--name</span><span> </span><span>yantr</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>--network</span><span> </span><span>host</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>-v</span><span> </span><span>/var/run/docker.sock:/var/run/docker.sock</span><span> </span><span>\</span></div></div><div><div><div>5</div></div><div><span>  </span><span>-v</span><span> </span><span>/var/lib/docker/volumes:/var/lib/docker/volumes</span><span> </span><span>\</span></div></div><div><div><div>6</div></div><div><span>  </span><span>--restart</span><span> </span><span>unless-stopped</span><span> </span><span>\</span></div></div><div><div><div>7</div></div><div><span>  </span><span>ghcr.io/besoeasy/yantr</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>访问应用<a href="#访问应用"><span>#</span></a></h3><p>打开 **<a href="http://localhost:5252**%EF%BC%8C%E9%A6%96%E6%AC%A1%E8%AE%BF%E9%97%AE%E6%97%B6%E5%88%9B%E5%BB%BA%E7%AE%A1%E7%90%86%E5%91%98%E8%B4%A6%E6%88%B7%E5%8D%B3%E5%8F%AF%E4%BD%BF%E7%94%A8%E3%80%82" target="_blank">http://localhost:5252**，首次访问时创建管理员账户即可使用。</a>
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/b56785646a054930b0fa59052955b97b20260623141345831.png" alt="" /></p></section><section><h3>macOS / Windows 用户<a href="#macos--windows-用户"><span>#</span></a></h3><p>由于 host 网络仅支持 Linux，macOS 和 Windows 用户需要配置端口映射：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>--name</span><span> </span><span>yantr</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>-p</span><span> </span><span>5252:5252</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>-v</span><span> </span><span>/var/run/docker.sock:/var/run/docker.sock</span><span> </span><span>\</span></div></div><div><div><div>5</div></div><div><span>  </span><span>-v</span><span> </span><span>/var/lib/docker/volumes:/var/lib/docker/volumes</span><span> </span><span>\</span></div></div><div><div><div>6</div></div><div><span>  </span><span>--restart</span><span> </span><span>unless-stopped</span><span> </span><span>\</span></div></div><div><div><div>7</div></div><div><span>  </span><span>ghcr.io/besoeasy/yantr</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/f96aabfcd73c4eccb5aa70681195ca3920260623141428388.png" alt="" /></p></section></section>
<section><h2>📝 使用场景<a href="#-使用场景"><span>#</span></a></h2><section><h3>场景一：家庭媒体中心<a href="#场景一家庭媒体中心"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>部署应用：</span></div></div><div><div><div>2</div></div><div><span>- Jellyfin：媒体服务器</span></div></div><div><div><div>3</div></div><div><span>- qBittorrent：下载工具</span></div></div><div><div><div>4</div></div><div><span>- Radarr/Sonarr：自动下载电影和电视剧</span></div></div><div><div><div>5</div></div><div><span>- Metube：YouTube 视频下载</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>效果：打造完整的家庭媒体中心，随时随地观看影视内容</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>场景二：个人云存储<a href="#场景二个人云存储"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>部署应用：</span></div></div><div><div><div>2</div></div><div><span>- Nextcloud：私有云存储</span></div></div><div><div><div>3</div></div><div><span>- Syncthing：文件同步</span></div></div><div><div><div>4</div></div><div><span>- Vaultwarden：密码管理</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>效果：数据完全自主可控，告别公有云隐私担忧</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>场景三：开发环境<a href="#场景三开发环境"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>部署应用：</span></div></div><div><div><div>2</div></div><div><span>- Gitea：代码仓库</span></div></div><div><div><div>3</div></div><div><span>- PostgreSQL：数据库</span></div></div><div><div><div>4</div></div><div><span>- MongoDB：文档数据库</span></div></div><div><div><div>5</div></div><div><span>- n8n：工作流自动化</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>效果：搭建完整的开发环境，支持团队协作</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>场景四：AI 工具集<a href="#场景四ai-工具集"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>部署应用：</span></div></div><div><div><div>2</div></div><div><span>- Open WebUI：AI 聊天界面</span></div></div><div><div><div>3</div></div><div><span>- Perplexica：AI 搜索</span></div></div><div><div><div>4</div></div><div><span>- Agent Zero：AI 代理</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>效果：在本地运行 AI 工具，数据不流出本地</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>场景五：网络安全<a href="#场景五网络安全"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>部署应用：</span></div></div><div><div><div>2</div></div><div><span>- AdGuard Home：广告拦截</span></div></div><div><div><div>3</div></div><div><span>- Pi-hole：网络级广告过滤</span></div></div><div><div><div>4</div></div><div><span>- WireGuard：VPN</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>效果：保护家庭网络安全，提升上网体验</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>📜 开源协议<a href="#-开源协议"><span>#</span></a></h2><p>yantr 采用 <strong>ISC</strong> 开源协议，完全免费使用。</p></section>
<section><h2>📝 总结<a href="#-总结"><span>#</span></a></h2><p>yantr 是一款功能强大的自托管应用商店，特别适合想要自建服务但又不想折腾的用户。它作为单个容器运行，不占用系统资源，支持 130+ 精选应用一键部署。与 Umbrel 不同，yantr 不会占用整台机器，您的主机保持不变。与手动 Docker 相比，yantr 提供了可视化管理界面，一键部署、一键更新，让自建服务变得无比简单。无论是搭建家庭媒体中心、个人云存储、开发环境还是 AI 工具集，yantr 都是一个非常好的选择！</p></section>
<section><h2>🌟 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>官方网站</strong>: <a href="https://yantr.org" target="_blank">https://yantr.org</a></p><p><strong>GitHub 地址</strong>: <a href="https://github.com/besoeasy/yantr" target="_blank">https://github.com/besoeasy/yantr</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p></section>
<section><h2>🎉 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你最想在自己的服务器上部署什么应用？在使用自托管服务时遇到过什么问题？欢迎在评论区和我交流分享！</p><p>我会定期分享更多好用的工具，记得关注我哦！</p><hr /><p><strong>推荐阅读</strong>:</p><ul>
<li><a href="https://mp.weixin.qq.com/s/10kSF42HjetziyT9uD3pPg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！freeCodeCamp：免费学编程，10万人转行成功</a></li>
<li><a href="https://mp.weixin.qq.com/s/tESfza_v76eAVFoS4dnjgg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！BentoPDF：浏览器端隐私优先的PDF工具箱，50+工具一键搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/tm9H33eCtmQCSDoGclENkA?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！PakePlus：网页秒变桌面应用</a></li>
<li><a href="https://mp.weixin.qq.com/s/1W0KIPzAXGLXjl7jyEsYEA?token=1837315026&amp;lang=zh_CN" target="_blank">服务器到期宕机？域名过期被抢注？这个工具帮你守住所有服务</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/docker/bentopdf-intro/</id>
      <title type="text">GitHub热门项目！BentoPDF：浏览器端隐私优先的PDF工具箱，50+工具一键搞定</title>
      <published>2026-06-22T00:00:00.000Z</published>
      <updated>2026-06-22T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/docker/bentopdf-intro/"/>
      <summary type="text">所有处理在浏览器端完成，文件不上传服务器，支持50+工具，可自建部署，完全免费开源！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！处理PDF文件总担心隐私泄露？<a href="#朋友们处理pdf文件总担心隐私泄露"><span>#</span></a></h2><p>你是不是经常遇到这些困扰：</p><ul>
<li><strong>在线工具不安全</strong>：上传PDF到第三方网站处理，担心文件内容被窃取</li>
<li><strong>功能不全</strong>：在线PDF工具功能有限，很多高级功能需要付费</li>
<li><strong>文件太大传不了</strong>：大文件上传慢，还经常失败</li>
<li><strong>本地软件麻烦</strong>：安装本地PDF软件太臃肿，占用空间大</li>
<li><strong>团队协作不便</strong>：多人共用电脑，配置麻烦</li>
</ul><p>今天我要给大家分享一个 GitHub 上的宝藏项目——<strong>BentoPDF</strong>！这个项目是一款隐私优先的浏览器端 PDF 工具箱，所有处理都在浏览器端完成，文件不上传服务器，支持 50+ 工具，可自建部署，完全免费开源！</p></section>
<section><h2>✨ 什么是 BentoPDF？<a href="#-什么是-bentopdf"><span>#</span></a></h2><p>BentoPDF 是一款<strong>隐私优先、客户端处理</strong>的 PDF 工具箱，支持在浏览器中直接操作、编辑、合并和处理 PDF 文件。所有处理都在本地完成，文件不会上传到服务器，确保您的文件安全和隐私。</p><p><strong>核心特点</strong>：</p><ul>
<li>🔒 <strong>隐私优先</strong>：所有处理在浏览器端完成，文件永不上传服务器</li>
<li>📦 <strong>50+ 工具</strong>：涵盖 PDF 管理、编辑、转换、安全等所有功能</li>
<li>🚀 <strong>高性能</strong>：基于现代 Web 技术和 WASM，处理速度快</li>
<li>🆓 <strong>完全免费</strong>：开源免费，无限制使用</li>
<li>🏠 <strong>可自建部署</strong>：支持 Docker、Netlify、Vercel、GitHub Pages 等多种部署方式</li>
<li>📱 <strong>跨平台</strong>：支持所有现代浏览器，无需安装任何软件</li>
<li>🎨 <strong>美观界面</strong>：现代化 UI 设计，操作简单直观</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/d366252d4ba6468685c71c645ac24e8520260622085038062.png" alt="" /></p></section>
<section><h2>🎯 50+ 工具分类<a href="#-50-工具分类"><span>#</span></a></h2><section><h3>1. 组织与管理 PDF<a href="#1-组织与管理-pdf"><span>#</span></a></h3>

<table><thead><tr><th>工具</th><th>功能</th></tr></thead><tbody><tr><td><strong>合并PDF</strong></td><td>将多个PDF合并为一个，保留书签</td></tr><tr><td><strong>拆分PDF</strong></td><td>提取特定页面或分割为多个文件</td></tr><tr><td><strong>页面管理</strong></td><td>拖拽重排、复制、删除页面</td></tr><tr><td><strong>提取页面</strong></td><td>保存指定页码范围为新PDF</td></tr><tr><td><strong>删除页面</strong></td><td>删除不需要的页面</td></tr><tr><td><strong>旋转PDF</strong></td><td>旋转单个或所有页面</td></tr><tr><td><strong>自定义旋转</strong></td><td>按任意角度旋转页面</td></tr><tr><td><strong>N-Up PDF</strong></td><td>多页合并到单页</td></tr><tr><td><strong>交替合并</strong></td><td>交替合并多个PDF的页面</td></tr><tr><td><strong>海报拆分</strong></td><td>将PDF拆分为多个小页面用于打印</td></tr><tr><td><strong>PDF小册子</strong></td><td>重排页面用于双面打印成书册</td></tr><tr><td><strong>添加附件</strong></td><td>嵌入文件到PDF中</td></tr><tr><td><strong>提取附件</strong></td><td>从PDF中提取所有附件</td></tr><tr><td><strong>反转页面</strong></td><td>反转所有页面顺序</td></tr></tbody></table><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/693d16eaa5b445f2bdaef43fc96b5c8320260622085328045.png" alt="" /></p></section><section><h3>2. 编辑与修改 PDF<a href="#2-编辑与修改-pdf"><span>#</span></a></h3>

<table><thead><tr><th>工具</th><th>功能</th></tr></thead><tbody><tr><td><strong>PDF编辑器</strong></td><td>标注、高亮、批注、添加形状/图片</td></tr><tr><td><strong>创建表单</strong></td><td>创建可填写的PDF表单（文本框、复选框、下拉框等）</td></tr><tr><td><strong>表单填写</strong></td><td>直接在浏览器中填写表单</td></tr><tr><td><strong>添加页码</strong></td><td>自定义格式添加页码</td></tr><tr><td><strong>Bates编号</strong></td><td>跨多个PDF添加连续编号</td></tr><tr><td><strong>添加水印</strong></td><td>添加文字或图片水印</td></tr><tr><td><strong>页眉页脚</strong></td><td>添加自定义页眉页脚</td></tr><tr><td><strong>裁剪PDF</strong></td><td>裁剪特定页面或整个文档</td></tr><tr><td><strong>自动纠偏</strong></td><td>自动修正倾斜的扫描页面</td></tr><tr><td><strong>字体转轮廓</strong></td><td>将字体转换为矢量轮廓</td></tr><tr><td><strong>颜色反转</strong></td><td>反转PDF页面颜色</td></tr><tr><td><strong>背景修改</strong></td><td>修改PDF背景颜色</td></tr><tr><td><strong>文本颜色</strong></td><td>修改PDF中文本颜色</td></tr><tr><td><strong>扁平化PDF</strong></td><td>将表单字段和注释合并为静态内容</td></tr><tr><td><strong>移除注释</strong></td><td>移除所有批注和高亮</td></tr><tr><td><strong>移除空白页</strong></td><td>自动检测并移除空白页</td></tr><tr><td><strong>编辑书签</strong></td><td>添加、编辑、导入导出书签</td></tr><tr><td><strong>目录生成</strong></td><td>从书签生成目录页</td></tr><tr><td><strong>内容遮蔽</strong></td><td>永久移除敏感内容</td></tr><tr><td><strong>扫描效果</strong></td><td>使PDF看起来像扫描件</td></tr></tbody></table><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/38ccfac6c4154213a7b9f5e29fc7318c20260622085125541.png" alt="" /></p></section><section><h3>3. 转换为 PDF<a href="#3-转换为-pdf"><span>#</span></a></h3>

<table><thead><tr><th>工具</th><th>功能</th></tr></thead><tbody><tr><td><strong>Word转PDF</strong></td><td>DOCX/DOC文件转换为PDF</td></tr><tr><td><strong>图片转PDF</strong></td><td>多张图片合并为PDF</td></tr><tr><td><strong>HTML转PDF</strong></td><td>HTML页面转换为PDF</td></tr><tr><td><strong>URL转PDF</strong></td><td>网页链接转换为PDF</td></tr><tr><td><strong>Markdown转PDF</strong></td><td>Markdown文件转换为PDF</td></tr><tr><td><strong>EPUB转PDF</strong></td><td>EPUB电子书转换为PDF</td></tr><tr><td><strong>MOBI转PDF</strong></td><td>MOBI电子书转换为PDF</td></tr><tr><td><strong>XPS转PDF</strong></td><td>XPS文件转换为PDF</td></tr></tbody></table><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/bf28be72bbc7443db73280b07b11e4d820260622085157786.png" alt="" /></p></section><section><h3>4. 从 PDF 转换<a href="#4-从-pdf-转换"><span>#</span></a></h3>

<table><thead><tr><th>工具</th><th>功能</th></tr></thead><tbody><tr><td><strong>PDF转Word</strong></td><td>PDF转换为DOCX文件</td></tr><tr><td><strong>PDF转图片</strong></td><td>PDF转换为PNG/JPEG图片</td></tr><tr><td><strong>PDF转文本</strong></td><td>提取PDF中的文本内容</td></tr><tr><td><strong>PDF转Markdown</strong></td><td>PDF转换为Markdown格式</td></tr><tr><td><strong>PDF转SVG</strong></td><td>PDF转换为SVG矢量图</td></tr><tr><td><strong>PDF转EPUB</strong></td><td>PDF转换为EPUB电子书</td></tr><tr><td><strong>PDF转JSON</strong></td><td>PDF转换为JSON格式</td></tr></tbody></table><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/48fa9b6571e34076be4a8d4fe4ad256920260622085300914.png" alt="" /></p></section><section><h3>5. 安全与优化<a href="#5-安全与优化"><span>#</span></a></h3>

<table><thead><tr><th>工具</th><th>功能</th></tr></thead><tbody><tr><td><strong>添加密码</strong></td><td>设置PDF打开密码</td></tr><tr><td><strong>移除密码</strong></td><td>解密受保护的PDF</td></tr><tr><td><strong>数字签名</strong></td><td>添加数字签名</td></tr><tr><td><strong>权限设置</strong></td><td>设置打印、复制、编辑权限</td></tr><tr><td><strong>PDF压缩</strong></td><td>压缩PDF文件大小</td></tr><tr><td><strong>PDF/A转换</strong></td><td>转换为PDF/A存档格式</td></tr><tr><td><strong>文件优化</strong></td><td>优化PDF文件结构</td></tr></tbody></table><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/05ec4740ebea41ceb7248610cc87766f20260622085355422.png" alt="" /></p></section></section>
<section><h2>🚀 部署方式<a href="#-部署方式"><span>#</span></a></h2><section><h3>方式一：使用官方在线版本<a href="#方式一使用官方在线版本"><span>#</span></a></h3><p>直接访问 <a href="https://bentopdf.com" target="_blank">BentoPDF 官网</a>，无需安装，打开浏览器即可使用。</p></section><section><h3>方式二：Docker 部署（推荐）<a href="#方式二docker-部署推荐"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 运行容器</span></div></div><div><div><div>2</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>-p</span><span> </span><span>3000:8080</span><span> </span><span>ghcr.io/alam00000/bentopdf-simple:latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>访问 <code>http://localhost:3000</code> 即可使用。</p></section><section><h3>方式三：Docker Compose<a href="#方式三docker-compose"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>bentopdf</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image</span><span>: </span><span>ghcr.io/alam00000/bentopdf-simple:latest</span></div></div><div><div><div>4</div></div><div><span>    </span><span>container_name</span><span>: </span><span>bentopdf</span></div></div><div><div><div>5</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>6</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>"3000:8080"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>启动服务：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>方式四：静态托管<a href="#方式四静态托管"><span>#</span></a></h3><p>支持部署到 Netlify、Vercel、GitHub Pages、Cloudflare Pages 等平台：</p><ol>
<li>Fork 项目到您的 GitHub 账户</li>
<li>连接到 Netlify/Vercel/GitHub Pages</li>
<li>自动构建部署</li>
</ol></section><section><h3>方式五：本地开发<a href="#方式五本地开发"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 安装依赖</span></div></div><div><div><div>2</div></div><div><span>npm</span><span> </span><span>install</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 开发模式</span></div></div><div><div><div>5</div></div><div><span>npm</span><span> </span><span>run</span><span> </span><span>dev</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 生产构建</span></div></div><div><div><div>8</div></div><div><span>npm</span><span> </span><span>run</span><span> </span><span>build</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>📝 使用指南<a href="#-使用指南"><span>#</span></a></h2><section><h3>快速开始<a href="#快速开始"><span>#</span></a></h3><ol>
<li>访问 BentoPDF（官方在线版或自建部署）</li>
<li>从左侧工具列表选择您需要的工具</li>
<li>上传或拖拽 PDF 文件到页面</li>
<li>根据工具提示进行操作</li>
<li>下载处理后的文件</li>
</ol></section><section><h3>实际场景演示<a href="#实际场景演示"><span>#</span></a></h3><section><h4>场景一：合并多个 PDF<a href="#场景一合并多个-pdf"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>操作步骤：</span></div></div><div><div><div>2</div></div><div><span>1. 选择"合并PDF"工具</span></div></div><div><div><div>3</div></div><div><span>2. 上传多个PDF文件</span></div></div><div><div><div>4</div></div><div><span>3. 拖拽调整顺序</span></div></div><div><div><div>5</div></div><div><span>4. 点击"合并"按钮</span></div></div><div><div><div>6</div></div><div><span>5. 下载合并后的PDF</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>场景二：添加水印<a href="#场景二添加水印"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>操作步骤：</span></div></div><div><div><div>2</div></div><div><span>1. 选择"添加水印"工具</span></div></div><div><div><div>3</div></div><div><span>2. 上传PDF文件</span></div></div><div><div><div>4</div></div><div><span>3. 设置水印文字、大小、颜色、位置</span></div></div><div><div><div>5</div></div><div><span>4. 点击"添加水印"按钮</span></div></div><div><div><div>6</div></div><div><span>5. 下载处理后的PDF</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>场景三：PDF 转 Word<a href="#场景三pdf-转-word"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>操作步骤：</span></div></div><div><div><div>2</div></div><div><span>1. 选择"PDF转Word"工具</span></div></div><div><div><div>3</div></div><div><span>2. 上传PDF文件</span></div></div><div><div><div>4</div></div><div><span>3. 点击"转换"按钮</span></div></div><div><div><div>5</div></div><div><span>4. 下载转换后的DOCX文件</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section>
<section><h2>📊 对比其他方案<a href="#-对比其他方案"><span>#</span></a></h2>

<table><thead><tr><th>方案</th><th>隐私性</th><th>功能数量</th><th>部署方式</th><th>成本</th><th>推荐指数</th></tr></thead><tbody><tr><td><strong>BentoPDF</strong></td><td>✅ 本地处理</td><td>50+</td><td>多种</td><td>🆓</td><td>⭐⭐⭐⭐⭐</td></tr><tr><td><strong>在线PDF工具</strong></td><td>❌ 上传服务器</td><td>20+</td><td>无</td><td>免费/付费</td><td>⭐⭐⭐</td></tr><tr><td><strong>Adobe Acrobat</strong></td><td>✅ 本地处理</td><td>50+</td><td>本地安装</td><td>付费</td><td>⭐⭐⭐⭐</td></tr><tr><td><strong>PDFelement</strong></td><td>✅ 本地处理</td><td>30+</td><td>本地安装</td><td>付费</td><td>⭐⭐⭐⭐</td></tr><tr><td><strong>LibreOffice</strong></td><td>✅ 本地处理</td><td>10+</td><td>本地安装</td><td>🆓</td><td>⭐⭐⭐</td></tr></tbody></table></section>
<section><h2>📝 总结<a href="#-总结"><span>#</span></a></h2><p>BentoPDF 是一款功能强大的隐私优先 PDF 工具箱，特别适合处理敏感文档。它支持 50+ 工具，涵盖 PDF 的所有操作需求，所有处理都在浏览器端完成，文件不会上传到服务器。支持多种部署方式，可以在个人电脑、服务器或云端部署使用。无论是个人用户还是企业用户，都能从中受益。如果你经常处理 PDF 文件，这个工具绝对值得一试！</p></section>
<section><h2>🌟 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub 地址</strong>: <a href="https://github.com/alam00000/bentopdf" target="_blank">https://github.com/alam00000/bentopdf</a></p><p><strong>官方网站</strong>: <a href="https://bentopdf.com" target="_blank">https://bentopdf.com</a></p><p><strong>使用文档</strong>: <a href="https://bentopdf.com/docs/" target="_blank">https://bentopdf.com/docs/</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p></section>
<section><h2>🎉 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你最常用的 PDF 操作是什么？最希望支持什么功能？欢迎在评论区和我交流分享！</p><p>我会定期分享更多好用的工具，记得关注我哦！</p><hr /><p><strong>推荐阅读</strong>:</p><ul>
<li><a href="https://mp.weixin.qq.com/s/tm9H33eCtmQCSDoGclENkA?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！PakePlus：网页秒变桌面应用</a></li>
<li><a href="https://mp.weixin.qq.com/s/1W0KIPzAXGLXjl7jyEsYEA?token=1837315026&amp;lang=zh_CN" target="_blank">服务器到期宕机？域名过期被抢注？这个工具帮你守住所有服务</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/freecodecamp-intro/</id>
      <title type="text">GitHub顶级项目！freeCodeCamp：免费学编程，已有10万人靠它转行成功</title>
      <published>2026-06-22T00:00:00.000Z</published>
      <updated>2026-06-22T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/freecodecamp-intro/"/>
      <summary type="text">全球最大的免费编程学习社区，支持前端、后端、Python、数据库等全栈开发课程，免费认证，已有超过10万人成功转行！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！想学编程却不知道从哪开始？<a href="#朋友们想学编程却不知道从哪开始"><span>#</span></a></h2><p>你是不是经常遇到这些困扰：</p><ul>
<li><strong>想学编程但没钱</strong>：市面上的编程课程动辄几千上万，太贵了</li>
<li><strong>不知道学什么</strong>：前端、后端、Python、AI，方向太多，不知道怎么选</li>
<li><strong>学了用不上</strong>：理论知识学了一堆，实际项目做不出来</li>
<li><strong>没有学习氛围</strong>：一个人学习太孤单，遇到问题没人问</li>
<li><strong>简历上没东西</strong>：想学完能证明自己，却没有拿得出手的认证</li>
</ul><p>今天我要给大家分享一个改变了无数人命运的 GitHub 项目——<strong>freeCodeCamp</strong>！这是全球最大的免费编程学习社区，已有超过 <strong>10万人</strong> 靠它成功转行，拿到了第一份开发工作！</p></section>
<section><h2>✨ 什么是 freeCodeCamp？<a href="#-什么是-freecodecamp"><span>#</span></a></h2><p>freeCodeCamp（简称 FCC）是一个<strong>非营利性的免费编程学习平台</strong>，由 donor-supported 501(c)(3) 慈善组织运营。它提供完整的全栈开发和机器学习课程，所有内容完全免费、自定进度学习。</p><p><strong>核心特点</strong>：</p><ul>
<li>🆓 <strong>完全免费</strong>：所有课程、认证、学习资源全部免费</li>
<li>🏆 <strong>权威认证</strong>：完成课程可获得免费的开发者认证，可添加到 LinkedIn 和简历</li>
<li>📚 <strong>丰富课程</strong>：涵盖前端、后端、Python、数据库、AI 等多个方向</li>
<li>💻 <strong>实战项目</strong>：每个认证需要完成 5 个实战项目，学以致用</li>
<li>👥 <strong>活跃社区</strong>：Discord、论坛、YouTube 等多种社区支持</li>
<li>🌍 <strong>全球影响力</strong>：帮助超过 10 万人成功转行，GitHub 星标超 37 万</li>
<li>🔄 <strong>自定进度</strong>：按照自己的节奏学习，无需赶进度</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/2f314fff65954050b1834851f91835bc20260622163036749.png" alt="" /></p></section>
<section><h2>🎯 课程体系<a href="#-课程体系"><span>#</span></a></h2><section><h3>全栈开发认证（Full-Stack Developer Curriculum）<a href="#全栈开发认证full-stack-developer-curriculum"><span>#</span></a></h3><p>freeCodeCamp 提供 6 个核心认证，组成完整的全栈开发课程体系：</p><section><h4>1. Responsive Web Design（响应式网页设计）<a href="#1-responsive-web-design响应式网页设计"><span>#</span></a></h4><ul>
<li><strong>学习内容</strong>：HTML、CSS、Flexbox、Grid 布局</li>
<li><strong>项目实践</strong>：构建响应式网页、个人作品集、产品登陆页等</li>
<li><strong>适合人群</strong>：零基础入门</li>
</ul></section><section><h4>2. JavaScript（JavaScript 编程）<a href="#2-javascriptjavascript-编程"><span>#</span></a></h4><ul>
<li><strong>学习内容</strong>：基础语法、DOM 操作、异步编程、算法</li>
<li><strong>项目实践</strong>：计算器、待办清单、随机引语生成器等</li>
<li><strong>适合人群</strong>：有基础 HTML/CSS 知识</li>
</ul></section><section><h4>3. Front-End Development Libraries（前端开发库）<a href="#3-front-end-development-libraries前端开发库"><span>#</span></a></h4><ul>
<li><strong>学习内容</strong>：React、Redux、Bootstrap、D3.js、jQuery</li>
<li><strong>项目实践</strong>：React 电商应用、图表可视化、Markdown 编辑器等</li>
<li><strong>适合人群</strong>：掌握 JavaScript 基础</li>
</ul></section><section><h4>4. Python（Python 编程）<a href="#4-pythonpython-编程"><span>#</span></a></h4><ul>
<li><strong>学习内容</strong>：Python 基础、面向对象、数据分析、机器学习入门</li>
<li><strong>项目实践</strong>：数据可视化、机器学习模型、自动化脚本等</li>
<li><strong>适合人群</strong>：想学习后端或数据科学</li>
</ul></section><section><h4>5. Relational Databases（关系型数据库）<a href="#5-relational-databases关系型数据库"><span>#</span></a></h4><ul>
<li><strong>学习内容</strong>：SQL、PostgreSQL、数据库设计、ORM</li>
<li><strong>项目实践</strong>：构建数据库、数据查询、项目管理系统等</li>
<li><strong>适合人群</strong>：全栈开发必备</li>
</ul></section><section><h4>6. Back-End Development and APIs（后端开发与 API）<a href="#6-back-end-development-and-apis后端开发与-api"><span>#</span></a></h4><ul>
<li><strong>学习内容</strong>：Node.js、Express、MongoDB、RESTful API</li>
<li><strong>项目实践</strong>：博客系统、认证系统、API 服务等</li>
<li><strong>适合人群</strong>：想成为全栈开发者</li>
</ul></section></section><section><h3>语言认证<a href="#语言认证"><span>#</span></a></h3><p>freeCodeCamp 还提供免费的语言认证，帮助开发者提升职场竞争力：</p><ul>
<li><strong>A2 English for Developers（Beta）</strong>：初级英语认证</li>
<li><strong>B1 English for Developers（Beta）</strong>：中级英语认证</li>
<li><strong>A1 Professional Spanish（Beta）</strong>：初级西班牙语认证</li>
<li><strong>A1 Professional Chinese（Beta）</strong>：初级中文认证</li>
</ul></section><section><h3>其他学习资源<a href="#其他学习资源"><span>#</span></a></h3><p>除了核心课程，freeCodeCamp 还提供丰富的学习资源：</p><ul>
<li><strong>The Odin Project（Remix）</strong>：深入的 Web 开发课程</li>
<li><strong>Coding Interview Prep</strong>：面试准备题库</li>
<li><strong>Project Euler</strong>：数学编程挑战</li>
<li><strong>Rosetta Code</strong>：多语言代码对比</li>
<li><strong>Foundational C# with Microsoft</strong>：微软合作的 C# 基础认证</li>
</ul></section></section>
<section><h2>🚀 学习路径<a href="#-学习路径"><span>#</span></a></h2><section><h3>零基础入门路径<a href="#零基础入门路径"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>1. 响应式网页设计（HTML/CSS）→ 获得认证</span></div></div><div><div><div>2</div></div><div><span>2. JavaScript 编程 → 获得认证</span></div></div><div><div><div>3</div></div><div><span>3. 前端开发库（React等）→ 获得认证</span></div></div><div><div><div>4</div></div><div><span>4. Python 编程 → 获得认证</span></div></div><div><div><div>5</div></div><div><span>5. 关系型数据库（SQL）→ 获得认证</span></div></div><div><div><div>6</div></div><div><span>6. 后端开发与 API → 获得认证</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>完成以上 6 个认证，即可成为合格的全栈开发者！</p></section><section><h3>进阶学习路径<a href="#进阶学习路径"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>1. 深入学习前端框架（React/Vue/Angular）</span></div></div><div><div><div>2</div></div><div><span>2. 学习后端框架（Django/Flask/Express）</span></div></div><div><div><div>3</div></div><div><span>3. 掌握数据库技术（MySQL/PostgreSQL/MongoDB）</span></div></div><div><div><div>4</div></div><div><span>4. 学习 DevOps（Docker/Kubernetes）</span></div></div><div><div><div>5</div></div><div><span>5. 了解 AI/机器学习基础</span></div></div><div><div><div>6</div></div><div><span>6. 参与开源项目贡献</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>📝 学习方式<a href="#-学习方式"><span>#</span></a></h2><section><h3>1. 交互式学习<a href="#1-交互式学习"><span>#</span></a></h3><p>freeCodeCamp 采用交互式学习方式，边学边练：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- 阅读课程内容</span></div></div><div><div><div>2</div></div><div><span>- 完成编程挑战</span></div></div><div><div><div>3</div></div><div><span>- 实时反馈代码</span></div></div><div><div><div>4</div></div><div><span>- 渐进式难度提升</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>2. 项目实战<a href="#2-项目实战"><span>#</span></a></h3><p>每个认证需要完成 <strong>5 个实战项目</strong>，真正学以致用：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>示例项目：</span></div></div><div><div><div>2</div></div><div><span>- 响应式网页设计：构建个人作品集网站</span></div></div><div><div><div>3</div></div><div><span>- JavaScript：创建一个计算器应用</span></div></div><div><div><div>4</div></div><div><span>- React：开发一个电商购物车</span></div></div><div><div><div>5</div></div><div><span>- Python：数据分析可视化项目</span></div></div><div><div><div>6</div></div><div><span>- 后端开发：构建一个博客系统</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>3. 社区支持<a href="#3-社区支持"><span>#</span></a></h3><p>freeCodeCamp 拥有活跃的社区，遇到问题可以随时求助：</p>

<table><thead><tr><th>社区平台</th><th>功能</th></tr></thead><tbody><tr><td><strong>Discord</strong></td><td>实时聊天，快速获得帮助</td></tr><tr><td><strong>论坛</strong></td><td>编程问题、项目反馈，通常几小时内回复</td></tr><tr><td><strong>YouTube</strong></td><td>免费视频课程，覆盖多种技术</td></tr><tr><td><strong>News</strong></td><td>技术文章、教程，涵盖编程、数学、计算机科学</td></tr></tbody></table></section></section>
<section><h2>📊 学习效果<a href="#-学习效果"><span>#</span></a></h2><section><h3>成功案例<a href="#成功案例"><span>#</span></a></h3><p>freeCodeCamp 帮助超过 <strong>10万人</strong> 成功转行，以下是一些真实案例：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- 从超市收银员到前端开发工程师</span></div></div><div><div><div>2</div></div><div><span>- 从教师到全栈开发工程师</span></div></div><div><div><div>3</div></div><div><span>- 从护士到数据科学家</span></div></div><div><div><div>4</div></div><div><span>- 从销售到后端开发工程师</span></div></div><div><div><div>5</div></div><div><span>- 从会计到移动端开发工程师</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>认证价值<a href="#认证价值"><span>#</span></a></h3><p>freeCodeCamp 认证可以添加到 LinkedIn 和简历中，当雇主点击链接时，可以看到您的验证证书。这是展示您技能的有力证明。</p><blockquote><p>⚠️ 注意：freeCodeCamp 严格执行学术诚信政策，如果发现抄袭，将撤销认证并封禁账号。</p></blockquote></section></section>
<section><h2>📜 开源协议<a href="#-开源协议"><span>#</span></a></h2><p>freeCodeCamp 采用 <strong>BSD-3-Clause</strong> 开源协议：</p><ul>
<li><strong>软件代码</strong>：BSD-3-Clause 许可证</li>
<li><strong>课程内容</strong>：freeCodeCamp.org 版权所有</li>
</ul><p>freeCodeCamp 是一个捐赠支持的非营利组织，您可以通过捐赠支持项目发展。</p></section>
<section><h2>📝 总结<a href="#-总结"><span>#</span></a></h2><p>freeCodeCamp 是全球最大的免费编程学习社区，它提供完整的全栈开发课程体系，支持前端、后端、Python、数据库等多个方向。所有课程完全免费，完成认证可获得权威的开发者证书。已有超过 10 万人靠它成功转行，拿到了第一份开发工作。如果你想学编程但不知道从哪开始，或者想系统地提升编程技能，freeCodeCamp 绝对是最佳选择！</p></section>
<section><h2>🌟 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>官方网站</strong>: <a href="https://www.freecodecamp.org" target="_blank">https://www.freecodecamp.org</a></p><p><strong>GitHub 地址</strong>: <a href="https://github.com/freeCodeCamp/freeCodeCamp" target="_blank">https://github.com/freeCodeCamp/freeCodeCamp</a></p><p><strong>学习路径</strong>: <a href="https://www.freecodecamp.org/learn/full-stack-developer-v9/" target="_blank">https://www.freecodecamp.org/learn/full-stack-developer-v9/</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p></section>
<section><h2>🎉 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你是怎么开始学习编程的？在学习过程中遇到过什么困难？欢迎在评论区和我交流分享！</p><p>我会定期分享更多好用的工具和学习资源，记得关注我哦！</p><hr /><p><strong>推荐阅读</strong>:</p><ul>
<li><a href="https://mp.weixin.qq.com/s/tESfza_v76eAVFoS4dnjgg?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！BentoPDF：浏览器端隐私优先的PDF工具箱，50+工具一键搞定</a></li>
<li><a href="https://mp.weixin.qq.com/s/tm9H33eCtmQCSDoGclENkA?token=1837315026&amp;lang=zh_CN" target="_blank">GitHub热门项目！PakePlus：网页秒变桌面应用</a></li>
<li><a href="https://mp.weixin.qq.com/s/1W0KIPzAXGLXjl7jyEsYEA?token=1837315026&amp;lang=zh_CN" target="_blank">服务器到期宕机？域名过期被抢注？这个工具帮你守住所有服务</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/pakeplus-intro/</id>
      <title type="text">网页秒变桌面应用！PakePlus：比Electron小20倍，5M体积全搞定</title>
      <published>2026-06-20T00:00:00.000Z</published>
      <updated>2026-06-20T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/pakeplus-intro/"/>
      <summary type="text">基于Rust Tauri构建，比Electron小20倍、快10倍，支持网页/Vue/React打包成桌面和移动应用，无需本地依赖！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！想把网页变成桌面应用吗？<a href="#朋友们想把网页变成桌面应用吗"><span>#</span></a></h2><p>你是不是经常遇到这些需求：</p><ul>
<li><strong>想把网站打包成应用</strong>：有个好用的网站，想做成桌面应用，方便日常使用</li>
<li><strong>Vue/React项目想打包</strong>：不想买服务器，直接把前端项目打包成桌面应用</li>
<li><strong>游戏想跨平台运行</strong>：Cocos/Unity游戏想做成跨平台客户端</li>
<li><strong>隐藏网站地址</strong>：不想让别人直接访问你的网站，只通过客户端访问</li>
<li><strong>内部平台限制访问</strong>：公司内部平台，只想通过专用客户端访问</li>
<li><strong>Electron太重了</strong>：Electron打包的应用动不动几百MB，太占空间</li>
</ul><p>今天我要给大家分享一个 GitHub 上的神器——<strong>PakePlus（PacBao）</strong>！这个工具可以把任何网页、Vue、React 项目打包成桌面和移动应用，体积小于 5MB，比 Electron 小 20 倍、快 10 倍！</p></section>
<section><h2>✨ 什么是 PakePlus？<a href="#-什么是-pakeplus"><span>#</span></a></h2><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/6dfae7c2f6254c41ab410a09a3ac69f420260618150110202.png" alt="" />
PakePlus（PacBao）是一款基于 <strong>Rust Tauri</strong> 构建的跨平台应用打包工具。它可以将任何网页、Vue、React 等项目快速打包成桌面和移动应用，无需本地安装复杂依赖，体积小、速度快。</p><p><strong>核心特点</strong>：</p><ul>
<li>💎 <strong>超小体积</strong>：比 Electron 小 20 倍，打包的应用小于 5MB</li>
<li>🚀 <strong>极速启动</strong>：比 JavaScript 框架快 10 倍，基于 Rust Tauri 构建</li>
<li>📦 <strong>丰富功能</strong>：支持快捷键、沉浸式窗口、极简自定义</li>
<li>📲 <strong>多平台支持</strong>：Mac、Windows、Linux、Android、iOS 全覆盖</li>
<li>🌹 <strong>零依赖</strong>：无需本地安装复杂依赖，云端自动打包</li>
<li>🤗 <strong>简单易用</strong>：只需一个 GitHub Token，即可获得桌面应用</li>
<li>🍔 <strong>本地打包</strong>：支持本地打包，无需 Token，30秒搞定</li>
<li>🍀 <strong>静态文件打包</strong>：支持 Vue/React 的 dist 文件夹直接打包</li>
<li>💡 <strong>自定义注入</strong>：支持自定义 JavaScript 注入，实现自动化和自定义功能</li>
<li>🎨 <strong>美观UI</strong>：界面美观，对新手友好，支持中文命名</li>
</ul></section>
<section><h2>🎯 核心功能<a href="#-核心功能"><span>#</span></a></h2><section><h3>1. 网页打包成应用<a href="#1-网页打包成应用"><span>#</span></a></h3><p>只需输入网站 URL，即可将任何网页打包成桌面应用：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>示例：</span></div></div><div><div><div>2</div></div><div><span>- https://chatgpt.com → ChatGPT 桌面应用</span></div></div><div><div><div>3</div></div><div><span>- https://notion.so → Notion 桌面应用</span></div></div><div><div><div>4</div></div><div><span>- https://docs.google.com → Google Docs 桌面应用</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/37f0fd83ccca4214957a8372f69225a420260618150143828.png" alt="" /></p></section><section><h3>2. Vue/React 项目打包<a href="#2-vuereact-项目打包"><span>#</span></a></h3><p>将 Vue/React 项目编译后的 dist 文件夹直接打包：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>示例：</span></div></div><div><div><div>2</div></div><div><span>- Vue 项目 dist 文件夹 → 桌面应用</span></div></div><div><div><div>3</div></div><div><span>- React 项目 dist 文件夹 → 桌面应用</span></div></div><div><div><div>4</div></div><div><span>- Vite 构建项目 → 桌面应用</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/adc179de25ef49f28c11437e8ad819fa20260618150210530.png" alt="" /></p></section><section><h3>3. 自定义功能<a href="#3-自定义功能"><span>#</span></a></h3><ul>
<li><strong>JavaScript 注入</strong>：注入自定义 JS，实现自动化和自定义功能</li>
<li><strong>隐藏广告</strong>：注入 JS 隐藏网页广告</li>
<li><strong>系统级 API</strong>：支持调用系统级 API（下载文件、执行命令、打开新窗口等）</li>
<li><strong>调试模式</strong>：支持调试模式，快速定位和修复问题
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/14d80270272b4469adc175714ff298d620260618150329898.png" alt="" /></li>
</ul></section></section>
<section><h2>🚀 使用方式<a href="#-使用方式"><span>#</span></a></h2><section><h3>方式一：客户端应用（推荐）<a href="#方式一客户端应用推荐"><span>#</span></a></h3><ol>
<li><strong>下载应用</strong>：访问 <a href="https://github.com/Sjj1024/PakePlus/releases" target="_blank">GitHub Release</a> 下载客户端</li>
<li><strong>安装运行</strong>：双击安装并运行应用</li>
<li><strong>配置 Token</strong>：配置 GitHub Token 或使用本地打包</li>
<li><strong>创建项目</strong>：创建新项目，设置配置（名称、URL、图标等）</li>
<li><strong>预览发布</strong>：预览应用，点击发布按钮打包</li>
<li><strong>下载应用</strong>：从 Release 页面下载打包好的应用</li>
</ol></section><section><h3>方式二：Web 版本<a href="#方式二web-版本"><span>#</span></a></h3><p>直接访问 <a href="https://pakeplus.pages.dev" target="_blank">PacBao Web</a> 使用网页版本，无需下载客户端。</p></section></section>
<section><h2>📊 对比其他方案<a href="#-对比其他方案"><span>#</span></a></h2>

<table><thead><tr><th>方案</th><th>体积</th><th>速度</th><th>跨平台</th><th>复杂度</th><th>推荐指数</th></tr></thead><tbody><tr><td><strong>PakePlus</strong></td><td>⚡ 5MB</td><td>⚡ 10x</td><td>✅ 全平台</td><td>⭐ 简单</td><td>⭐⭐⭐⭐⭐</td></tr><tr><td><strong>Electron</strong></td><td>~100MB</td><td>1x</td><td>✅ 全平台</td><td>⭐⭐⭐ 中等</td><td>⭐⭐⭐</td></tr><tr><td><strong>Tauri</strong></td><td>~10MB</td><td>10x</td><td>✅ 全平台</td><td>⭐⭐⭐⭐ 复杂</td><td>⭐⭐⭐⭐</td></tr><tr><td><strong>PWA</strong></td><td>~5MB</td><td>5x</td><td>✅ 全平台</td><td>⭐⭐ 简单</td><td>⭐⭐⭐⭐</td></tr><tr><td><strong>原生开发</strong></td><td>~20MB</td><td>20x</td><td>❌ 单平台</td><td>⭐⭐⭐⭐⭐ 很难</td><td>⭐⭐</td></tr></tbody></table></section>
<section><h2>⚠️ 注意事项<a href="#️-注意事项"><span>#</span></a></h2><section><h3>Mac 用户提示<a href="#mac-用户提示"><span>#</span></a></h3><p>Mac 用户安装时可能会看到”应用已损坏”的警告，解决方法：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>xattr</span><span> </span><span>-r</span><span> </span><span>-d</span><span> </span><span>com.apple.quarantine</span><span> </span><span>/Applications/PacBao.app</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>GitHub Token 权限<a href="#github-token-权限"><span>#</span></a></h3><p>使用 GitHub Token 打包时，需要以下权限：</p><p><strong>Beta 版本</strong>：</p><ul>
<li>All repositories：Fork 原始模板仓库</li>
<li>Actions：管理 GitHub actions</li>
<li>Administration：Fork 和管理仓库文件</li>
<li>Contents：添加、删除、修改和查找仓库内容</li>
<li>Issues：向 PacBao 提交问题</li>
</ul><p><strong>Classic 版本</strong>：</p><ul>
<li>repo：Fork 和管理模板代码</li>
<li>workflow：编译和发布软件</li>
</ul></section><section><h3>合法使用<a href="#合法使用"><span>#</span></a></h3><p>请合法合规使用此软件，仅限个人使用，不得传播或用于商业目的。</p></section></section>
<section><h2>📝 总结<a href="#-总结"><span>#</span></a></h2><p>PakePlus 是一款功能强大的跨平台应用打包工具，特别适合将网页、Vue/React 项目快速打包成桌面和移动应用。它基于 Rust Tauri 构建，体积小、速度快，比 Electron 小 20 倍、快 10 倍。支持云端自动打包和本地打包，无需复杂依赖，30秒内完成打包。无论是个人用户还是企业用户，都能从中受益。如果你想把网页变成应用，这个工具绝对值得一试！</p></section>
<section><h2>🌟 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub 地址</strong>: <a href="https://github.com/Sjj1024/PakePlus" target="_blank">https://github.com/Sjj1024/PakePlus</a></p><p><strong>官方网站</strong>: <a href="https://pakeplus.com" target="_blank">https://pakeplus.com</a></p><p><strong>Web 版本</strong>: <a href="https://pakeplus.pages.dev" target="_blank">https://pakeplus.pages.dev</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p></section>
<section><h2>🎉 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你最想把什么网站打包成应用？最期待什么功能？欢迎在评论区和我交流分享！</p><p>我会定期分享更多好用的工具，记得关注我哦！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/docker/renewhelper-intro/</id>
      <title type="text">服务器到期宕机？域名过期被抢注？这个工具帮你守住所有服务</title>
      <published>2026-06-19T00:00:00.000Z</published>
      <updated>2026-06-19T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/docker/renewhelper-intro/"/>
      <summary type="text">基于Cloudflare Workers的服务生命周期管理工具，支持公历/农历周期计算、多渠道通知推送、资金流向看板，零成本托管！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！服务到期总忘记？<a href="#朋友们服务到期总忘记"><span>#</span></a></h2><p>你是不是每天都要面对这些困扰：</p><ul>
<li><strong>域名续费忘了</strong>：辛辛苦苦做的网站，域名过期被抢注，欲哭无泪</li>
<li><strong>服务器到期忘了</strong>：半夜服务宕机，紧急充值，手忙脚乱</li>
<li><strong>订阅服务忘了</strong>：自动续费扣了钱才发现，想退都来不及</li>
<li><strong>通知渠道太少</strong>：手机短信容易漏，邮件看不到，错过重要提醒</li>
<li><strong>没有统一管理</strong>：各种服务分散在不同平台，到期时间记不住</li>
</ul><p>今天我要给大家分享一个 GitHub 上的宝藏项目——<strong>RenewHelper（时序·守望）</strong>！这个项目让管理周期性订阅变得无比简单，支持公历/农历周期计算、多渠道通知推送、资金流向看板，零成本托管！</p></section>
<section><h2>✨ 什么是 RenewHelper？<a href="#-什么是-renewhelper"><span>#</span></a></h2><p>RenewHelper（时序·守望）是一款基于 <strong>Cloudflare Workers</strong> 的全栈服务生命周期提醒、管理工具。它专为管理周期性订阅、域名续费、服务器到期等场景设计，无需服务器，零成本托管。</p><p><strong>核心特点</strong>：</p><ul>
<li>⚡ <strong>Serverless 架构</strong>：完全运行在 Cloudflare Workers 上，免费额度足够个人使用</li>
<li>📅 <strong>公历/农历双支持</strong>：内置高精度农历算法（1900-2100），支持公历循环和农历循环</li>
<li>🔔 <strong>多渠道通知</strong>：支持 Telegram、Bark、PushPlus、钉钉、飞书、企微等 12+ 种通知渠道</li>
<li>💰 <strong>资金流向看板</strong>：支持多币种混合统计，按月/年查看消费趋势</li>
<li>📆 <strong>日历同步</strong>：支持 ICS 订阅，完美接入 iOS 日历、Google Calendar</li>
<li>🛡️ <strong>安全可靠</strong>：JWT 身份验证，数据仅存储在您私有的 Cloudflare KV 中</li>
<li>🎨 <strong>现代化 UI</strong>：Vue 3 + Element Plus，支持深色/浅色模式，响应式设计</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/169af888fed6415ebb8111b20e77ba1a20260618144352167.png" alt="" /></p></section>
<section><h2>🎯 核心功能<a href="#-核心功能"><span>#</span></a></h2><section><h3>1. 智能周期管理<a href="#1-智能周期管理"><span>#</span></a></h3><p>支持三种模式：</p>

<table><thead><tr><th>模式</th><th>说明</th><th>适用场景</th></tr></thead><tbody><tr><td><strong>循环订阅</strong></td><td>到期自动更新下次提醒时间</td><td>月付/年付订阅</td></tr><tr><td><strong>到期重置</strong></td><td>到期后标记为过期，需手动处理</td><td>一次性服务</td></tr><tr><td><strong>固定重复</strong></td><td>按固定间隔重复提醒</td><td>生日、纪念日</td></tr></tbody></table><p>支持公历和农历两种周期计算：</p><ul>
<li><strong>公历循环</strong>：月付、季付、年付等固定间隔</li>
<li><strong>农历循环</strong>：生日、传统节日等农历日期</li>
</ul></section><section><h3>2. 多渠道通知推送<a href="#2-多渠道通知推送"><span>#</span></a></h3><p>支持 <strong>12+ 种通知渠道</strong>，可无限添加，支持为每个项目配置不同的推送渠道：</p>

<table><thead><tr><th>渠道</th><th>适用平台</th><th>特点</th></tr></thead><tbody><tr><td><strong>Telegram</strong></td><td>全平台</td><td>即时推送，支持群组</td></tr><tr><td><strong>Bark</strong></td><td>iOS</td><td>轻量推送，无需服务器</td></tr><tr><td><strong>PushPlus</strong></td><td>微信</td><td>微信公众号推送</td></tr><tr><td><strong>Server酱</strong></td><td>微信</td><td>微信服务号推送</td></tr><tr><td><strong>钉钉</strong></td><td>企业</td><td>企业内部通知</td></tr><tr><td><strong>飞书</strong></td><td>企业</td><td>企业内部通知</td></tr><tr><td><strong>企微</strong></td><td>企业</td><td>企业微信通知</td></tr><tr><td><strong>Resend</strong></td><td>邮件</td><td>邮件通知</td></tr><tr><td><strong>Gotify</strong></td><td>自建</td><td>自建通知服务</td></tr><tr><td><strong>Ntfy</strong></td><td>全平台</td><td>开源通知服务</td></tr><tr><td><strong>Webhook</strong></td><td>自定义</td><td>自定义集成</td></tr></tbody></table></section><section><h3>3. 资金流向看板<a href="#3-资金流向看板"><span>#</span></a></h3><p>提供精美的账单统计视图：</p><ul>
<li>按月、按年查看消费趋势</li>
<li>支持多币种混合统计（自动汇率转换）</li>
<li>区分账单金额（预算）与实际支出（实付）</li>
<li>未来 n 天待付账单预览</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/dc8301dd04b54e0886d197363e1a8eab20260618144432438.png" alt="" /></p></section><section><h3>4. 日历可视化 &amp; ICS 订阅<a href="#4-日历可视化--ics-订阅"><span>#</span></a></h3><ul>
<li><strong>内置日历面板</strong>：直观查看当月各种续费事件及未来的预测待办</li>
<li><strong>ICS 订阅</strong>：提供标准的 <code>.ics</code> 订阅链接，可完美接入 iOS 日历、Google Calendar、Outlook</li>
<li><strong>时区支持</strong>：支持基于时区的精确提醒</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/991c0fa7bfe54f15a83bdabbe514ca8c20260618144446392.png" alt="" /></p></section><section><h3>5. 自动化管理<a href="#5-自动化管理"><span>#</span></a></h3><ul>
<li><strong>自动续期</strong>：到期自动更新下次提醒时间</li>
<li><strong>自动禁用</strong>：过期太久未处理的服务自动标记为禁用</li>
<li><strong>Cron 触发</strong>：支持通过 Cloudflare Cron Triggers 每日定时检查</li>
</ul></section><section><h3>6. 安全可靠<a href="#6-安全可靠"><span>#</span></a></h3><ul>
<li><strong>JWT 身份验证</strong>：支持高强度密钥自动生成</li>
<li><strong>混合限流策略</strong>：内存 + KV，防止暴力破解</li>
<li><strong>数据私有化</strong>：数据仅存储在您私有的 Cloudflare KV 中</li>
<li><strong>二次确认</strong>：敏感操作（删除、重置）需要二次确认</li>
</ul></section></section>
<section><h2>🚀 部署方式<a href="#-部署方式"><span>#</span></a></h2><section><h3>方式一：一键部署到 Cloudflare Workers（推荐）<a href="#方式一一键部署到-cloudflare-workers推荐"><span>#</span></a></h3><p>点击按钮即可完成部署：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/6bc0c4626b94445482511bfaca686b5720260618144529112.png" alt="" /></p><p>部署后需要设置：</p><ol>
<li>添加环境变量 <code>AUTH_PASSWORD</code>（登录密码）</li>
<li>绑定 KV 命名空间 <code>RENEW_KV</code></li>
<li>设置 Cron Triggers：<code>0,30 * * * *</code></li>
</ol></section><section><h3>方式二：Docker 部署（私有化）<a href="#方式二docker-部署私有化"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>renew-helper</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image</span><span>: </span><span>ieax/renewhelper:latest</span></div></div><div><div><div>4</div></div><div><span>    </span><span>container_name</span><span>: </span><span>renew-helper</span></div></div><div><div><div>5</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>6</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>"9787:9787"</span></div></div><div><div><div>8</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>- </span><span>./data:/data</span></div></div><div><div><div>10</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>- </span><span>AUTH_PASSWORD=你的访问密码</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>- </span><span>CRON_SCHEDULE=0,30 * * * *</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span>- </span><span>TZ=Asia/Shanghai</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>启动服务：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>⚠️ 注意：需要配置 HTTPS 反向代理（Nginx/Caddy）</p></blockquote></section></section>
<section><h2>📊 对比其他方案<a href="#-对比其他方案"><span>#</span></a></h2>

<table><thead><tr><th>方案</th><th>成本</th><th>部署难度</th><th>通知渠道</th><th>农历支持</th><th>资金看板</th></tr></thead><tbody><tr><td><strong>RenewHelper</strong></td><td>免费</td><td>⭐⭐</td><td>12+</td><td>✅</td><td>✅</td></tr><tr><td><strong>Notion 模板</strong></td><td>免费</td><td>⭐</td><td>少</td><td>❌</td><td>手动</td></tr><tr><td><strong>手机日历</strong></td><td>免费</td><td>⭐</td><td>少</td><td>部分</td><td>❌</td></tr><tr><td><strong>付费订阅管理</strong></td><td>付费</td><td>⭐</td><td>多</td><td>❌</td><td>✅</td></tr></tbody></table></section>
<section><h2>📝 总结<a href="#-总结"><span>#</span></a></h2><p>RenewHelper 是一款功能强大的服务生命周期管理工具，特别适合管理域名续费、服务器到期、订阅服务等周期性任务。它基于 Cloudflare Workers 实现零成本托管，支持公历/农历双周期计算、12+ 种通知渠道、资金流向看板和 ICS 日历同步。无论是个人用户还是企业用户，都能从中受益。如果你经常忘记服务到期，这个工具绝对值得一试！</p></section>
<section><h2>🌟 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub 地址</strong>: <a href="https://github.com/ieax/renewhelper" target="_blank">https://github.com/ieax/renewhelper</a></p><p><strong>Docker 镜像</strong>: <code>ieax/renewhelper:latest</code></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p></section>
<section><h2>🎉 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你最常忘记哪些服务的到期时间？最希望支持什么通知渠道？欢迎在评论区和我交流分享！</p><p>我会定期分享更多好用的工具，记得关注我哦！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/ai/docmd-intro/</id>
      <title type="text">GitHub热门项目！DocMD：AI优先的零配置文档引擎，秒级生成生产级文档</title>
      <published>2026-06-18T00:00:00.000Z</published>
      <updated>2026-06-18T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/ai/docmd-intro/"/>
      <summary type="text">零配置启动，AI原生支持，18kb超小体积，从Markdown到生产级文档只需一行命令！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！写文档怎么这么麻烦？<a href="#朋友们写文档怎么这么麻烦"><span>#</span></a></h2><p>你是不是每天都要面对这些困扰：</p><ul>
<li><strong>配置太复杂</strong>：Docusaurus、VitePress、MkDocs……每个都要写一堆配置文件，还要学框架语法</li>
<li><strong>启动太慢</strong>：npm install 半天，build 又半天，开发体验极差</li>
<li><strong>AI 支持弱</strong>：想让 AI 助手读取文档，还要手动整理，太麻烦了</li>
<li><strong>迁移成本高</strong>：从一个工具换到另一个，配置和结构全要改</li>
<li><strong>体积太大</strong>：生成的页面动不动几百 KB，加载慢死了</li>
</ul><p>今天我要给大家分享一个 GitHub 上的宝藏项目——<strong>DocMD</strong>！这个项目让写文档变得无比简单，零配置启动，AI 原生支持，一行命令搞定所有！</p></section>
<section><h2>✨ 什么是 DocMD？<a href="#-什么是-docmd"><span>#</span></a></h2><p>DocMD 是一款 <strong>AI 优先的零配置文档引擎</strong>，专为开发者和 LLM 代理设计。它的核心理念是：<strong>文档工具应该消失，让你专注于写作</strong>。</p><p><strong>核心特点</strong>：</p><ul>
<li>⚡ <strong>零配置启动</strong>：无需任何配置文件，直接运行即可</li>
<li>🤖 <strong>AI 原生支持</strong>：内置 MCP Server、AI Context，AI 助手可直接读取文档</li>
<li>📦 <strong>超小体积</strong>：初始加载仅 18KB，比 Docusaurus 小 13 倍</li>
<li>🚀 <strong>秒级启动</strong>：<code>npx @docmd/core dev</code> 一行命令，瞬间启动开发服务器</li>
<li>📱 <strong>生产就绪</strong>：静态 HTML、SEO 优化、PWA 支持，开箱即用</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/3520a57258dd4043a3782845875f50e720260618142943452.png" alt="" /></p></section>
<section><h2>🎯 核心功能<a href="#-核心功能"><span>#</span></a></h2><section><h3>1. 零配置，秒级启动<a href="#1-零配置秒级启动"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 直接在任意包含Markdown文件的文件夹中运行</span></div></div><div><div><div>2</div></div><div><span>npx</span><span> </span><span>@docmd/core</span><span> </span><span>dev</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 启动完成！访问 http://localhost:3000</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>就是这么简单！无需配置文件、无需安装依赖、无需学习新语法。导航自动生成，页面瞬间渲染，你的文档默认就是生产就绪的。</p></section><section><h3>2. AI-First 集成<a href="#2-ai-first-集成"><span>#</span></a></h3><p>DocMD 是首个专为 AI 时代设计的文档工具：</p><p><strong>MCP Server</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docmd</span><span> </span><span>mcp</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>启动 MCP Server，AI 代理可通过标准输入输出搜索、读取和验证文档。</p><p><strong>AI Context 生成</strong></p><ul>
<li><code>llms.txt</code> / <code>llms-full.txt</code> — 构建时自动生成完整文档上下文</li>
<li>AI 助手可直接读取这些文件，无需手动整理</li>
</ul><p><strong>AI 友好的复制按钮</strong></p><ul>
<li>页面内置 “Copy Markdown” / “Copy Context” 按钮</li>
<li>一键复制，优化 AI 聊天体验</li>
</ul></section><section><h3>3. 生产就绪的输出<a href="#3-生产就绪的输出"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npx</span><span> </span><span>@docmd/core</span><span> </span><span>build</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>生成的文档包含：</p><ul>
<li>✅ 静态 HTML（无运行时依赖）</li>
<li>✅ SEO 优化（sitemap、canonical、redirects）</li>
<li>✅ 离线搜索（模糊匹配）</li>
<li>✅ PWA 支持（离线导航）</li>
<li>✅ 多语言支持（i18n）</li>
<li>✅ 版本管理</li>
</ul></section><section><h3>4. 一键迁移和部署<a href="#4-一键迁移和部署"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 从其他工具迁移</span></div></div><div><div><div>2</div></div><div><span>docmd</span><span> </span><span>migrate</span><span>   </span><span># 支持 Docusaurus、VitePress、MkDocs 等</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 生成部署配置</span></div></div><div><div><div>5</div></div><div><span>docmd</span><span> </span><span>deploy</span><span>    </span><span># 自动生成 Docker、Nginx、Caddy 配置</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>5. 丰富的插件生态<a href="#5-丰富的插件生态"><span>#</span></a></h3>

<table><thead><tr><th>插件</th><th>状态</th><th>描述</th></tr></thead><tbody><tr><td><code>search</code></td><td>✅ 默认</td><td>离线全文搜索，支持模糊匹配</td></tr><tr><td><code>seo</code></td><td>✅ 默认</td><td>SEO 标签和 Open Graph 元数据</td></tr><tr><td><code>sitemap</code></td><td>✅ 默认</td><td>生成 sitemap.xml</td></tr><tr><td><code>llms</code></td><td>✅ 默认</td><td>AI 上下文生成</td></tr><tr><td><code>mermaid</code></td><td>✅ 默认</td><td>Markdown 中的 Mermaid 图表</td></tr><tr><td><code>openapi</code></td><td>✅ 默认</td><td>OpenAPI 3.x 规范渲染器</td></tr><tr><td><code>pwa</code></td><td>📦 可选</td><td>渐进式 Web App 支持</td></tr><tr><td><code>math</code></td><td>📦 可选</td><td>KaTeX/LaTeX 数学公式渲染</td></tr></tbody></table><p>安装可选插件：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docmd</span><span> </span><span>add</span><span> </span><span>pwa</span></div></div><div><div><div>2</div></div><div><span>docmd</span><span> </span><span>add</span><span> </span><span>math</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>🚀 安装教程<a href="#-安装教程"><span>#</span></a></h2><section><h3>方法一：npx 直接运行（推荐）<a href="#方法一npx-直接运行推荐"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 开发模式</span></div></div><div><div><div>2</div></div><div><span>npx</span><span> </span><span>@docmd/core</span><span> </span><span>dev</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 生产构建</span></div></div><div><div><div>5</div></div><div><span>npx</span><span> </span><span>@docmd/core</span><span> </span><span>build</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>方法二：全局安装<a href="#方法二全局安装"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>-g</span><span> </span><span>@docmd/core</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span># 开发模式</span></div></div><div><div><div>4</div></div><div><span>docmd</span><span> </span><span>dev</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span># 生产构建</span></div></div><div><div><div>7</div></div><div><span>docmd</span><span> </span><span>build</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>方法三：Docker 运行<a href="#方法三docker-运行"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-p</span><span> </span><span>3000:3000</span><span> </span><span>ghcr.io/docmd-io/docmd:0.8.6</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>方法四：项目依赖安装<a href="#方法四项目依赖安装"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>@docmd/core</span><span> </span><span>--save-dev</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在 <code>package.json</code> 中添加脚本：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"scripts"</span><span>: {</span></div></div><div><div><div>3</div></div><div><span>    </span><span>"docs:dev"</span><span>: </span><span>"docmd dev"</span><span>,</span></div></div><div><div><div>4</div></div><div><span>    </span><span>"docs:build"</span><span>: </span><span>"docmd build"</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>6</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>📝 使用指南<a href="#-使用指南"><span>#</span></a></h2><section><h3>快速开始<a href="#快速开始"><span>#</span></a></h3><ol>
<li>创建一个项目目录：</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>mkdir</span><span> </span><span>my-docs</span><span> &amp;&amp; </span><span>cd</span><span> </span><span>my-docs</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>创建一些 Markdown 文件：</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>mkdir</span><span> </span><span>docs</span></div></div><div><div><div>2</div></div><div><span>echo</span><span> </span><span>"# 欢迎使用 DocMD"</span><span> &gt; </span><span>docs/index.md</span></div></div><div><div><div>3</div></div><div><span>echo</span><span> </span><span>"# API 文档"</span><span> &gt; </span><span>docs/api.md</span></div></div><div><div><div>4</div></div><div><span>echo</span><span> </span><span>"# 快速开始"</span><span> &gt; </span><span>docs/getting-started.md</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>启动开发服务器：</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npx</span><span> </span><span>@docmd/core</span><span> </span><span>dev</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>访问 <code>http://localhost:3000</code>，你的文档已经准备好了！</li>
</ol></section><section><h3>配置示例（可选）<a href="#配置示例可选"><span>#</span></a></h3><p>当你需要更多控制时，创建 <code>docmd.config.json</code>：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>const</span><span> { </span><span>defineConfig</span><span> } </span><span>=</span><span> </span><span>require</span><span>(</span><span>'@docmd/core'</span><span>);</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>module</span><span>.</span><span>exports</span><span> </span><span>=</span><span> </span><span>defineConfig</span><span>({</span></div></div><div><div><div>4</div></div><div><span>  </span><span>title</span><span>:</span><span> </span><span>'My Project'</span><span>,</span></div></div><div><div><div>5</div></div><div><span>  </span><span>url</span><span>:</span><span> </span><span>'https://docs.myproject.com'</span><span>,</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>  </span><span>// 版本管理</span></div></div><div><div><div>8</div></div><div><span>  </span><span>versions</span><span>:</span><span> {</span></div></div><div><div><div>9</div></div><div><span>    </span><span>current</span><span>:</span><span> </span><span>'v2'</span><span>,</span></div></div><div><div><div>10</div></div><div><span>    </span><span>all</span><span>:</span><span> [</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>{ </span><span>id</span><span>:</span><span> </span><span>'v2'</span><span>, </span><span>dir</span><span>:</span><span> </span><span>'docs'</span><span> },</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>{ </span><span>id</span><span>:</span><span> </span><span>'v1'</span><span>, </span><span>dir</span><span>:</span><span> </span><span>'docs-v1'</span><span> }</span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>]</span></div></div><div><div><div>14</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span>  </span><span>// 多语言支持</span></div></div><div><div><div>17</div></div><div><span>  </span><span>i18n</span><span>:</span><span> {</span></div></div><div><div><div>18</div></div><div><span>    </span><span>default</span><span>:</span><span> </span><span>'zh'</span><span>,</span></div></div><div><div><div>19</div></div><div><span>    </span><span>locales</span><span>:</span><span> [</span></div></div><div><div><div>20</div></div><div><span><span>      </span></span><span>{ </span><span>id</span><span>:</span><span> </span><span>'zh'</span><span>, </span><span>label</span><span>:</span><span> </span><span>'中文'</span><span> },</span></div></div><div><div><div>21</div></div><div><span><span>      </span></span><span>{ </span><span>id</span><span>:</span><span> </span><span>'en'</span><span>, </span><span>label</span><span>:</span><span> </span><span>'English'</span><span> },</span></div></div><div><div><div>22</div></div><div><span><span>    </span></span><span>]</span></div></div><div><div><div>23</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>24</div></div><div><span>});</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section>
<section><h2>📊 对比其他文档工具<a href="#-对比其他文档工具"><span>#</span></a></h2>

<table><thead><tr><th>特性</th><th>DocMD</th><th>Docusaurus</th><th>MkDocs</th><th>VitePress</th><th>Mintlify</th></tr></thead><tbody><tr><td><strong>语言</strong></td><td>Node.js</td><td>React.js</td><td>Python</td><td>Vue</td><td>SaaS</td></tr><tr><td><strong>需要配置</strong></td><td>❌ 零配置</td><td>✅ 需要</td><td>✅ 需要</td><td>✅ 需要</td><td>✅ 需要</td></tr><tr><td><strong>初始体积</strong></td><td>⚡ 18KB</td><td>~250KB</td><td>~40KB</td><td>~50KB</td><td>~120KB</td></tr><tr><td><strong>导航</strong></td><td>即时 SPA</td><td>React SPA</td><td>全页刷新</td><td>Vue SPA</td><td>Hosted SPA</td></tr><tr><td><strong>版本管理</strong></td><td>✅ 原生</td><td>✅ 复杂</td><td>插件</td><td>手动</td><td>✅</td></tr><tr><td><strong>多语言</strong></td><td>✅ 原生</td><td>✅ 复杂</td><td>插件</td><td>✅</td><td>✅</td></tr><tr><td><strong>搜索</strong></td><td>✅ 内置</td><td>Algolia</td><td>✅</td><td>MiniSearch</td><td>Cloud</td></tr><tr><td><strong>AI Context</strong></td><td>✅ 内置</td><td>❌</td><td>❌</td><td>❌</td><td>✅</td></tr><tr><td><strong>MCP Server</strong></td><td>✅ 内置</td><td>❌</td><td>❌</td><td>❌</td><td>✅</td></tr><tr><td><strong>Docker</strong></td><td>✅ 官方</td><td>❌</td><td>✅</td><td>❌</td><td>N/A</td></tr><tr><td><strong>自托管</strong></td><td>✅</td><td>✅</td><td>✅</td><td>✅</td><td>❌</td></tr><tr><td><strong>成本</strong></td><td>🆓 开源</td><td>🆓 开源</td><td>🆓 开源</td><td>🆓 开源</td><td>Freemium</td></tr></tbody></table></section>
<section><h2>📝 总结<a href="#-总结"><span>#</span></a></h2><p>DocMD 是一款真正为 AI 时代设计的文档工具。它以零配置为核心，让你专注于写作而非配置；以 AI 原生为特色，让文档与 AI 助手无缝协作；以超小体积为优势，提供极速的加载体验。如果你正在寻找一款简单、高效、AI 友好的文档工具，DocMD 绝对值得一试！</p></section>
<section><h2>🌟 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub 地址</strong>: <a href="https://github.com/docmd-io/docmd" target="_blank">https://github.com/docmd-io/docmd</a></p><p><strong>官方网站</strong>: <a href="https://docmd.io" target="_blank">https://docmd.io</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p></section>
<section><h2>🎉 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你平时用什么工具写文档？最希望文档工具支持什么功能？欢迎在评论区和我交流分享！</p><p>我会定期分享更多好用的开发工具，记得关注我哦！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/dotnet/dotnet9%E4%B8%AD%E7%9A%84%E8%AE%A4%E8%AF%81%E9%89%B4%E6%9D%83%E5%AD%A6%E4%B9%A0/</id>
      <title type="text">dotnet9中的认证鉴权学习</title>
      <published>2026-06-17T12:32:13.000Z</published>
      <updated>2026-06-17T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/dotnet/dotnet9%E4%B8%AD%E7%9A%84%E8%AE%A4%E8%AF%81%E9%89%B4%E6%9D%83%E5%AD%A6%E4%B9%A0/"/>
      <summary type="text">dotnet9中的认证鉴权学习</summary>
      <content type="html"><![CDATA[<section><h1>1.简介<a href="#1简介"><span>#</span></a></h1><p><strong>OpenAPI</strong></p><p><strong>类型</strong>：接口规范标准</p><p><strong>作用</strong>：</p><ul>
<li>生成标准化 API 文档（JSON/YAML 格式）。</li>
<li>支持客户端 SDK 自动生成。</li>
<li>支持 API 版本化（v1、v2…）并在文档中体现。</li>
</ul><p><strong>适用环境</strong>：开发环境 + 生产环境。</p><p><strong>特点</strong>：</p><ul>
<li>偏向“规范化文档”，强调接口定义的标准和一致性。</li>
<li>可以在 Swagger UI 或 Redoc 上展示。</li>
</ul><p><strong>Scalar</strong></p><p><strong>类型</strong>：开发环境工具 / Minimal API 可视化。</p><p><strong>作用</strong>：</p><ul>
<li>提供交互式 API 浏览界面，快速查看接口、参数、返回值。</li>
<li>集成 API 版本化，方便开发者调试不同版本的接口。</li>
<li>支持 Minimal API，提供根路径重定向（如 <code>/</code> → <code>/scalar/v1</code>）。</li>
</ul><p><strong>适用环境</strong>：仅开发环境。</p><p><strong>特点</strong>：</p><ul>
<li>偏向“开发体验”，方便快速调试 Minimal API。</li>
<li>并不生成标准文档或 SDK，主要供开发者内部使用。</li>
</ul><p><strong>OpenAPI 与 Scalar 的关系</strong></p>

<table><thead><tr><th>功能 / 特性</th><th>OpenAPI</th><th>Scalar</th></tr></thead><tbody><tr><td>核心用途</td><td>标准化接口文档</td><td>开发环境 API 浏览与调试</td></tr><tr><td>适用环境</td><td>开发 + 生产</td><td>开发环境</td></tr><tr><td>Minimal API 支持</td><td>需要手动集成</td><td>原生支持</td></tr><tr><td>API 版本化</td><td>支持</td><td>支持，并可与 OpenAPI 集成</td></tr><tr><td>接口调试</td><td>可选，但不是核心</td><td>核心功能</td></tr><tr><td>文档标准化</td><td>是</td><td>否</td></tr></tbody></table></section>
<section><h1>2.基本使用<a href="#2基本使用"><span>#</span></a></h1><p>在 .NET 9 中，Web API 模板里 <code>Program.cs</code> 通常会有：<code>builder.Services.AddOpenApi()</code>、<code>app.MapOpenApi()</code> 这样的调用，用于生成<code>OpenAPI </code>规范文档（通常输出为 <code>/openapi/v1.json</code> 或类似路径）。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/4bb7c799bba5423fad90cf78aad6a0a91916404-20251121234747207-1843190792.png" alt="image-20251031170754363" /><figcaption>image-20251031170754363</figcaption></figure><p></p><p>启动项目后可打开<code>OpenAPI </code>规范文档</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://localhost:7031/openapi/v1.json</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/d25ca4811d154f119e0c44b22483c71d1916404-20251121234747513-1754445920.png" alt="image-20251031170949411" /><figcaption>image-20251031170949411</figcaption></figure><p></p><p>虽然规范文档自动生成，但交互式文档界面（像以前常见的 Swashbuckle.AspNetCore／Swagger UI）在 .NET 9 模板中已经 <strong>不再默认</strong> 引入。如果你想有漂亮的 UI 文档页面／测试接口功能，可以选择第三方工具，比如 Scalar.AspNetCore（简称 “Scalar”）来做补充。</p><p><strong>安装 <code>Scalar.AspNetCore</code> 包</strong></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/3f009674ee4c44b7a77f74e31b17daa81916404-20251121234747781-550163971.png" alt="image-20251031171208860" /><figcaption>image-20251031171208860</figcaption></figure><p></p><p>然后在 <code>Program.cs</code> 中加入 <code>app.MapScalarApiReference()</code> 即可</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/8636d69d23144f23925e526aa4424e801916404-20251121234748074-875407871.png" alt="image-20251102002943714" /><figcaption>image-20251102002943714</figcaption></figure><p></p><p>然后启动项目，再次访问</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://localhost:7031/scalar/</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/8fe3108367174228a508d7fa6e5551691916404-20251121234748328-1343743223.png" alt="image-20251031171319037" /><figcaption>image-20251031171319037</figcaption></figure><p></p><p><strong>这只是<code>Scalar</code>的基本使用，正常开发会添加很多<code>Scalar</code>配置，具体可参考<code>ehop</code>相关</strong></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/9e4f553436514c74ba52a03028636fcc1916404-20251121234748580-493322218.png" alt="image-20251031171509868" /><figcaption>image-20251031171509868</figcaption></figure><p></p></section>
<section><h1>3.<code>ehop</code>中使用<code>Scalar</code><a href="#3ehop中使用scalar"><span>#</span></a></h1><p>还是简单过一下<code>eshop</code>中的代码</p><p>在<code>appsettings.json</code>中配置<code>Scalar</code></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/8ece1049f24a4371a0cbf2bea346a01a1916404-20251121234748814-813056873.png" alt="image-20251102003401706" /><figcaption>image-20251102003401706</figcaption></figure><p></p><p>注册<code>API</code>版本控制（<code>API Versioning</code>）服务，然后注册默认<code>OpenAPI </code>文档</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/ad468b7f0db44ff3897ac75b614a02181916404-20251121234749063-2086835512.png" alt="image-20251102173420418" /><figcaption>image-20251102173420418</figcaption></figure><p></p><p>获取<code>appsettings.json</code>中的<code>OpenApi</code>和<code>Identity</code>相关配置</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/44a612421247470b851a360b919ec6431916404-20251121234749355-1272941358.png" alt="image-20251102173537913" /><figcaption>image-20251102173537913</figcaption></figure><p></p><p>所有的服务都配置了2个版本的接口文档</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/31a4a36453884ec684596ff32cf71cb91916404-20251121234749619-1717208486.png" alt="image-20251102173814101" /><figcaption>image-20251102173814101</figcaption></figure><p></p><section><h2>3.1配置文档标题和描述(<code>ApplyApiVersionInfo</code>)<a href="#31配置文档标题和描述applyapiversioninfo"><span>#</span></a></h2><p>然后我们具体看一下<code>OpenAPI</code> 文档的相关配置</p><p>把配置文件中 <code>OpenApi:Document:Title</code> 和 <code>OpenApi:Document:Description</code> 应用到当前文档（指定版本）的元数据中（即 <code>Info.title</code>、<code>Info.description</code>）（设置文档标题和描述）。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>options.ApplyApiVersionInfo(openApi.GetRequiredValue("Document:Title"), openApi.GetRequiredValue("Document:Description"));</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/44494300f67c4107b9117b0708be7b251916404-20251121234749903-721690440.png" alt="image-20251103193743856" /><figcaption>image-20251103193743856</figcaption></figure><p></p><p>查看一下<code>ApplyApiVersionInfo</code>的具体实现，这个方法设置了版本、标题、描述</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/b4b353c018b34f31bdd87d94c7c79d6d1916404-20251121234750134-1570467142.png" alt="image-20251103204717865" /><figcaption>image-20251103204717865</figcaption></figure><p></p><p>然后打开<code>Scalar</code>可以查看到对应的标题和描述</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/3a65ab5e6efc4062a786cd5b21aa7b271916404-20251121234750345-1631170933.png" alt="image-20251103165747439" /><figcaption>image-20251103165747439</figcaption></figure><p></p></section><section><h2>3.2配置授权检查(<code>ApplyAuthorizationChecks</code>)<a href="#32配置授权检查applyauthorizationchecks"><span>#</span></a></h2><p>把读取到的 scopes（scope 名称列表）注入到 OpenAPI 文档的 security requirement / OAuth2 flows 中。目的是让<code>Scalar</code>的 “<code>Authorize</code>” 界面能展示可用的<code>scope</code>，用户可以在 UI 中选择要请求的 scope。</p><p>对所有带 <code>[Authorize]</code> 特性的 API 操作：</p><ul>
<li>自动添加 <code>401 Unauthorized</code> 和 <code>403 Forbidden</code> 响应描述。</li>
<li>在 OpenAPI 文档中添加 Security Requirement，绑定 OAuth2 scopes。</li>
</ul><p><code>scopes.Keys</code> 取自配置文件 <code>Identity:Scopes</code>，表示 API 可以使用哪些权限范围（scope）。</p><p>订单服务(<code>Ordering.API</code>)配置的是<code>orders</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>// 根据 Identity 配置的 Scopes 添加授权检查</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>options.ApplyAuthorizationChecks([.. scopes.Keys]);</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/bdb79781109b4150af58a30fd7a9ccdf1916404-20251121234750615-2129135828.png" alt="image-20251103193910937" /><figcaption>image-20251103193910937</figcaption></figure><p></p><p>查看<code>ApplyAuthorizationChecks</code>具体实现</p><ul>
<li>设置 401/403 响应描述</li>
<li>绑定 OAuth2 scopes</li>
</ul><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/85934c5b99f64368a30188ce66afd8e01916404-20251121234750872-1990935526.png" alt="image-20251103204927560" /><figcaption>image-20251103204927560</figcaption></figure><p></p><p>然后打开<code>Scalar</code>，点击<code>Auth Type</code>，然后选择<code>oauth2</code></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/1ba8346afcd5435b95bc328477e76c831916404-20251121234751140-1038325057.png" alt="image-20251103194359642" /><figcaption>image-20251103194359642</figcaption></figure><p></p><p>发现我们配置的<code>"orders": "Ordering API"</code>已经正常显示</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/b9656e0941d94918a8e2f6cd5f845b8c1916404-20251121234751336-1344311035.png" alt="image-20251103194522424" /><figcaption>image-20251103194522424</figcaption></figure><p></p><p>选择<code>api/orders/cancel</code>接口，最下面有配置的<code>401/403</code>响应描述</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/8415639c124e4f86bb3c62b32ec78a251916404-20251121234751571-1451651038.png" alt="image-20251103205331756" /><figcaption>image-20251103205331756</figcaption></figure><p></p></section><section><h2>3.3配置安全方案(<code>ApplySecuritySchemeDefinitions</code>)<a href="#33配置安全方案applysecurityschemedefinitions"><span>#</span></a></h2><p>上面配置授权的<code>Scope</code>，这里配置具体的授权方案</p><p>将安全方案（security schemes）定义加入到生成的 OpenAPI 文档中（例如 <code>bearerAuth</code> 的 <code>type: http</code>、<code>scheme: bearer</code>，或 OAuth2 的 <code>authorizationCode</code>/<code>implicit</code>/<code>clientCredentials</code> flows）。这一步通常负责在 <code>components.securitySchemes</code> 下注册 scheme，并可能把默认安全要求加入到文档中。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/003720f9bba645058479aee3dbebca4d1916404-20251121234751811-971255508.png" alt="image-20251103194844679" /><figcaption>image-20251103194844679</figcaption></figure><p></p><p>查看<code>ApplySecuritySchemeDefinitions</code>的具体实现：创建<code>oauth2</code>的安全方案</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/5de78a71d62c4bebbeec3f32d749c08d1916404-20251121234752075-1463640978.png" alt="image-20251103205653148" /><figcaption>image-20251103205653148</figcaption></figure><p></p><p>打开<code>Scalar</code>，选择<code>oauth2</code>，显示的就是<code>oauth2</code>的安全方案</p><blockquote><p><strong>正常顺序应该先配置<code>oauth2</code>方案，在配置需要的<code>Scopes</code>，<code>eshop</code>这里代码顺序好像没有影响功能，我这块只是好奇提一下</strong></p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/f21c294fb56d4a5f87f3d6ca40e03e771916404-20251121234752256-1275342851.png" alt="image-20251103205814938" /><figcaption>image-20251103205814938</figcaption></figure><p></p></section><section><h2>3.4配置弃用接口(<code>ApplyOperationDeprecatedStatus</code>)<a href="#34配置弃用接口applyoperationdeprecatedstatus"><span>#</span></a></h2><p>根据 API Versioning 或 <code>[Obsolete]</code> 特性自动标记接口是否已弃用。在生成的 OpenAPI 文档里把接口标记为已弃用，Swagger/Scalar UI 就会显示“Deprecated”提示。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/224d454bbf3d4281a1a7dfe1186ab7381916404-20251121234752524-694000742.png" alt="image-20251103211112849" /><figcaption>image-20251103211112849</figcaption></figure><p></p><p>查看<code>ApplyOperationDeprecatedStatus</code>具体实现：</p><ul>
<li><code>apiDescription.IsDeprecated()</code> ：如果接口被标记为 <code>[Obsolete]</code>返回 <code>true</code></li>
<li><code>operation.Deprecated |= </code>： 表示 <strong>如果接口已弃用，则在 OpenAPI 文档里设置 <code>deprecated: true</code></strong></li>
<li>只要 <code>apiDescription</code> 标记为弃用，就把 <code>operation.Deprecated</code> 设置为 <code>true</code>，否则保持原值</li>
</ul><blockquote><p><strong><code>|=</code>符号什么意思？</strong></p><ul>
<li><code>|=</code> 是一种 <strong>缩写</strong>，等价于a = a | b</li>
<li>对 <strong>布尔类型</strong>，就是 <strong>逻辑或赋值</strong></li>
<li>对 <strong>整型类型</strong>，就是 <strong>按位或赋值</strong></li>
</ul></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/ed67e321f06941d8949f61ec3985b2ad1916404-20251121234752818-1025408574.png" alt="image-20251103211426388" /><figcaption>image-20251103211426388</figcaption></figure><p></p><p>经过测试<code>apiDescription.IsDeprecated()</code>不支持<code> Minimal API</code>，接口加上<code>[Obsolete]</code>没有弃用显示</p><blockquote><p><strong>为什么<code>apiDescription.IsDeprecated()</code>不支持<code> Minimal API</code>？</strong></p><p><code>apiDescription.IsDeprecated()</code> <strong>并不是</strong>检测方法上有没有 <code>[Obsolete]</code>，它是基于 <strong>API Versioning</strong>（<code>ApiVersionMetadata</code>）来判断“某个版本是否被标为弃用”（看源码）。因此在 Minimal API（通常不会把版本 metadata 放到同样位置）下常常无效。</p><p><code>apiDescription.IsDeprecated()</code> 只能可靠用于 <strong>Controller + API Versioning</strong>，对于 <strong>Minimal API/Scalar</strong>，必须手动在 OpenAPI 生成时读取 <code>[Obsolete]</code> 或自定义 Metadata 来标记 Deprecated。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/ed9a5e7797394de7ad582d84f0bc500a1916404-20251121234753089-1331966214.png" alt="image-20251103221040151" /><figcaption>image-20251103221040151</figcaption></figure><p></p><p>为了演示弃用效果，我还是找到了2种方法：</p><ul>
<li>第二种方法：维护一个弃用的接口列表，读到过期的接口直接<code>operation.Deprecated = true</code></li>
<li>第三种方法：<code>context.Description.ActionDescriptor?.EndpointMetadata</code> 获取当前 API 方法（Endpoint）上附加的所有元数据（Attributes/特性），例如 <code>[Obsolete]</code>、授权特性等。如果有<code>ObsoleteAttribute</code>返回<code>operation.Deprecated = true</code>，并且可以获取弃用设置的消息。</li>
</ul><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/96f1403ee84e4facbb8e2cfa165928811916404-20251121234753330-1273127299.png" alt="image-20251103223125039" /><figcaption>image-20251103223125039</figcaption></figure><p></p><p>然后在接口加上<code>[Obsolete("自定义消息")]</code>特性和提示弃用的消息，有2种方法：</p><ul>
<li>使用<code>WithMetadata</code>链式添加</li>
<li>直接在方法上添加特性</li>
</ul><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/ac9263b97b254d2fbed203722d85d0321916404-20251121234753684-1717324505.png" alt="image-20251103223419433" /><figcaption>image-20251103223419433</figcaption></figure><p></p><p>启动项目，打开<code>Scalar</code>，可以看到<code>api/orders/cancel</code>接口已被弃用</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/448b229dde884d2d9ca940d7dd0d87c01916404-20251121234753955-1703652115.png" alt="image-20251103223542587" /><figcaption>image-20251103223542587</figcaption></figure><p></p></section><section><h2>3.5配置<code>API</code>版本描述(<code>ApplyApiVersionDescription</code>)<a href="#35配置api版本描述applyapiversiondescription"><span>#</span></a></h2><p>给每个操作的 <code>api-version</code> 参数添加描述信息，提供示例值（如 v1 → “1.0”, v2 → “2.0”），帮助调用者知道如何在 URL 或 Header 中传递版本号。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/084edbc186fa4217a7788c474506794d1916404-20251121234754253-1218690863.png" alt="image-20251103210545646" /><figcaption>image-20251103210545646</figcaption></figure><p></p><p>查看<code>ApplyApiVersionDescription</code>具体实现：配置版本描述，区分显示了版本号</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/f1397c0f0b0545539cbd532bfab55e831916404-20251121234754541-821225078.png" alt="image-20251103210824832" /><figcaption>image-20251103210824832</figcaption></figure><p></p><p>启动项目，打开<code>Scalar</code>，选择接口<code>api/orders/cancel</code>，<code>Query Parameters</code>下显示版本信息</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/669e90eae8014044a88b1149fd8d8bac1916404-20251121234754745-1318163501.png" alt="image-20251103210953760" /><figcaption>image-20251103210953760</figcaption></figure><p></p></section><section><h2>3.6配置<code>Schema</code>的<code>Nullable </code>属性(<code>ApplySchemaNullableFalse</code>)<a href="#36配置schema的nullable-属性applyschemanullablefalse"><span>#</span></a></h2><p>遍历所有生成的模型（Schema）属性，对非必填字段，将 <code>Nullable</code> 属性设置为 <code>false</code>，避免前端生成可选字段为空时的类型问题。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/f8cced59422a46d491ca63b430acf8b81916404-20251121234755047-1963245240.png" alt="image-20251104001540378" /><figcaption>image-20251104001540378</figcaption></figure><p></p><p>查看<code>ApplySchemaNullableFalse</code>的具体实现：</p><ul>
<li><code>schema.Properties</code>不能<code>null</code></li>
<li>然后遍历<code>schema.Properties</code></li>
<li>判断<code>schema.Required</code>不包含<code>property.Key</code>(属性名称)</li>
<li>设置<code>property.Key</code>(属性名称)的<code>Nullable</code>为<code>false</code></li>
</ul><p>代码简单就是不知道这个<code>schema</code>是什么玩意</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/cb1c4c8b6b7b4bab9ebce41e7522ede91916404-20251121234755368-2120854540.png" alt="image-20251104001842203" /><figcaption>image-20251104001842203</figcaption></figure><p></p><p>我对这个<code>schema</code>挺好奇的，一开始不知道上面在遍历什么</p><p>我们启动项目，然后打开<code>OpenAPI </code>规范文档，找到<code>components</code>节点，<code>components</code>下的<code>schemas</code>列表就是我们要遍历的<code>schema</code>，然后代码就清晰了</p><ul>
<li>
<p><code>schema</code>：描述请求或返回实体的数据结构，包括字段、类型、必填/可选、格式等信息。</p>
</li>
<li>
<p><code>schema.Properties</code>：定义对象的所有字段及类型。</p>
</li>
<li>
<p><code>Type</code>：字段的数据类型</p>
</li>
<li>
<p><code>Format</code>：对 <code>Type</code> 的进一步限定，通常表示数据的具体存储或精度方式</p>
</li>
<li>
<p><code>Nullable</code>：表示字段是否可以为 <code>null</code>，也就是可空性</p>
</li>
<li>
<p><code>schema.Required</code>：列出必填字段的名字数组。</p>
</li>
<li>
<p><code>schema.type</code>：表示整个<code>schema </code>的类型，这里都是 <code>"object"</code>，意味着它是一个对象/DTO。</p>
</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>http://localhost:5224/openapi/v1.json</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/80f2fef4d64c46c0a21c2822b4a0aeaa1916404-20251121234755568-980865830.png" alt="image-20251104002018542" /><figcaption>image-20251104002018542</figcaption></figure><p></p><p>打开<code>Scalar</code>，可以查看<code>nullable</code>标记</p><blockquote><p><strong>为什么<code>CreateOrderRequest</code>好多字段<code>"nullable": true</code>，其他对象都没有这个”nullable”？</strong></p><ul>
<li><code>CreateOrderRequest</code> 全部字段都是 <strong>record 构造函数参数</strong></li>
<li>项目未启用 NRT → 引用类型默认可空 → OpenAPI 自动生成 <code>"nullable": true</code></li>
<li>而其他 record 或 class 的字段：
<ul>
<li>不是构造函数参数</li>
<li>或嵌套 record / class</li>
<li>或值类型字段（如 <code>int</code>、<code>DateTime</code>）</li>
<li>OpenAPI 默认省略 <code>nullable</code></li>
</ul>
</li>
</ul><p>OpenAPI 的 <code>nullable</code> 属性主要由 <strong>字段类型 + record 构造函数 + 项目 NRT 设置</strong> 决定，构造函数的引用类型在未启用 NRT 时会被标记 <code>"nullable": true"</code>，其他字段默认省略。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/c09e25a76897462ca171246594badda21916404-20251121234755800-1982607503.png" alt="image-20251104004821610" /><figcaption>image-20251104004821610</figcaption></figure><p></p></section><section><h2>3.7配置<code>Schema</code>的<code>Nullable </code>属性(<code>ApplySchemaNullableFalse</code>)<a href="#37配置schema的nullable-属性applyschemanullablefalse"><span>#</span></a></h2><p>OpenAPI 文档中默认会生成 <code>Servers</code> 列表，通常包含项目启动时的本地 URL，清空后，文档不会绑定具体端口，适用于动态端口或服务注册场景（如 Aspire 微服务平台），确保在不同环境下，文档不会显示错误 URL。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/f3791e94089c4f1eb73b6a689c7b5b481916404-20251121234756099-61525666.png" alt="image-20251104005609859" /><figcaption>image-20251104005609859</figcaption></figure><p></p><p>通过 <code>servers</code> 设置不同环境地址，<code>Scalar</code>根据选择的 URL 发送请求</p><p>我们配置几个不存在的服务器地址</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/f0cb8b4a0ffa4638a2c9a5c43348a9261916404-20251121234756359-467910912.png" alt="image-20251104010334713" /><figcaption>image-20251104010334713</figcaption></figure><p></p><p>重启项目，再打开<code>Scalar</code>，配置的<code>Url</code>都显示出来了</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/7a3560b5997e4c9185e713a2aaee895e1916404-20251121234756549-586186957.png" alt="image-20251104010424300" /><figcaption>image-20251104010424300</figcaption></figure><p></p><p>选择一个<code>get</code>请求接口，然后测试，发现请求地址已经变成勾选的<code>Server</code>了</p><p><strong>接口不通没有关系，我们主要看请求地址，授权认证后面再调，测试完记得把<code>document.Servers</code>改回去</strong></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/d0fa478595c44b7589ce2af7d63d29e51916404-20251121234756728-619623729.png" alt="image-20251104010558799" /><figcaption>image-20251104010558799</figcaption></figure><p></p></section><section><h2>3.8配置<code>Scalar</code>认证授权(<code>Implicit</code>)<a href="#38配置scalar认证授权implicit"><span>#</span></a></h2><section><h4>1.配置服务认证授权<a href="#1配置服务认证授权"><span>#</span></a></h4><p>订单服务(<code>Ordering.API</code>)配置了认证授权，所以我们使用<code>Scalar</code>调试接口的时候也需要认证服务(<code>Identity.API</code>)颁发的<code>token</code>，上面的测试就是<code>401</code>无权限</p><p>首先我们再回忆下我们认证授权配置了那些：</p><ul>
<li>认证服务(<code>Authority</code>)：我们本地启动的<code>Identity.API</code>，其他服务认证授权配置<code>Identity.API</code>的地址即可。</li>
<li>使用<code>Https</code>协议获取认证中心(<code>Authority </code>)元数据(<code>RequireHttpsMetadata</code>)：原来这里是<code>false</code>，访问不验证<code>https</code>，为了多学习我们设置为<code>true</code>，本身<code>Identity.API</code>启动就是使用的<code>https</code>协议</li>
<li>订阅人(<code>Audience</code>)：确保认证服务<code>Identity.API</code>颁发的<code>token</code>是发给我的(订单服务)，就是我们在<code>appsettings.json</code>中配置<code>"Audience": "orders"</code>。简单理解：什么服务就配置什么服务的标识，但是认证服务同时也要有此标识。确保这个<code>Token </code>是发给当前 API 的，而不是其他服务。验证签发<code>token</code>的<code>aud</code>。</li>
<li>签发者(<code>Issuers</code>)：确保<code>Token</code>是由受信任的认证中心签发。验证签发<code>token</code>的<code>iss</code>。</li>
</ul><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/5033d6374592465aa3204ce6f5e4d16d1916404-20251121234756999-62539003.png" alt="image-20251104012258084" /><figcaption>image-20251104012258084</figcaption></figure><p></p><p>还需要再回忆一下认证服务(<code>Identity.API</code>)中的客户端配置，找到<code>orderingswaggerui</code>配置</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/3baf193998344d21a08c29e313f193201916404-20251121234757216-2101100493.png" alt="image-20251104014215886" /><figcaption>image-20251104014215886</figcaption></figure><p></p><p>然后我们启动认证服务，在<code>..\eShop\src\Identity.API</code>目录下运行以下命令：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>dotnet run --urls https://localhost:5243/</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/5d4dbcc9af6443558bc7a3ef062ac5811916404-20251121234757784-1496489501.png" alt="image-20251103193457394" /><figcaption>image-20251103193457394</figcaption></figure><p></p></section><section><h4>2.配置隐式授权(<code>Implicit</code>)<a href="#2配置隐式授权implicit"><span>#</span></a></h4><p>启动订单服务(<code>Ordering.API</code>)，打开<code>Scalar</code>，然后配置好<code>Client ID</code>和<code>Scopes</code>，之后点击<code>Authorize</code></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/0b7d87604d6b465aa3b5315e55eb21951916404-20251121234758076-1730835387.png" alt="image-20251104014612043" /><figcaption>image-20251104014612043</figcaption></figure><p></p><p>提示我们错误的回调地址(<code>Invalid redirect_uri</code>)</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/b8b9cdd6ccdf4e369da9d3438dd029801916404-20251121234758431-612211542.png" alt="image-20251104014913406" /><figcaption>image-20251104014913406</figcaption></figure><p></p><p>再回到认证服务(<code>Identity.API</code>)的<code>Config</code>配置中，简单了解一下隐式授权模式(<code>Implicit Grant Type</code>)</p><blockquote><p><strong><code>Implicit Flow</code>：</strong></p><p>响应类型直接把 <code>access_token</code>（以及可选的 <code>id_token</code>）返回给浏览器。常用于早期的单页应用（SPA）、Swagger UI、Scalar 等纯前端客户端，不需要/也无法安全保存客户端密钥（client secret）。</p><p><strong>特点：</strong></p><ul>
<li>不使用客户端密钥（client secret）；</li>
<li>Token 直接通过 URL fragment (<code>#access_token=...</code>) 返回给浏览器；</li>
<li>通常不会返回 refresh_token（为避免长期泄露风险）；</li>
<li>更容易实现，但安全性低于 Authorization Code + PKCE。</li>
</ul></blockquote><p><strong>所以我们需要配置回调地址，我们配置<code>Scalar</code>的地址，有<code>v1/v2</code>俩个版本的地址：</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># ehsop没有配置configuration["OrderingApiClient"]，这个返回的是null</span></div></div><div><div><div>2</div></div><div><span># 我们要配置完整地址</span></div></div><div><div><div>3</div></div><div><span>RedirectUris = {</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>$"{configuration["OrderingApiClient"]}/swagger/oauth2-redirect.html",</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>$"http://localhost:5224/scalar/v1",</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>$"http://localhost:5224/scalar/v2"</span></div></div><div><div><div>7</div></div><div><span>},</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/6b0c71657acc412bb5c44f7c1510c1df1916404-20251121234758754-1986102963.png" alt="image-20251104175844494" /><figcaption>image-20251104175844494</figcaption></figure><p></p><p>配置完回调地址后，再次启动项目，打开<code>Scalar</code>，设置<code>Client ID</code>和<code>Scopes</code>，然后点击<code>Authorize</code></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/8fdbc9cdab4743ee8aa782c81e461f531916404-20251121234759018-64485508.png" alt="image-20251104180230495" /><figcaption>image-20251104180230495</figcaption></figure><p></p><p>已经成功获取<code>token</code>，可以点开右边小眼睛图标查看<code>token</code></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/2bf9b246bd3e472ea5d8e0aefac2fb2f1916404-20251121234759228-1885006033.png" alt="image-20251104180349148" /><figcaption>image-20251104180349148</figcaption></figure><p></p><p>点开<code>/api/orders</code>接口测试一下，返现还是返回错误：<code>Bearer error="invalid_token", error_description="The audience 'empty' is invalid"</code></p><p><code>token</code>中的<code>audience</code>(订阅人)不对</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/824518e98f5643c8a196e5557818b98c1916404-20251121234759411-64735547.png" alt="image-20251104180523049" /><figcaption>image-20251104180523049</figcaption></figure><p></p><p>复制获取的<code>token</code>到<code>https://www.jwt.io/</code>中看看</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/3d966a6c4c3243ae9e13c6fbfc54fa241916404-20251121234759667-1522173170.png" alt="image-20251104180813029" /><figcaption>image-20251104180813029</figcaption></figure><p></p><p><strong>我们在配置<code>AddJwtBearer</code>需要验证签发者(<code>Issuers</code>)和订阅人(<code>Audience</code>)，<code>token</code>中没有订阅人(<code>aud</code>)</strong></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/afd9918806c84ce7a372ee497799adb81916404-20251121234759871-1995023976.png" alt="image-20251104181038147" /><figcaption>image-20251104181038147</figcaption></figure><p></p><p>知道原因了，就在<code>orders</code>的<code>API</code>服务配置授权范围<code>Scopes</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>new ApiResource("orders", "Orders Service"){</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>Scopes = { "orders" }</span></div></div><div><div><div>3</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/fe37f14a78a84af8a51043840d3860231916404-20251121234800119-1752100440.png" alt="image-20251104181342028" /><figcaption>image-20251104181342028</figcaption></figure><p></p><p>重新启动认证服务(<code>Identity.API</code>)（<strong>有时候需要关闭<code>cmd</code>，重新输入命令启动</strong>），再次测试接口，发现请求状态200</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/b3f8b64229ec47a69eff057394ad28b21916404-20251121234800401-1409426680.png" alt="image-20251104193242480" /><figcaption>image-20251104193242480</figcaption></figure><p></p><p>通过<code>https://www.jwt.io/</code>解密<code>token</code>，发现已经有了<code>aud</code></p><p>以下几个字段是比较重要的字段，需要留意下：</p>

<table><thead><tr><th>字段</th><th>英文全称</th><th>中文解释</th></tr></thead><tbody><tr><td><strong>iss</strong></td><td><em>Issuer</em></td><td>签发者：表示令牌由谁颁发。这里是授权服务器（IdentityServer）的地址，即 <code>"https://localhost:5243"</code>。API 服务会通过它来验证 token 来源是否可信。</td></tr><tr><td><strong>aud</strong></td><td><em>Audience</em></td><td>受众（目标服务）：表示这个令牌是发给哪个 API 的。这里是 <code>"orders"</code>，说明这个 token 只能访问名为 <code>orders</code> 的服务。</td></tr><tr><td><strong>scope</strong></td><td><em>Scopes</em></td><td>授权范围：描述 token 拥有哪些访问权限。这里只有 <code>"orders"</code>，即允许访问订单服务对应的资源。</td></tr><tr><td><strong>client_id</strong></td><td><em>Client Identifier</em></td><td>客户端 ID：标识是谁请求了这个 token。这里是 <code>"orderingswaggerui"</code>，说明是 Swagger UI 这个客户端发起的授权请求。</td></tr><tr><td><strong>sub</strong></td><td><em>Subject</em></td><td>用户唯一标识：表示这个 token 属于哪个用户。通常是用户 ID（GUID）。例如 <code>"473aebe2-7d91-4d99-a4e0-3fcfd0764061"</code>。</td></tr></tbody></table><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>"iss": "https://localhost:5243",</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>"aud": "orders",</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>"scope": [</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>"orders"</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>],</span></div></div><div><div><div>7</div></div><div><span><span> </span></span><span>"client_id": "orderingswaggerui",</span></div></div><div><div><div>8</div></div><div><span><span> </span></span><span>"sub": "473aebe2-7d91-4d99-a4e0-3fcfd0764061"</span></div></div><div><div><div>9</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/dfb043defaed427d988114183f5b19291916404-20251121234800658-57007926.png" alt="image-20251104193342136" /><figcaption>image-20251104193342136</figcaption></figure><p></p><p><strong>有时候没有登录，是因为<code>IdentityServer</code>的<code>Cookie</code>缓存时间较长，可以主动清除<code>Cookie</code>缓存（鼠标右键）</strong></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/b82a271da2b94623ac3217bc4adb2cde1916404-20251121234800912-1542622775.png" alt="image-20251104205558593" /><figcaption>image-20251104205558593</figcaption></figure><p></p><p>但是<code>IdentityServer</code>弹窗没有弹出授权，这就需要我们在配置<code>RequireConsent</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>RequireConsent = true,      // 强制用户在授权页面确认 scope</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>RequirePkce = true,         // 可选，增加安全性，SPA推荐开启</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/1751852daf04434db286cb1ff48ed1771916404-20251121234801173-1783063338.png" alt="image-20251104205747481" /><figcaption>image-20251104205747481</figcaption></figure><p></p><p><strong>清除<code>Cookie</code>缓存（鼠标右键）</strong></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/4081ade4ace54268b4597655dfa2ceea1916404-20251121234801404-790721280.png" alt="image-20251104210006799" /><figcaption>image-20251104210006799</figcaption></figure><p></p><p>重新启动认证服务(<code>Identity.API</code>)，再次<code>Authorize</code>时，输入完用户密码就需要授权<code>Scope</code></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/7cfba287ea334660b97ce113a113d9181916404-20251121234801745-517815676.png" alt="image-20251104210154198" /><figcaption>image-20251104210154198</figcaption></figure><p></p></section><section><h4>3.隐式授权流程(<code>Implicit</code>)<a href="#3隐式授权流程implicit"><span>#</span></a></h4><p>首先查看OpenAPI 规范（Scalar 用）中 OAuth2 安全认证机制的定义：本 API(订单服务) 使用 OAuth2 的隐式授权模式，通过认证服务器 <code>https://localhost:5243</code> 登录获取访问令牌，以访问 <code>orders</code> 资源范围的受保护接口。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/9a4484a48f6c48bca365f9eb3d9395c21916404-20251121234802012-540883357.png" alt="image-20251104194434005" /><figcaption>image-20251104194434005</figcaption></figure><p></p><p><strong>关闭认证服务(<code>Identity.API</code>)，然后再次点击<code>authorize</code>，我们查看<code>Scalar</code>如何请求认证服务(<code>Identity.API</code>)的</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># redirect_uri加密了</span></div></div><div><div><div>2</div></div><div><span>https://localhost:5243/connect/authorize?response_type=token&amp;redirect_uri=http%3A%2F%2Flocalhost%3A5224%2Fscalar%2Fv1&amp;client_id=orderingswaggerui&amp;state=7b7rbpap&amp;scope=orders</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 解密后</span></div></div><div><div><div>5</div></div><div><span>https://localhost:5243/connect/authorize?response_type=token&amp;redirect_uri=http://localhost:5224/scalar/v1&amp;client_id=orderingswaggerui&amp;state=7b7rbpap&amp;scope=orders</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>点击 “<code>Authorize</code>”，<code>Scalar </code>弹出一个授权窗口，引导浏览器跳转到<code>IdentityServer</code>的授权端点</p><p>参数说明：</p>

<table><thead><tr><th>参数</th><th>说明</th></tr></thead><tbody><tr><td><code>response_type=token</code></td><td>表示使用隐式模式（直接要 access_token）</td></tr><tr><td><code>client_id</code></td><td>注册的客户端 ID（例如 orderingswaggerui）</td></tr><tr><td><code>redirect_uri</code></td><td>授权完成后的回调地址（必须与配置匹配）</td></tr><tr><td><code>scope</code></td><td>要申请访问的 API 权限（如 orders）</td></tr><tr><td><code>state</code></td><td>防止 CSRF 攻击的随机值</td></tr></tbody></table><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/91053c0436cb443ab6b987aa0b7712cb1916404-20251121234802230-1800906605.png" alt="image-20251104195921715" /><figcaption>image-20251104195921715</figcaption></figure><p></p><p>重新启动认证服务(<code>Identity.API</code>)，设置<code>Client ID</code>和<code>Scopes</code>，然后点击<code>Authorize</code>，弹出<code>IdentityServer</code>进行登录</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/61d693456da6450c8e11d9ef3335a8731916404-20251121234802499-100749019.png" alt="image-20251104205133235" /><figcaption>image-20251104205133235</figcaption></figure><p></p><p>认证服务(<code>Identity.API</code>)不好调试流程，可以查看日志了解认证授权的流程：没有登录前，<code>User is not authenticated</code>(用户未认证)</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/4279f56c217247d0bdeee812240013931916404-20251121234802789-1774070061.png" alt="image-20251104232753239" /><figcaption>image-20251104232753239</figcaption></figure><p></p><p>登录成功后，跳转到授权页面，显示<code>Showing consent: User has not yet consented</code>(正在显示授权同意页面，因为这个用户还没有同意让这个客户端访问他的信息。)</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/4616dee2c2d544c8966f28d0fa1f286d1916404-20251121234803080-747297845.png" alt="image-20251104232856396" /><figcaption>image-20251104232856396</figcaption></figure><p></p><p>授权完成后，这段日志的意思是：用户（<code>13051f3a-c540-4f64-8048-b141d7a3e026</code>）已授权客户端 <code>orderingswaggerui </code>访问 <code>orders </code>资源，并且记住了授权</p><ul>
<li>
<p><strong>SubjectId</strong>：当前登录用户的唯一标识（数据库里 <code>AspNetUsers</code> 表的 <code>Id</code>）。</p>
</li>
<li>
<p><strong>ClientId</strong>：请求授权的客户端，即 <code>orderingswaggerui</code>（Swagger UI）。</p>
</li>
<li>
<p><strong>RequestedScopes</strong>：客户端请求访问的资源范围，这里是 <code>"orders"</code>。</p>
</li>
<li>
<p><strong>GrantedScopes</strong>：最终同意授权的范围（同上）。</p>
</li>
<li>
<p><strong>ConsentRemembered = true</strong>：表示用户点击了“记住我的授权”，以后不会再弹出“同意授权”页面。</p>
</li>
<li>
<p><strong>EventType = Information</strong>：普通信息事件。</p>
</li>
</ul><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/96415fec45694fe08383e7af272591ec1916404-20251121234803347-1568401277.png" alt="image-20251104233235079" /><figcaption>image-20251104233235079</figcaption></figure><p></p><p>这一段日志的含义：</p><ul>
<li>
<p>客户端（Scalar）在用户同意后，<code>IdentityServer</code>现在调用 <code>/connect/authorize/callback</code> 来处理授权回调。 也就是把用户授权结果重定向（redirect）回客户端。</p>
</li>
<li>
<p><code>IdentityServer </code>需要加载用户的详细信息（例如 Email、用户名、状态等），所以它从数据库查出了这位用户的记录。</p>
</li>
<li>
<p>用户最终同意了访问 <code>orders</code> 范围。</p>
</li>
</ul><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/81d9a2aad4f74f858f3b3835edc786161916404-20251121234803545-974345025.png" alt="image-20251104233732689" /><figcaption>image-20251104233732689</figcaption></figure><p></p><p><code>IdentityServer </code>已成功签发<code>access_token</code>给客户端 <code>orderingswaggerui</code>：</p><ul>
<li><strong>GrantType</strong>：使用的授权模式是 <code>implicit</code>（隐式授权）。</li>
<li><strong>RedirectUri</strong>：授权成功后重定向到客户端（Swagger UI）的回调地址。</li>
<li><strong>Tokens</strong>：生成了一个访问令牌（access_token）。</li>
<li><strong>EventType = Success</strong>：代表令牌签发成功。</li>
</ul><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/8defc7826fe34de49b1bd311558fb3eb1916404-20251121234803841-36835550.png" alt="image-20251104233850653" /><figcaption>image-20251104233850653</figcaption></figure><p></p><p>登录授权成功后，<code>IdentityServer</code>弹窗自动关闭，<code>Scalar</code>获取到<code>token</code></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/37309d258b9e47ffab0fbdab479c970c1916404-20251121234804044-1821930887.png" alt="image-20251104205316588" /><figcaption>image-20251104205316588</figcaption></figure><p></p><p><strong>流程说明</strong></p>

<table><thead><tr><th>步骤</th><th>Implicit Flow</th></tr></thead><tbody><tr><td>1</td><td>用户点击 Authorize</td></tr><tr><td>2</td><td>跳转 IdentityServer 登录</td></tr><tr><td>3</td><td>如果未登录 → 输入用户名/密码</td></tr><tr><td>4</td><td>用户同意授权</td></tr><tr><td>5</td><td>Scalar 获取 token</td></tr><tr><td>6</td><td>使用 token 调用 API</td></tr></tbody></table></section><section><h4>4.配置授权码模式(<code>Authorization Code + PKCE</code>)<a href="#4配置授权码模式authorization-code--pkce"><span>#</span></a></h4><p>隐式模式(<code>Implicit</code>)已经被淘汰了，<code>eShop </code>官方示例用 Implicit，是为了<strong>演示方便</strong>（快速看到授权效果），让 Swagger UI（或浏览器）/Scalar能够直接拿到 Access Token，方便开发和测试。</p><p>在 OAuth 2.1 规范中（2023 年正式发布），<strong>Implicit 模式已被标记为弃用</strong>：</p><ul>
<li>Access Token 暴露在 URL；</li>
<li>无法安全刷新；</li>
<li>浏览器中易被脚本窃取；</li>
<li>无法防止中间人攻击。</li>
</ul><p>所以现代标准中 <strong>强制推荐改用 Authorization Code + PKCE</strong>。</p><p>既然学习，我们也看看授权码模式(<code>Authorization Code + PKCE</code>)，我们就以购物车服务(<code>Basket.API</code>)为例，因为购物车的<code>Scalar</code>也是我们为了学习加上的，购物车服务(<code>Basket.API</code>)因为使用了<code>Grpc</code>，所以只能使用<code>https</code>协议，我们把接口也加上了<code>api</code>版本</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/7cb3a8b22ed24db0a31fb414ebf02e061916404-20251121234804301-747524848.png" alt="image-20251104235344290" /><figcaption>image-20251104235344290</figcaption></figure><p></p><p>先添加以下配置：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>// 授权类型：Authorization Code + PKCE</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>AllowedGrantTypes = GrantTypes.Code,</span></div></div><div><div><div>3</div></div><div><span><span> </span></span><span>// SPA/Scalar 客户端不保存 secret，所以不要求 client_secret</span></div></div><div><div><div>4</div></div><div><span><span> </span></span><span>RequireClientSecret = false,</span></div></div><div><div><div>5</div></div><div><span><span> </span></span><span>// 强制使用 PKCE（安全性必须）</span></div></div><div><div><div>6</div></div><div><span><span> </span></span><span>RequirePkce = true,</span></div></div><div><div><div>7</div></div><div><span><span> </span></span><span>// 是否显示用户同意授权页面</span></div></div><div><div><div>8</div></div><div><span><span> </span></span><span>RequireConsent = true, // 强制每次授权确认</span></div></div><div><div><div>9</div></div><div><span><span> </span></span><span>// token 生命周期和刷新控制（可选）</span></div></div><div><div><div>10</div></div><div><span><span> </span></span><span>AllowOfflineAccess = false, // 如果暂时不需要 refresh token</span></div></div><div><div><div>11</div></div><div><span><span> </span></span><span>// 允许跨域请求的 origin</span></div></div><div><div><div>12</div></div><div><span><span> </span></span><span>AllowedCorsOrigins =</span></div></div><div><div><div>13</div></div><div><span><span> </span></span><span>{</span></div></div><div><div><div>14</div></div><div><span><span>   </span></span><span>"https://localhost:5221"  // Scalar / Swagger UI 所在的域名</span></div></div><div><div><div>15</div></div><div><span><span> </span></span><span>},</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><blockquote><p><strong>为什么授权码模式(<code>Authorization Code + PKCE</code>)会触发跨域？隐式模式(<code>Implicit </code>)不需要（这是我调试过程遇到的问题，我提前记录一下）</strong></p><p>在 <strong>Implicit 流</strong> 下：</p><ul>
<li>浏览器通过 <strong>302 重定向 + URL fragment</strong> 获取 token</li>
<li>不走 JS Ajax，所以不会触发 CORS</li>
</ul><p>在 <strong>Authorization Code + PKCE</strong> 下：</p><ul>
<li>前端 SPA 需要用 JS 通过 <strong>POST <code>/connect/token</code></strong> 来交换 code → access_token</li>
<li>浏览器 JS 发起的是跨域 AJAX 请求</li>
<li>IdentityServer 如果没有允许该 Origin，就报 <code>CorsPolicyService did not allow origin: ...</code></li>
</ul></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/caececc68daf4b2988191e1d016ef2521916404-20251121234804611-881116867.png" alt="image-20251105000220581" /><figcaption>image-20251105000220581</figcaption></figure><p></p><p>然后配置回调地址(<code>RedirectUris</code>)和允许访问的的API范围(<code>AllowedScopes</code>)</p><blockquote><p><strong>为什么需要配置 <code>RedirectUris</code>？</strong></p><ul>
<li>
<p>OAuth2 / OIDC 协议要求每个客户端注册 <strong>回调地址</strong>（redirect_uri）。</p>
</li>
<li>
<p>当用户在 IdentityServer 授权成功后，浏览器会重定向到这个地址，并带上 <strong>code 或 token</strong>。</p>
</li>
<li>
<p><strong>严格匹配</strong>：IdentityServer 会检查请求中的 <code>redirect_uri</code> 是否在客户端注册列表里，否则会报：<code>Invalid redirect_uri</code></p>
</li>
</ul><p><strong>为什么还要配置 <code>openid</code> / <code>profile</code> scopes？</strong></p><p>这些 scope 来自 <strong>OpenID Connect (OIDC)</strong> 协议：</p><ul>
<li><code>openid</code> → 表示这是一个 OIDC 请求（IdentityServer 会返回 id_token）</li>
<li><code>profile</code> → 请求用户信息（如名字、头像等）</li>
</ul><p><strong>区别于普通 API scope</strong>：</p><ul>
<li>API scope（比如 <code>basket</code>）只控制访问后端 API</li>
<li><code>openid/profile</code> 用于获取用户身份信息（JWT 中的 claims）</li>
</ul><p>如果你的前端只需要访问 API，不关心用户信息，可以不用 <code>openid/profile</code>，<code>openid/profile</code> 可以根据需要决定是否保留。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/b30ef79815624dcfafc9d27a4f8ad3891916404-20251121234804899-281025617.png" alt="image-20251105000716645" /><figcaption>image-20251105000716645</figcaption></figure><p></p><p>定义一个名为 <code>"basket"</code> 的受保护 API，并指定访问它需要 <code>"basket"</code> 这个 scope。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/1fd9947765fc43759e028d6a74b568411916404-20251121234805112-987676317.png" alt="image-20251105001310689" /><figcaption>image-20251105001310689</figcaption></figure><p></p><p><code>OAuth2</code>新增授权码模式(<code>Authorization Code + PKCE </code>)</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/9a23539c5a2d4a67b0e8177f5756d2211916404-20251121234805627-372329000.png" alt="image-20251105001538818" /><figcaption>image-20251105001538818</figcaption></figure><p></p><p><code>RequireAuthorization</code>：<strong>给这个 API 分组下的所有端点应用授权策略</strong>，也就是需要用户已经登录或具备某些权限才能访问这些接口。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>var api = vApi.MapGroup("api/Basket").HasApiVersion(1, 0).HasApiVersion(2, 0).RequireAuthorization();</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/4ad1f08ec31940c98b7498bead60b6c21916404-20251121234805996-1087281116.png" alt="image-20251105003204676" /><figcaption>image-20251105003204676</figcaption></figure><p></p><p>如果配置<code>RequireAuthorization()</code>没有<code>token</code>访问接口返回401（无权限）</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/ea7df5d1cfd24161bfc4142e21c5dbc51916404-20251121234806235-361960231.png" alt="image-20251105003342117" /><figcaption>image-20251105003342117</figcaption></figure><p></p><p>所有代码配置完成后，启动购物车服务(<code>Basket.API</code>)，打开<code>Scalar</code>，选择<code>OAuth2</code>，发现多了一种授权方案(<code>Authorization Code</code>)</p><p>跟之前一样配置：<code>Client ID</code>、<code>Use PKCE</code>、<code>Scopes</code></p><blockquote><p><strong>Client Secret 可选</strong></p><ul>
<li>
<p>对于 <strong>SPA 或前端客户端</strong>（比如 Scalar 文档 UI、Swagger UI），<strong>不存储密钥</strong>是推荐做法，因为前端代码无法安全保管 secret。</p>
</li>
<li>
<p>所以在IdentityServer中，你可以配置 <code>RequireClientSecret = false</code>。</p>
</li>
<li>
<p>如果你在 Scalar 上看到 <code>Client Secret: XYZ123</code>，那只是生成的示例，并不是必须的。</p>
</li>
</ul><p><strong>PKCE 强制使用 SHA-256</strong></p><ul>
<li>PKCE（Proof Key for Code Exchange）是 <strong>Authorization Code 流</strong>的增强安全机制，用于前端应用防止授权码被截获。</li>
<li>PKCE 流程里有一个 <code>code_challenge</code>，必须经过 <strong>SHA-256 哈希</strong>（S256）生成，原始的 <code>plain</code> 方法被现代安全标准弃用。</li>
<li>因此 <code>IdentityServer</code> 会要求 <code>code_challenge_method = S256</code>，不能用 plain，否则报错：<code>code_challenge_method of plain is not allowed</code></li>
</ul></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/4aac5c6aa7044731a21b1b0d44bc8b7e1916404-20251121234806442-1878212524.png" alt="image-20251105001926111" /><figcaption>image-20251105001926111</figcaption></figure><p></p><p>输入用户名和密码，然后点击登录</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/a89c879d2f3e4f7e9fb64d3a2f6cbe981916404-20251121234806688-1381909598.png" alt="image-20251105002848800" /><figcaption>image-20251105002848800</figcaption></figure><p></p><p>再点击<code>Yes,Allow</code>(允许授权)</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/8bb5cd81289442788f36ab8d96effebb1916404-20251121234806971-1112094860.png" alt="image-20251105002929930" /><figcaption>image-20251105002929930</figcaption></figure><p></p><p>打开<code>/api/Basket/{customerId}</code>，测试一下，查询正常</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/a64c4ed2853f4a808c8ab97ba8b720e31916404-20251121234807259-407061142.png" alt="image-20251105003038439" /><figcaption>image-20251105003038439</figcaption></figure><p></p></section><section><h4>5.授权码模式流程(<code>Authorization Code + PKCE</code>)<a href="#5授权码模式流程authorization-code--pkce"><span>#</span></a></h4><p>在查看 OpenAPI 规范文档时，我们为 <code>oauth2</code> 安全方案配置了两种授权模式：<strong>Implicit</strong> 和 <strong>Authorization Code</strong>，分别对应浏览器直接获取 token 和通过授权码交换 token 的安全流程，并指定了 <code>basket</code> API 的访问范围。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://localhost:5221/openapi/v1.json</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/1510b3e7b40a4abcb1d73ec2e3f95f5a1916404-20251121234807459-1256923923.png" alt="image-20251105004034522" /><figcaption>image-20251105004034522</figcaption></figure><p></p><p>先关闭认证服务(<code>Identity.API</code>)，然后设置<code>Client ID</code>、<code>Use PKCE</code>、<code>Scopes</code>，点击<code>Authorize</code></p><p>查看<code>Scalar</code>发起的授权请求：</p><ul>
<li><code>response_type=code</code>：授权码模式。</li>
<li><code>scope</code>：请求访问的范围。</li>
<li><code>code_challenge</code> &amp; <code>code_challenge_method</code>：PKCE，客户端生成随机字符串和散列，服务器用来校验。</li>
<li><code>redirect_uri</code>：授权成功后回调地址。</li>
<li><code>state</code>：防 CSRF，同时保持请求上下文</li>
<li><code>client_id</code>：当前客户端的唯一标识</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 原请求</span></div></div><div><div><div>2</div></div><div><span>https://localhost:5243/connect/authorize?response_type=code&amp;code_challenge=3_V716AyAbS7uKOkhK6jDTW7Ho8As2_zq6EOBA_i7jQ&amp;code_challenge_method=S256&amp;redirect_uri=https%3A%2F%2Flocalhost%3A5221%2Fscalar%2Fv1&amp;client_id=basketswaggerui&amp;state=78jzgb2i&amp;scope=basket</span></div></div><div><div><div>3</div></div><div><span># 解码后 redirect_uri加密了</span></div></div><div><div><div>4</div></div><div><span>https://localhost:5243/connect/authorize?</span></div></div><div><div><div>5</div></div><div><span>response_type=code&amp;</span></div></div><div><div><div>6</div></div><div><span>code_challenge=3_V716AyAbS7uKOkhK6jDTW7Ho8As2_zq6EOBA_i7jQ&amp;</span></div></div><div><div><div>7</div></div><div><span>code_challenge_method=S256&amp;</span></div></div><div><div><div>8</div></div><div><span>redirect_uri=https://localhost:5221/scalar/v1&amp;</span></div></div><div><div><div>9</div></div><div><span>client_id=basketswaggerui&amp;</span></div></div><div><div><div>10</div></div><div><span>state=78jzgb2i&amp;</span></div></div><div><div><div>11</div></div><div><span>scope=basket</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/b6b6d8aca4b1444d8b8d38c879cf579e1916404-20251121234807654-515344124.png" alt="image-20251105004502293" /><figcaption>image-20251105004502293</figcaption></figure><p></p><p>启动认证服务(<code>Identity.API</code>)和购物车服务(<code>Basket.API</code>)，设置<code>Client ID</code>、<code>Use PKCE</code>、<code>Scopes</code>，点击<code>Authorize</code></p><p>没登录前：<code>Showing login: User is not authenticated</code>（显示登录页，用户没有认证）</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/17d2895d90974ad28ee1fc9e8890d0af1916404-20251121234807931-905584629.png" alt="image-20251105005336634" /><figcaption>image-20251105005336634</figcaption></figure><p></p><p>登陆成功后：<code>Showing consent: User has not yet consented</code>（显示授权：用户未授权）</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/1cc4feee460645629d715182e0bb25b01916404-20251121234808378-1378483916.png" alt="image-20251105005723209" /><figcaption>image-20251105005723209</figcaption></figure><p></p><p>登录&amp;授权后：<code>Scalar</code>发送 POST 请求到 Token 端点</p><ul>
<li><code>client_id</code>：客户端唯一标识</li>
<li><code>redirect_uri</code>：回调地址，必须匹配注册信息</li>
<li><code>code</code>：授权码，用于换取 Access Token</li>
<li><code>grant_type</code>：授权模式，这里是授权码模式(<code>authorization_code</code>)</li>
<li><code>code_verifier</code>：PKCE 验证码，保证授权码安全</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>POST https://localhost:5243/connect/token</span></div></div><div><div><div>2</div></div><div><span>client_id=basketswaggerui&amp;</span></div></div><div><div><div>3</div></div><div><span>redirect_uri=https%3A%2F%2Flocalhost%3A5221%2Fscalar%2Fv1&amp;</span></div></div><div><div><div>4</div></div><div><span>code=32BAD9BF9537F37C142CAC44066BFC80F5A81DDBB61B74E06445FA61881D0A85-1&amp;</span></div></div><div><div><div>5</div></div><div><span>grant_type=authorization_code&amp;</span></div></div><div><div><div>6</div></div><div><span>code_verifier=5JddRWZjBe72ixVPwZMxIQblPyhe_MivmcNUQFa2LEI</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p><strong>为什么授权码模式(<code>Authorization Code + PKCE</code>)会触发跨域？隐式模式(<code>Implicit </code>)不需要（这是我调试过程遇到的问题，我提前记录一下）</strong></p><p>上面记录了这个问题，就是因为<code>Scalar</code>客户端发起了<code>Ajax</code>请求获取<code>token</code>，所以认证服务(<code>Identity.API</code>)需要配置<code>AllowedCorsOrigins</code></p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/9dcfc66e84684833af933f6d3457fe7c1916404-20251121234808652-498560479.png" alt="image-20251105005842494" /><figcaption>image-20251105005842494</figcaption></figure><p></p><p><code>Scalar</code>设置<code>Access Token</code>，所有<code>api</code>调用就可以使用这个<code>Access Token</code></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/e5538b713eb14b3bac3a4a1065dfd0ba1916404-20251121234808988-1265552817.png" alt="image-20251105010600233" /><figcaption>image-20251105010600233</figcaption></figure><p></p><p><code>SPA/Scalar </code>通常不使用 Refresh Token，是因为浏览器无法安全存储长期凭证，短期 Access Token + PKCE 重新授权比使用 Refresh Token 更安全。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/8e16af2eee0848be82eb065895dc9d281916404-20251121234809273-329327830.png" alt="image-20251105010745695" /><figcaption>image-20251105010745695</figcaption></figure><p></p><p><strong>流程说明</strong></p>

<table><thead><tr><th>步骤</th><th>Authorization Code + PKCE Flow</th></tr></thead><tbody><tr><td>1</td><td>用户点击 Authorize</td></tr><tr><td>2</td><td>跳转 IdentityServer 登录</td></tr><tr><td>3</td><td>如果未登录 → 输入用户名/密码</td></tr><tr><td>4</td><td>用户同意授权</td></tr><tr><td>5</td><td>IdentityServer 重定向回客户端（带 <strong>授权码 code</strong>）</td></tr><tr><td>6</td><td>客户端使用 <strong>code + code_verifier</strong> 向 IdentityServer Token Endpoint 交换 <strong>Access Token</strong></td></tr><tr><td>7</td><td>IdentityServer 返回 Access Token（可选 ID Token）</td></tr><tr><td>8</td><td>客户端使用 Access Token 调用受保护 API</td></tr></tbody></table></section></section><section><h2>3.9配置请求<code>Header</code>中<code>requestid</code><a href="#39配置请求header中requestid"><span>#</span></a></h2><p>订单服务(<code>Ordering.API</code>)作为核心服务，对于一些比较重要的命令请求时必须在<code>Header</code>中加上<code>x-requestid</code>，用于保证<strong>相同 x-requestid 的请求只执行一次</strong>。</p><p>我们需要在<code>Scalar</code>文档上给<code>x-requestid</code>加上默认值，这个需求是我为了方便自己加上的，和<code>eshop</code>无关</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/4c1add89e8fb4b34932cd103c03a6a211916404-20251121234809528-164506515.png" alt="image-20251105181131529" /><figcaption>image-20251105181131529</figcaption></figure><p></p><p>获取<code>Header</code>的<code>x-requestid</code>，然后赋值<code>Guid.NewGuid().ToString()</code></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/179c1d30e1094cd2b388bff490be18471916404-20251121234809822-1440821451.png" alt="image-20251105181538864" /><figcaption>image-20251105181538864</figcaption></figure><p></p><p><code>Scalar</code>中的<code>x-requestid</code>有了默认值，但是这个只是在<code>OpenAPI </code>文档生成的时候设置的默认值，没法在每次请求的时候自动设置<code>x-requestid</code>默认值</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/dc4a7ab13dd84757b3f25825e34f958b1916404-20251121234810168-1459169364.png" alt="image-20251105181716338" /><figcaption>image-20251105181716338</figcaption></figure><p></p></section><section><h2>3.10启用<code>OpenAPI</code>/<code>Scalar</code><a href="#310启用openapiscalar"><span>#</span></a></h2><p>在 <strong>开发环境下</strong>自动启用 <strong>Swagger/OpenAPI 文档</strong>，并提供 <strong>Scalar 可视化文档</strong>，同时把根路径 <code>/</code> 指向 Scalar 文档首页。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/b709dd9114ba45a7a8cc40118817c06d1916404-20251121234810526-1631333201.png" alt="image-20251105011502960" /><figcaption>image-20251105011502960</figcaption></figure><p></p><p>📌 创作不易，感谢支持！</p><p>每一篇内容都凝聚了心血与热情，如果我的内容对您有帮助，欢迎请我喝杯咖啡☕，您的支持是我持续分享的最大动力！</p><p>💬 加入交流群（QQ群）：<strong>576434538</strong></p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%A8%B1%E4%B9%90/iptv-intro/</id>
      <title type="text">NAS闲置？TVBox无源？这个120K+星项目，一个链接拯救你的电视体验</title>
      <published>2026-06-17T00:00:00.000Z</published>
      <updated>2026-06-17T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%A8%B1%E4%B9%90/iptv-intro/"/>
      <summary type="text">120K+星标的开源项目，汇聚全球免费直播源，支持央视、卫视、境外频道，一个链接搞定所有电视直播！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！看电视怎么这么难？<a href="#朋友们看电视怎么这么难"><span>#</span></a></h2><p>你是不是每天都要面对这些困扰：</p><ul>
<li><strong>家庭电视高清要会员</strong>：想看高清直播？对不起，先充个会员吧！央视、卫视、体育频道……每个都要单独付费，一个月下来好几百块</li>
<li><strong>有NAS却无有效源</strong>：花大价钱买了NAS，想搭建家庭媒体中心，结果到处找IPTV源，不是失效就是卡顿，根本用不起来</li>
<li><strong>TVBox等软件无有效源</strong>：安装了TVBox、Kodi这些播放器，结果源地址三天两头失效，好不容易找到的源，过几天就404了</li>
<li><strong>无法随时随地看电视</strong>：家里有电视，出门想看怎么办？手机、平板、电脑……每个设备都要重新配置，太麻烦了</li>
</ul><p>今天我要给大家分享一个 GitHub 上的宝藏项目——<strong>IPTV-ORG</strong>！这个项目汇聚了全球 12000+ 免费电视频道，央视、卫视、BBC、CNN、NHK……一个链接全部搞定！</p></section>
<section><h2>✨ 什么是 IPTV-ORG？<a href="#-什么是-iptv-org"><span>#</span></a></h2><p>IPTV-ORG 是一个由全球志愿者共同维护的<strong>免费 IPTV 直播源集合</strong>。它不提供视频内容，而是收集整理了全球各地公开可用的电视直播源，以 M3U 播放列表的形式提供给大家。</p><p><strong>核心特点</strong>：</p><ul>
<li>📺 <strong>12000+ 频道</strong>：覆盖全球 220+ 国家和地区</li>
<li>🌐 <strong>190+ 语言</strong>：支持中文、英文、日语、韩语等多种语言</li>
<li>🆓 <strong>完全免费</strong>：无需注册、无需付费、无广告</li>
<li>🔄 <strong>社区维护</strong>：志愿者持续更新，每天自动检测</li>
<li>📱 <strong>跨平台</strong>：支持电脑、手机、电视盒子等所有设备
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/87b8fc0366c14fb69cc2b064c1aa156d20260617170848908.png" alt="" /></li>
</ul></section>
<section><h2>🎯 频道分类<a href="#-频道分类"><span>#</span></a></h2><section><h3>按地区分类<a href="#按地区分类"><span>#</span></a></h3>

<table><thead><tr><th>地区</th><th>频道数量</th><th>代表频道</th></tr></thead><tbody><tr><td><strong>中国大陆</strong></td><td>800+</td><td>央视全系列、各大卫视、地方台</td></tr><tr><td><strong>中国港澳台</strong></td><td>100+</td><td>香港TVB、台湾中天、澳门澳视</td></tr><tr><td><strong>美国</strong></td><td>700+</td><td>CNN、BBC America、ESPN、HBO</td></tr><tr><td><strong>英国</strong></td><td>200+</td><td>BBC全系列、ITV、Channel 4</td></tr><tr><td><strong>日本</strong></td><td>150+</td><td>NHK、富士电视台、东京电视台</td></tr><tr><td><strong>韩国</strong></td><td>100+</td><td>KBS、SBS、MBC</td></tr><tr><td><strong>其他地区</strong></td><td>8000+</td><td>全球各国本地频道</td></tr></tbody></table></section><section><h3>按类型分类<a href="#按类型分类"><span>#</span></a></h3>

<table><thead><tr><th>类型</th><th>频道数量</th><th>说明</th></tr></thead><tbody><tr><td><strong>新闻</strong></td><td>215</td><td>全球新闻频道</td></tr><tr><td><strong>体育</strong></td><td>110</td><td>ESPN、FOX Sports 等</td></tr><tr><td><strong>电影</strong></td><td>50</td><td>电影频道</td></tr><tr><td><strong>音乐</strong></td><td>133</td><td>MTV、音乐台</td></tr><tr><td><strong>儿童</strong></td><td>42</td><td>卡通频道、少儿节目</td></tr><tr><td><strong>纪录片</strong></td><td>10</td><td>Discovery、国家地理</td></tr><tr><td><strong>娱乐</strong></td><td>59</td><td>综艺节目、真人秀</td></tr><tr><td><strong>宗教</strong></td><td>177</td><td>宗教频道</td></tr></tbody></table></section></section>
<section><h2>🚀 使用方法<a href="#-使用方法"><span>#</span></a></h2><section><h3>第一步：获取播放列表<a href="#第一步获取播放列表"><span>#</span></a></h3><p>项目提供了多种播放列表，您可以根据需求选择：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 全部频道（推荐）</span></div></div><div><div><div>2</div></div><div><span>https://iptv-org.github.io/iptv/index.m3u</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 按国家分类</span></div></div><div><div><div>5</div></div><div><span>https://iptv-org.github.io/iptv/index.country.m3u</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 按语言分类</span></div></div><div><div><div>8</div></div><div><span>https://iptv-org.github.io/iptv/index.language.m3u</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 按类型分类</span></div></div><div><div><div>11</div></div><div><span>https://iptv-org.github.io/iptv/index.category.m3u</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># 仅中国大陆频道</span></div></div><div><div><div>14</div></div><div><span>https://iptv-org.github.io/iptv/countries/cn.m3u</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span># 仅新闻频道</span></div></div><div><div><div>17</div></div><div><span>https://iptv-org.github.io/iptv/categories/news.m3u</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>第二步：选择播放器<a href="#第二步选择播放器"><span>#</span></a></h3>

<table><thead><tr><th>平台</th><th>推荐播放器</th><th>特点</th></tr></thead><tbody><tr><td><strong>Windows</strong></td><td>PotPlayer / VLC</td><td>功能强大，支持格式多</td></tr><tr><td><strong>macOS</strong></td><td>IINA / VLC</td><td>界面美观，性能优秀</td></tr><tr><td><strong>Linux</strong></td><td>VLC</td><td>开源免费，全平台支持</td></tr><tr><td><strong>Android</strong></td><td>nPlayer / VLC</td><td>手机端体验好</td></tr><tr><td><strong>iOS</strong></td><td>nPlayer</td><td>支持网络串流</td></tr><tr><td><strong>电视盒子</strong></td><td>Kodi / TiviMate</td><td>机顶盒专用</td></tr></tbody></table></section><section><h3>第三步：配置播放列表<a href="#第三步配置播放列表"><span>#</span></a></h3><p>以 <strong>VLC</strong> 为例：</p><ol>
<li>打开 VLC 播放器</li>
<li>点击菜单：<code>媒体</code> → <code>打开网络串流</code>（快捷键：Ctrl+N）</li>
<li>粘贴播放列表 URL</li>
<li>点击 <code>播放</code>，等待加载频道列表</li>
<li>在左侧播放列表中选择频道观看</li>
</ol><p>以 <strong>Kodi</strong> 为例：</p><ol>
<li>安装 <code>PVR IPTV Simple Client</code> 插件</li>
<li>打开插件配置</li>
<li>选择 <code>M3U Play List URL</code></li>
<li>输入播放列表地址</li>
<li>重启 Kodi，即可在电视菜单中看到频道</li>
</ol></section><section><h3>优点<a href="#优点"><span>#</span></a></h3><ol>
<li><strong>频道丰富</strong>：央视 1-17 套全齐，各大卫视秒开，港澳台频道也能看</li>
<li><strong>完全免费</strong>：没有广告、没有弹窗、没有开屏等待</li>
<li><strong>跨平台</strong>：同一个链接，电脑、手机、电视盒子都能用</li>
<li><strong>社区活跃</strong>：每天自动检测失效源，持续更新</li>
</ol></section><section><h3>缺点<a href="#缺点"><span>#</span></a></h3><ol>
<li><strong>稳定性一般</strong>：部分频道会失效，尤其是境外频道</li>
<li><strong>画质参差不齐</strong>：有的 1080p，有的只有 480p</li>
<li><strong>部分境外频道有地域限制</strong>：需要 VPN 才能观看</li>
</ol></section></section>
<section><h2>⚠️ 重要提醒<a href="#️-重要提醒"><span>#</span></a></h2><section><h3>关于版权<a href="#关于版权"><span>#</span></a></h3><ul>
<li>项目收录的都是<strong>公开可用的免费频道</strong>，不涉及盗版内容</li>
<li>请尊重版权，对于需要付费的内容（如体育赛事、付费电影），建议支持正版</li>
<li>使用前请确认当地法律法规</li>
</ul></section><section><h3>安全建议<a href="#安全建议"><span>#</span></a></h3><ul>
<li>只使用官方提供的播放列表链接，不要下载不明来源的文件</li>
<li>建议使用正规播放器，避免安装盗版软件</li>
<li>境外频道可能需要 VPN，选择可靠的 VPN 服务</li>
</ul></section></section>
<section><h2>📝 使用技巧<a href="#-使用技巧"><span>#</span></a></h2><section><h3>技巧一：使用精简版列表<a href="#技巧一使用精简版列表"><span>#</span></a></h3><p>如果觉得全量列表太大，可以使用分类列表：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 仅看新闻</span></div></div><div><div><div>2</div></div><div><span>https://iptv-org.github.io/iptv/categories/news.m3u</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 仅看体育</span></div></div><div><div><div>5</div></div><div><span>https://iptv-org.github.io/iptv/categories/sport.m3u</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 仅看儿童频道</span></div></div><div><div><div>8</div></div><div><span>https://iptv-org.github.io/iptv/categories/kids.m3u</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>技巧二：本地缓存播放列表<a href="#技巧二本地缓存播放列表"><span>#</span></a></h3><p>将 M3U 文件下载到本地，避免每次都从网络加载：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Windows</span></div></div><div><div><div>2</div></div><div><span><span>curl </span><span>-</span><span>o iptv.m3u https:</span><span>//</span><span>iptv</span><span>-</span><span>org.github.io</span><span>/</span><span>iptv</span><span>/</span><span>index.m3u</span></span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># macOS/Linux</span></div></div><div><div><div>5</div></div><div><span><span>wget https:</span><span>//</span><span>iptv</span><span>-</span><span>org.github.io</span><span>/</span><span>iptv</span><span>/</span><span>index.m3u</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>技巧三：自定义播放列表<a href="#技巧三自定义播放列表"><span>#</span></a></h3><p>如果官方列表中有不喜欢的频道，可以下载后手动编辑 M3U 文件，删除不需要的频道。</p></section></section>
<section><h2>📝 总结<a href="#-总结"><span>#</span></a></h2><p>IPTV-ORG 是一个非常棒的开源项目，它让我们可以免费观看全球数千个电视频道。虽然稳定性和画质不如付费方案，但胜在完全免费、频道丰富、跨平台支持。如果你不想为电视会员花钱，或者想看看境外频道，这个项目绝对值得一试！</p></section>
<section><h2>🌟 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub 地址</strong>: <a href="https://github.com/iptv-org/iptv" target="_blank">https://github.com/iptv-org/iptv</a></p><p><strong>官方网站</strong>: <a href="https://iptv-org.github.io/iptv/" target="_blank">https://iptv-org.github.io/iptv/</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p></section>
<section><h2>🎉 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你平时用什么看直播？最想看什么频道？欢迎在评论区和我交流分享！</p><p>我会定期分享更多好用的工具，记得关注我哦！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/ai/intelligent-terminal-intro/</id>
      <title type="text">Microsoft 放大招！Intelligent Terminal 来了：AI 加持的命令行神器</title>
      <published>2026-06-16T00:00:00.000Z</published>
      <updated>2026-06-16T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/ai/intelligent-terminal-intro/"/>
      <summary type="text">微软在 Build 2026 发布的 Intelligent Terminal，将 AI 代理引入命令行，支持 Copilot、Claude、Gemini，完全开源免费！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！命令行也要被 AI 占领了？<a href="#朋友们命令行也要被-ai-占领了"><span>#</span></a></h2><p>作为开发者，每天都要和终端打交道。写脚本、跑构建、部署应用…命令行是我们最常用的工具之一。但是，你有没有遇到过这些困扰：</p><ul>
<li>记不住复杂的命令参数？</li>
<li>命令执行出错不知道怎么修复？</li>
<li>想要自动化一些重复操作却不会写脚本？</li>
<li>在多个命令之间切换时上下文丢失？</li>
</ul><p>就在最近的 <strong>Microsoft Build 2026</strong> 大会上，微软发布了一个重磅项目——<strong>Intelligent Terminal</strong>！这是一款集成了 AI 代理的智能终端，让你的命令行体验彻底升级！今天就来给大家详细介绍这个神器！</p></section>
<section><h2>✨ 什么是 Intelligent Terminal？<a href="#-什么是-intelligent-terminal"><span>#</span></a></h2><p>Intelligent Terminal 是 <strong>Windows Terminal 的开源分支</strong>，由微软官方推出。它在保留 Windows Terminal 所有功能的基础上，引入了原生 AI 代理集成，让开发者可以在命令行中获得 AI 助手的帮助。</p><p><strong>核心特点</strong>：</p><ul>
<li>🔧 <strong>完全独立</strong>：不替换现有 Windows Terminal，作为独立应用安装</li>
<li>🤖 <strong>AI 代理集成</strong>：原生支持多个 AI 服务提供商</li>
<li>🔒 <strong>隐私优先</strong>：所有 AI 功能严格可选（Opt-in），终端本身不做云端调用</li>
<li>📖 <strong>开源免费</strong>：MIT 许可证，代码完全开放</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/d10d917a162d425dacf599de1c218b1020260616163328985.png" alt="" /></p></section>
<section><h2>🎯 核心功能<a href="#-核心功能"><span>#</span></a></h2><section><h3>1. AI 代理面板<a href="#1-ai-代理面板"><span>#</span></a></h3><p>按下 <code>Ctrl+Shift+.</code> 即可打开 AI 代理面板，直接在终端中与 AI 助手对话：</p><ul>
<li><strong>命令解释</strong>：输入命令，AI 帮你解释每个参数的含义</li>
<li><strong>错误诊断</strong>：命令执行失败时，AI 自动分析错误并给出修复建议</li>
<li><strong>脚本生成</strong>：描述你想做的事情，AI 帮你生成对应的命令或脚本</li>
<li><strong>上下文感知</strong>：AI 可以看到当前终端的上下文和历史记录</li>
</ul></section><section><h3>2. 多 AI 提供商支持<a href="#2-多-ai-提供商支持"><span>#</span></a></h3><p>Intelligent Terminal 支持多种 AI 服务提供商，通过 Agent Client Protocol 通信：</p>

<table><thead><tr><th>AI 提供商</th><th>状态</th></tr></thead><tbody><tr><td><strong>GitHub Copilot</strong></td><td>默认支持</td></tr><tr><td><strong>Claude Code</strong></td><td>✅ 支持</td></tr><tr><td><strong>OpenAI Codex</strong></td><td>✅ 支持</td></tr><tr><td><strong>Google Gemini</strong></td><td>✅ 支持</td></tr></tbody></table><p>终端会自动检测你已安装的 AI 代理，无需手动配置。</p></section><section><h3>3. 智能错误检测<a href="#3-智能错误检测"><span>#</span></a></h3><p>当命令执行失败时，终端会自动检测错误，并提供一键加载上下文的功能，让 AI 代理能够看到刚刚发生的错误并给出针对性的解决方案。</p></section><section><h3>4. 后台任务支持<a href="#4-后台任务支持"><span>#</span></a></h3><p>AI 代理可以在后台标签页中执行长时间任务，比如构建项目、运行测试等，而你可以在其他标签页继续工作，互不干扰。</p></section><section><h3>5. 插件生态系统<a href="#5-插件生态系统"><span>#</span></a></h3><p>Intelligent Terminal 支持插件扩展，开发者可以编写自定义 AI 代理或工具，扩展终端的功能。</p></section></section>
<section><h2>🔧 技术架构<a href="#-技术架构"><span>#</span></a></h2><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>┌─────────────────────────────────────────────────────────────┐</span></div></div><div><div><div>2</div></div><div><span>│                   Intelligent Terminal                       │</span></div></div><div><div><div>3</div></div><div><span>├─────────────────────────────────────────────────────────────┤</span></div></div><div><div><div>4</div></div><div><span>│  ┌──────────────┐    ┌──────────────────────┐              │</span></div></div><div><div><div>5</div></div><div><span>│  │   Terminal   │    │    AI Agent Panel    │              │</span></div></div><div><div><div>6</div></div><div><span>│  │  (核心界面)   │    │    (Ctrl+Shift+.)   │              │</span></div></div><div><div><div>7</div></div><div><span>│  └──────┬───────┘    └──────────┬───────────┘              │</span></div></div><div><div><div>8</div></div><div><span>│         │                       │                          │</span></div></div><div><div><div>9</div></div><div><span>│         └───────────┬───────────┘                          │</span></div></div><div><div><div>10</div></div><div><span>│                     ▼                                      │</span></div></div><div><div><div>11</div></div><div><span>│         ┌──────────────────────┐                           │</span></div></div><div><div><div>12</div></div><div><span>│         │   Agent Client       │                           │</span></div></div><div><div><div>13</div></div><div><span>│         │    Protocol          │                           │</span></div></div><div><div><div>14</div></div><div><span>│         │   (JSON-RPC 2.0)     │                           │</span></div></div><div><div><div>15</div></div><div><span>│         └──────────┬───────────┘                           │</span></div></div><div><div><div>16</div></div><div><span>│                    │                                       │</span></div></div><div><div><div>17</div></div><div><span>│     ┌──────────────┼──────────────┐                        │</span></div></div><div><div><div>18</div></div><div><span>│     ▼              ▼              ▼                        │</span></div></div><div><div><div>19</div></div><div><span>│ ┌─────────┐   ┌─────────┐   ┌─────────┐                    │</span></div></div><div><div><div>20</div></div><div><span>│ │Copilot  │   │Claude   │   │Gemini   │                    │</span></div></div><div><div><div>21</div></div><div><span>│ │  CLI    │   │  Code   │   │         │                    │</span></div></div><div><div><div>22</div></div><div><span>│ └─────────┘   └─────────┘   └─────────┘                    │</span></div></div><div><div><div>23</div></div><div><span>└─────────────────────────────────────────────────────────────┘</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p><strong>关键技术点</strong>：</p><ul>
<li>使用 <strong>Agent Client Protocol</strong> 进行通信</li>
<li>通过 <strong>JSON-RPC 2.0</strong> 协议与 AI 代理交互</li>
<li>终端本身<strong>不做云端调用</strong>，所有数据由用户选择的 AI 代理处理</li>
<li>支持超过 <strong>25 种</strong>兼容协议的 AI 代理</li>
</ul></section>
<section><h2>🚀 安装教程<a href="#-安装教程"><span>#</span></a></h2><section><h3>方法一：Microsoft Store（推荐）<a href="#方法一microsoft-store推荐"><span>#</span></a></h3><ol>
<li>打开 Microsoft Store</li>
<li>搜索 “Intelligent Terminal”</li>
<li>点击安装
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/9bd79200fa334f038d7311ace3046dce20260616163438811.png" alt="" /></li>
</ol></section><section><h3>方法二：winget<a href="#方法二winget"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>winget install Microsoft.IntelligentTerminal</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>方法三：GitHub 下载<a href="#方法三github-下载"><span>#</span></a></h3><ol>
<li>访问 GitHub 发布页：<a href="https://github.com/microsoft/intelligent-terminal/releases" target="_blank">https://github.com/microsoft/intelligent-terminal/releases</a></li>
<li>下载最新版本的安装包</li>
<li>运行安装程序
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/c98d7ed2f0204e1393252fccc16b980c20260616163520054.png" alt="" /></li>
</ol></section><section><h3>系统要求<a href="#系统要求"><span>#</span></a></h3><ul>
<li>Windows 11 build 22621.6060 或更高版本</li>
<li>需要 AI 服务提供商订阅（GitHub Copilot、Azure OpenAI、OpenAI 等）</li>
</ul></section></section>
<section><h2>📝 使用指南<a href="#-使用指南"><span>#</span></a></h2><section><h3>快速开始<a href="#快速开始"><span>#</span></a></h3><ol>
<li>打开 Intelligent Terminal</li>
<li>按下 <code>Ctrl+Shift+.</code> 打开 AI 代理面板</li>
<li>输入你的问题，比如：“帮我写一个 git commit 命令”</li>
<li>AI 会给出相应的命令建议</li>
</ol></section><section><h3>实际场景演示<a href="#实际场景演示"><span>#</span></a></h3><section><h4>场景一：命令解释<a href="#场景一命令解释"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 输入</span></div></div><div><div><div>2</div></div><div><span><span>解释一下 git push </span><span>--</span><span>force 的作用</span></span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># AI 回答</span></div></div><div><div><div>5</div></div><div><span><span>git push </span><span>--</span><span>force 用于强制推送本地分支到远程仓库，会覆盖远程分支的历史记录。</span></span></div></div><div><div><div>6</div></div><div><span>⚠️ 警告：此命令可能会导致远程分支的数据丢失，请谨慎使用。</span></div></div><div><div><div>7</div></div><div><span><span>推荐使用 git push </span><span>--</span><span>force</span><span>-</span><span>with</span><span>-</span><span>lease 替代，它会先检查远程分支是否有新的提交。</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>场景二：错误诊断<a href="#场景二错误诊断"><span>#</span></a></h4><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 执行失败的命令</span></div></div><div><div><div>2</div></div><div><span>dotnet build</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># AI 自动检测到错误并给出建议</span></div></div><div><div><div>5</div></div><div><span>Copilot v1.</span><span>0.55</span><span>-</span><span>7</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span><span>&gt; Auto</span><span>-</span><span>diagnosed a recent command failure</span></span></div></div><div><div><div>8</div></div><div><span>[</span><span>Viewing</span><span> ...</span><span>rs</span><span>\</span><span>mousma</span><span>\</span><span>Documents</span><span>\</span><span>ContosoApp</span><span>\</span><span>MainPage.xaml.cs</span><span>] Completed</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>Suggested </span><span>1</span><span> option:</span></div></div><div><div><div>11</div></div><div><span>√ </span><span>1</span><span>. Run: (</span><span>Get-Content</span><span><span> C:\Users\mousma\Documents\ContosoApp\MainPage.xaml.cs) </span><span>-replace</span><span> </span></span><span>'this\.UpdateLayout\(\)$'</span><span>, </span><span>'this.UpdateLayout();'</span><span> | </span><span>Set-Content</span><span> C:\Users\mousma\Documents\ContosoApp\MainPage.xaml.cs</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>命令文本：</span></div></div><div><div><div>14</div></div><div><span>(</span><span>Get-Content</span><span><span> C:\Users\mousma\Documents\ContosoApp\MainPage.xaml.cs) </span><span>-replace</span><span> </span></span><span>'this\.UpdateLayout\(\)$'</span><span>, </span><span>'this.UpdateLayout();'</span><span> | </span><span>Set-Content</span><span> C:\Users\mousma\Documents\ContosoApp\MainPage.xaml.cs</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span>[ </span><span>Run</span><span> </span><span>command</span><span> ]  Insert </span><span>in</span><span> Terminal</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>快捷键提示：</span></div></div><div><div><div>19</div></div><div><span><span>(Ctrl</span><span>+</span><span>Shift</span><span>+</span><span>. to show</span><span>/</span><span>hide agent pane • Ctrl</span><span>+</span><span>Shift</span><span>+/</span><span> to show</span><span>/</span><span>hide agent session)</span></span></div></div><div><div><div>20</div></div><div><span>(↑ ↓ to navigate suggestions • ← → to </span><span>switch</span><span> actions • Enter to select • Esc to cancel)</span></div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span>输入框提示：</span></div></div><div><div><div>23</div></div><div><span><span>&gt; Ask anything, </span><span>/</span><span> </span></span><span>for</span><span> commands..</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/a75e9f7d2c874fd491d12f6db7f7885b20260616163736855.png" alt="" /></p></section><section><h4>场景三：脚本生成<a href="#场景三脚本生成"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 输入</span></div></div><div><div><div>2</div></div><div><span>帮我生成一个脚本，统计当前目录下的文件数量</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># AI 生成脚本</span></div></div><div><div><div>5</div></div><div><span>Get-ChildItem</span><span><span> </span><span>-</span><span>Path . </span><span>-</span><span>File | </span></span><span>Measure-Object</span><span> | </span><span>Select-Object</span><span><span> </span><span>-</span><span>ExpandProperty Count</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h3>配置 AI 服务提供商<a href="#配置-ai-服务提供商"><span>#</span></a></h3><ol>
<li>打开终端设置（<code>Ctrl+,</code>）</li>
<li>选择 “AI Agent” 选项卡</li>
<li>选择你想要使用的 AI 服务提供商</li>
<li>按照提示进行身份验证或配置</li>
</ol></section></section>
<section><h2>📝 总结<a href="#-总结"><span>#</span></a></h2><p>Microsoft Intelligent Terminal 是微软在 AI 时代对命令行工具的一次重要升级。它通过开放协议和可选 AI 集成的方式，既满足了开发者对 AI 辅助的需求，又保证了隐私和控制。支持多 AI 提供商、智能错误检测、后台任务等功能，让命令行工作更加高效。如果你是 Windows 用户，想要体验 AI 加持的终端，不妨试试这个工具！</p></section>
<section><h2>🌟 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub 地址</strong>: <a href="https://github.com/microsoft/intelligent-terminal" target="_blank">https://github.com/microsoft/intelligent-terminal</a></p><p><strong>官方文档</strong>: <a href="https://learn.microsoft.com/zh-cn/windows/terminal/" target="_blank">https://learn.microsoft.com/zh-cn/windows/terminal/</a></p><p><strong>最新版本</strong>: v0.1</p><p><strong>开源协议</strong>: MIT License</p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p></section>
<section><h2>🎉 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你平时使用什么终端工具？最期待 AI 终端带来什么功能？欢迎在评论区和我交流分享！</p><p>我会定期分享更多好用的开发工具，记得关注我哦！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E7%B3%BB%E7%BB%9F%E7%BE%8E%E5%8C%96/twinkle-tray-intro/</id>
      <title type="text">GitHub热门项目！Twinkle Tray：多显示器亮度调节神器</title>
      <published>2026-06-15T00:00:00.000Z</published>
      <updated>2026-06-15T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E7%B3%BB%E7%BB%9F%E7%BE%8E%E5%8C%96/twinkle-tray-intro/"/>
      <summary type="text">告别手动调节！这个开源工具让你一键控制所有显示器亮度，支持热键、定时调光、DDC/CI扩展控制</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！多显示器亮度调节太麻烦？<a href="#朋友们多显示器亮度调节太麻烦"><span>#</span></a></h2><p>作为一个多屏工作者，你是不是每天都要面对这些困扰：</p><ul>
<li>Windows 只能调节笔记本屏幕亮度，外接显示器完全不受控制</li>
<li>每次调亮度都要弯腰去按显示器物理按键，麻烦又不精确</li>
<li>多台显示器亮度不一致，眼睛累到不行</li>
<li>晚上工作时想调暗屏幕，却找不到合适的工具</li>
</ul><p>直到我发现了 <strong>Twinkle Tray</strong>！这个 GitHub 上 6.6k+ Star 的神器，让我彻底告别了手动调节亮度的痛苦！今天就来给大家分享这个宝藏工具！</p></section>
<section><h2>✨ 什么是 Twinkle Tray？<a href="#-什么是-twinkle-tray"><span>#</span></a></h2><p>Twinkle Tray 是一款专门为 Windows 设计的<strong>多显示器亮度控制工具</strong>。它通过系统托盘提供直观的亮度调节界面，支持几乎所有 DDC/CI 协议的显示器。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/1d028956251b461b8dffa4e60eb6360920260615090439344.png" alt="" /></p></section>
<section><h2>🎯 核心功能<a href="#-核心功能"><span>#</span></a></h2>

<table><thead><tr><th>功能</th><th>说明</th></tr></thead><tbody><tr><td><strong>系统托盘滑块</strong></td><td>一键调节所有显示器亮度，1% 精度控制</td></tr><tr><td><strong>热键支持</strong></td><td>自定义快捷键快速调节，无需打开界面</td></tr><tr><td><strong>定时调光</strong></td><td>根据时间自动调整亮度，日出日落智能适配</td></tr><tr><td><strong>DDC/CI 扩展</strong></td><td>支持对比度、音量、输入源切换等高级功能</td></tr><tr><td><strong>多语言支持</strong></td><td>支持 20+ 种语言，中文界面友好</td></tr><tr><td><strong>开机启动</strong></td><td>Windows 启动时自动运行，无需手动开启</td></tr></tbody></table></section>
<section><h2>🎨 界面特色<a href="#-界面特色"><span>#</span></a></h2><p>Twinkle Tray 最让我喜欢的一点是它的界面设计：</p><ul>
<li><strong>自动适配 Windows 风格</strong>：完美融入 Windows 10/11 系统，采用毛玻璃效果</li>
<li><strong>跟随系统主题</strong>：自动匹配你的个性化设置（浅色/深色模式）</li>
<li><strong>直观操作</strong>：左键点击显示亮度面板，滚轮直接调节</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/2b5ea4ca2dc047b184bea9dceaeb967820260615090552565.png" alt="" /></p></section>
<section><h2>🚀 安装教程<a href="#-安装教程"><span>#</span></a></h2><section><h3>方法一：包管理器安装（推荐）<a href="#方法一包管理器安装推荐"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Windows 11 内置包管理器</span></div></div><div><div><div>2</div></div><div><span>winget install xanderfrangos.twinkletray</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># Chocolatey</span></div></div><div><div><div>5</div></div><div><span><span>choco install twinkle</span><span>-</span><span>tray</span></span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># Scoop</span></div></div><div><div><div>8</div></div><div><span>scoop bucket add extras</span></div></div><div><div><div>9</div></div><div><span><span>scoop install extras</span><span>/</span><span>twinkle</span><span>-</span><span>tray</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>方法二：手动下载<a href="#方法二手动下载"><span>#</span></a></h3><ol>
<li>访问 GitHub 发布页：<a href="https://github.com/xanderfrangos/twinkle-tray/releases" target="_blank">https://github.com/xanderfrangos/twinkle-tray/releases</a></li>
<li>下载最新版本的 <code>.exe</code> 安装包</li>
<li>运行安装程序，建议选择”为所有用户安装”
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/4aa15a02a45847bf9edb15ddafc85e7020260615090746615.png" alt="" /></li>
</ol></section><section><h3>方法三：Microsoft Store<a href="#方法三microsoft-store"><span>#</span></a></h3><p>直接在 Microsoft Store 搜索 “Twinkle Tray” 即可安装。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/59f141a457d94d07b64a139899a35b1b20260615090700481.png" alt="" /></p></section></section>
<section><h2>📝 使用指南<a href="#-使用指南"><span>#</span></a></h2><section><h3>基础操作<a href="#基础操作"><span>#</span></a></h3><ol>
<li><strong>调节亮度</strong>：点击系统托盘的 ✨ 图标，拖动滑块调节</li>
<li><strong>单独控制</strong>：每个显示器有独立的亮度滑块</li>
<li><strong>统一调节</strong>：拖动顶部的”所有显示器”滑块一起调整</li>
</ol></section><section><h3>热键配置<a href="#热键配置"><span>#</span></a></h3><p>右键点击托盘图标 → 设置 → 热键</p><p><strong>推荐配置</strong>：</p>

<table><thead><tr><th>操作</th><th>推荐热键</th></tr></thead><tbody><tr><td>所有显示器亮度+10%</td><td>Ctrl+Win+↑</td></tr><tr><td>所有显示器亮度-10%</td><td>Ctrl+Win+↓</td></tr><tr><td>显示器关闭</td><td>Ctrl+Shift+F10</td></tr></tbody></table></section><section><h3>定时调光<a href="#定时调光"><span>#</span></a></h3><p>在设置的”时间”标签页中，可以配置：</p><ul>
<li><strong>日出日落模式</strong>：根据地理位置自动调节</li>
<li><strong>固定时间表</strong>：设置时间段和目标亮度</li>
<li><strong>空闲检测</strong>：电脑空闲时自动调暗</li>
</ul></section></section>
<section><h2>⚙️ 高级功能<a href="#️-高级功能"><span>#</span></a></h2><section><h3>DDC/CI 扩展控制<a href="#ddcci-扩展控制"><span>#</span></a></h3><p>除了亮度，还可以控制：</p><ul>
<li><strong>对比度</strong>：调整显示器对比度</li>
<li><strong>音量</strong>：控制显示器内置扬声器</li>
<li><strong>输入源</strong>：切换 HDMI/DP/USB-C 输入</li>
<li><strong>电源状态</strong>：开关显示器</li>
</ul></section><section><h3>显示器归一化<a href="#显示器归一化"><span>#</span></a></h3><p>如果你的显示器亮度曲线不一致，可以使用”归一化”功能让它们看起来亮度相同。</p></section><section><h3>命令行支持<a href="#命令行支持"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 设置所有显示器亮度为 50%</span></div></div><div><div><div>2</div></div><div><span><span>twinkle</span><span>-</span><span>tray </span><span>--</span></span><span>set-all</span><span> </span><span>50</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 增加亮度</span></div></div><div><div><div>5</div></div><div><span><span>twinkle</span><span>-</span><span>tray </span><span>--</span><span>increase </span></span><span>10</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 减少亮度</span></div></div><div><div><div>8</div></div><div><span><span>twinkle</span><span>-</span><span>tray </span><span>--</span><span>decrease </span></span><span>10</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>💡 使用场景<a href="#-使用场景"><span>#</span></a></h2><section><h3>场景一：程序员多屏开发<a href="#场景一程序员多屏开发"><span>#</span></a></h3><p>作为程序员，我通常连接 2-3 台显示器。以前调亮度要一个个按物理按键，现在用 Twinkle Tray 一键搞定，效率提升太多！</p></section><section><h3>场景二：夜间工作<a href="#场景二夜间工作"><span>#</span></a></h3><p>晚上工作时，自动调光功能可以根据时间逐渐降低亮度，保护眼睛。</p></section><section><h3>场景三：演示场景<a href="#场景三演示场景"><span>#</span></a></h3><p>做演示时，可以快速关闭不需要的显示器，或者统一调整所有屏幕亮度。</p></section></section>
<section><h2>⚠️ 注意事项<a href="#️-注意事项"><span>#</span></a></h2><ol>
<li><strong>DDC/CI 支持</strong>：确保你的显示器支持 DDC/CI 协议（大多数现代显示器都支持）</li>
<li><strong>显卡驱动</strong>：更新显卡驱动到最新版本，AMD 用户需禁用”自定义颜色”</li>
<li><strong>显示器连接</strong>：建议使用 HDMI/DP 直连，部分转接器可能不支持</li>
</ol></section>
<section><h2>📊 对比其他工具<a href="#-对比其他工具"><span>#</span></a></h2>

<table><thead><tr><th>工具</th><th>价格</th><th>平台</th><th>核心功能</th></tr></thead><tbody><tr><td><strong>Twinkle Tray</strong></td><td>免费</td><td>Windows</td><td>亮度、热键、定时</td></tr><tr><td><strong>DisplayBuddy</strong></td><td>付费</td><td>Win/Mac</td><td>亮度、对比度、预设</td></tr><tr><td><strong>Monitorian</strong></td><td>免费</td><td>Windows</td><td>基础亮度控制</td></tr><tr><td><strong>Windows 自带</strong></td><td>免费</td><td>Windows</td><td>仅笔记本屏幕</td></tr></tbody></table></section>
<section><h2>📝 总结<a href="#-总结"><span>#</span></a></h2><p>Twinkle Tray 是一款非常实用的多显示器亮度控制工具，界面美观、功能全面、完全免费。它解决了 Windows 系统不支持外接显示器亮度调节的痛点，通过 DDC/CI 协议实现精确控制。支持热键、定时调光、命令行等高级功能，适合程序员、设计师等多屏工作者使用。如果你正在为多显示器亮度调节烦恼，不妨试试这个工具！</p></section>
<section><h2>🌟 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub 地址</strong>: <a href="https://github.com/xanderfrangos/twinkle-tray" target="_blank">https://github.com/xanderfrangos/twinkle-tray</a></p><p><strong>官方网站</strong>: <a href="https://twinkletray.com" target="_blank">https://twinkletray.com</a></p><p><strong>最新版本</strong>: v1.17.2</p><p><strong>开源协议</strong>: MIT License</p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p></section>
<section><h2>🎉 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你平时使用几台显示器？最需要的功能是什么？欢迎在评论区和我交流分享！</p><p>我会定期分享更多好用的开发工具，记得关注我哦！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/docker/hoppscotch-docker-intro/</id>
      <title type="text">GitHub热门项目！Hoppscotch Docker私有部署实战指南</title>
      <published>2026-06-12T00:00:00.000Z</published>
      <updated>2026-06-12T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/docker/hoppscotch-docker-intro/"/>
      <summary type="text">手把手教你用Docker部署Hoppscotch，打造企业级私有API测试平台，支持团队协作、OAuth认证、SMTP配置等完整功能</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！API测试工具选对了吗？<a href="#朋友们api测试工具选对了吗"><span>#</span></a></h2><p>作为开发者，你是不是每天都要和各种 API 打交道？测试接口、调试接口、文档化接口…市面上的 API 测试工具不少，但要么收费太贵，要么数据不安全，要么功能不够用。</p><p>作为一个资深开发者，我试过很多工具：Postman 功能强大但收费高，Insomnia 不错但团队协作不方便，curl 太麻烦…直到遇到了 <strong>Hoppscotch</strong>！这是一个完全开源的 API 开发生态系统，功能媲美 Postman，而且可以私有部署，数据完全可控！</p><p>这两天我研究了一下它的 Docker 部署方案，发现部署起来其实很简单。今天我就来手把手教大家如何在自己的服务器上部署 Hoppscotch，打造一个专属的 API 测试平台！</p></section>
<section><h2>✨ 什么是 Hoppscotch？<a href="#-什么是-hoppscotch"><span>#</span></a></h2><p>Hoppscotch 是一个开源的 API 开发生态系统，被誉为”开源版 Postman”。它支持 REST、GraphQL、WebSocket、MQTT 等多种协议，提供团队协作、环境变量、前置脚本等强大功能。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/8bb0d717ca084ef4b1f847cfd48ffb5620260612160443593.png" alt="" /></p></section>
<section><h2>🎯 核心功能<a href="#-核心功能"><span>#</span></a></h2><ul>
<li><strong>🚀 全协议支持</strong>: REST、GraphQL、WebSocket、Server-Sent Events、Socket.IO、MQTT</li>
<li><strong>👥 团队协作</strong>: 创建团队、共享集合、角色权限控制</li>
<li><strong>📁 工作空间</strong>: 组织个人和团队项目到不同工作空间</li>
<li><strong>🌱 环境变量</strong>: 支持多环境配置，方便切换开发/测试/生产环境</li>
<li><strong>📜 前置/后置脚本</strong>: 支持 JavaScript 编写测试脚本</li>
<li><strong>🔐 多种认证</strong>: Basic Auth、Bearer Token、OAuth 2.0、OIDC</li>
<li><strong>📱 跨平台</strong>: Web、桌面应用、CLI 工具</li>
</ul></section>
<section><h2>📋 前置准备<a href="#-前置准备"><span>#</span></a></h2><section><h3>环境要求<a href="#环境要求"><span>#</span></a></h3>

<table><thead><tr><th>依赖</th><th>版本要求</th><th>说明</th></tr></thead><tbody><tr><td>Docker</td><td>20+</td><td>容器运行环境</td></tr><tr><td>Docker Compose</td><td>2+</td><td>容器编排工具</td></tr><tr><td>Node.js</td><td>18+</td><td>可选，用于开发模式</td></tr><tr><td>pnpm</td><td>6+</td><td>可选，用于开发模式</td></tr><tr><td>Git</td><td>任意</td><td>克隆代码仓库</td></tr></tbody></table></section><section><h3>服务器配置建议<a href="#服务器配置建议"><span>#</span></a></h3>

<table><thead><tr><th>配置项</th><th>最低配置</th><th>推荐配置</th></tr></thead><tbody><tr><td>CPU</td><td>2核</td><td>4核+</td></tr><tr><td>内存</td><td>4GB</td><td>8GB+</td></tr><tr><td>存储</td><td>20GB</td><td>50GB+</td></tr><tr><td>系统</td><td>Linux (Ubuntu/Debian/CentOS)</td><td>Linux</td></tr></tbody></table></section></section>
<section><h2>🚀 部署实战<a href="#-部署实战"><span>#</span></a></h2><section><h3>方式一：使用官方 AIO 容器（推荐）<a href="#方式一使用官方-aio-容器推荐"><span>#</span></a></h3><p><strong>优点</strong>: 单容器部署，简单快捷，适合快速体验</p><section><h4>1. 创建目录结构<a href="#1-创建目录结构"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>mkdir</span><span> </span><span>-p</span><span> </span><span>/opt/hoppscotch/data</span></div></div><div><div><div>2</div></div><div><span>mkdir</span><span> </span><span>-p</span><span> </span><span>/opt/hoppscotch/config</span></div></div><div><div><div>3</div></div><div><span>cd</span><span> </span><span>/opt/hoppscotch</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>2. 创建 .env 配置文件<a href="#2-创建-env-配置文件"><span>#</span></a></h4><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cat</span><span> &gt; </span><span>/opt/hoppscotch/config/.env</span><span> &lt;&lt; </span><span>'EOF'</span></div></div><div><div><div>2</div></div><div><span>#-----------------------Backend Config------------------------------#</span></div></div><div><div><div>3</div></div><div><span># Prisma Config - 使用内置SQLite数据库</span></div></div><div><div><div>4</div></div><div><span>DATABASE_URL=file:./data/db.sqlite</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span># 数据加密密钥（32位字符）</span></div></div><div><div><div>7</div></div><div><span>DATA_ENCRYPTION_KEY=your-32-character-encryption-key-here</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span># 允许的来源（根据需要添加你的域名）</span></div></div><div><div><div>10</div></div><div><span>WHITELISTED_ORIGINS=http://localhost:3000,http://localhost:3100,http://localhost:3170,app://localhost_3200,app://hoppscotch</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>#-----------------------Frontend Config------------------------------#</span></div></div><div><div><div>13</div></div><div><span># 应用基础URL</span></div></div><div><div><div>14</div></div><div><span>APP_URL=http://localhost:3000</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span># API基础URL</span></div></div><div><div><div>17</div></div><div><span>API_URL=http://localhost:3170</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>#-----------------------Auth Config------------------------------#</span></div></div><div><div><div>20</div></div><div><span># JWT密钥（32位字符）</span></div></div><div><div><div>21</div></div><div><span>JWT_SECRET=your-32-character-jwt-secret-here</span></div></div><div><div><div>22</div></div><div>
</div></div><div><div><div>23</div></div><div><span># 密码重置密钥（32位字符）</span></div></div><div><div><div>24</div></div><div><span>PASSWORD_RESET_SECRET=your-32-character-reset-secret-here</span></div></div><div><div><div>25</div></div><div>
</div></div><div><div><div>26</div></div><div><span>#-----------------------SMTP Config（可选）------------------------------#</span></div></div><div><div><div>27</div></div><div><span># SMTP_HOST=smtp.example.com</span></div></div><div><div><div>28</div></div><div><span># SMTP_PORT=587</span></div></div><div><div><div>29</div></div><div><span># SMTP_USERNAME=your-email@example.com</span></div></div><div><div><div>30</div></div><div><span># SMTP_PASSWORD=your-email-password</span></div></div><div><div><div>31</div></div><div><span># SMTP_FROM_NAME=Hoppscotch</span></div></div><div><div><div>32</div></div><div><span># SMTP_FROM_EMAIL=no-reply@example.com</span></div></div><div><div><div>33</div></div><div><span>EOF</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>3. 运行 AIO 容器<a href="#3-运行-aio-容器"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>--name</span><span> </span><span>hoppscotch-aio</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>-p</span><span> </span><span>3000:3000</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>-p</span><span> </span><span>3170:3170</span><span> </span><span>\</span></div></div><div><div><div>5</div></div><div><span>  </span><span>-v</span><span> </span><span>/opt/hoppscotch/data:/app/data</span><span> </span><span>\</span></div></div><div><div><div>6</div></div><div><span>  </span><span>-v</span><span> </span><span>/opt/hoppscotch/config/.env:/app/.env</span><span> </span><span>\</span></div></div><div><div><div>7</div></div><div><span>  </span><span>--restart</span><span> </span><span>unless-stopped</span><span> </span><span>\</span></div></div><div><div><div>8</div></div><div><span>  </span><span>hoppscotch/hoppscotch:latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>4. 访问应用<a href="#4-访问应用"><span>#</span></a></h4><p>打开浏览器访问 <code>http://your-server-ip:3000</code></p><hr /></section></section><section><h3>方式二：使用 Docker Compose 多容器部署（生产推荐）<a href="#方式二使用-docker-compose-多容器部署生产推荐"><span>#</span></a></h3><p><strong>优点</strong>: 服务分离，便于扩展和维护，适合生产环境</p><section><h4>1. 克隆项目代码<a href="#1-克隆项目代码"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/hoppscotch/hoppscotch.git</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>hoppscotch</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>2. 创建 .env 配置文件<a href="#2-创建-env-配置文件-1"><span>#</span></a></h4><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cat</span><span> &gt; </span><span>.env</span><span> &lt;&lt; </span><span>'EOF'</span></div></div><div><div><div>2</div></div><div><span>#-----------------------Backend Config------------------------------#</span></div></div><div><div><div>3</div></div><div><span># PostgreSQL数据库配置</span></div></div><div><div><div>4</div></div><div><span>DATABASE_URL=postgresql://hoppscotch:hoppscotch@hoppscotch-db:5432/hoppscotch</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span># 数据加密密钥（32位字符，必须修改！）</span></div></div><div><div><div>7</div></div><div><span>DATA_ENCRYPTION_KEY=your-32-character-encryption-key-here</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span># 允许的来源</span></div></div><div><div><div>10</div></div><div><span>WHITELISTED_ORIGINS=http://localhost:3000,http://localhost:3100,http://localhost:3170,app://localhost_3200,app://hoppscotch</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>#-----------------------Frontend Config------------------------------#</span></div></div><div><div><div>13</div></div><div><span>APP_URL=http://localhost:3000</span></div></div><div><div><div>14</div></div><div><span>API_URL=http://localhost:3170</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span>#-----------------------Auth Config------------------------------#</span></div></div><div><div><div>17</div></div><div><span># JWT密钥（32位字符，必须修改！）</span></div></div><div><div><div>18</div></div><div><span>JWT_SECRET=your-32-character-jwt-secret-here</span></div></div><div><div><div>19</div></div><div>
</div></div><div><div><div>20</div></div><div><span># 密码重置密钥（32位字符，必须修改！）</span></div></div><div><div><div>21</div></div><div><span>PASSWORD_RESET_SECRET=your-32-character-reset-secret-here</span></div></div><div><div><div>22</div></div><div>
</div></div><div><div><div>23</div></div><div><span>#-----------------------SMTP Config------------------------------#</span></div></div><div><div><div>24</div></div><div><span>SMTP_HOST=smtp.example.com</span></div></div><div><div><div>25</div></div><div><span>SMTP_PORT=587</span></div></div><div><div><div>26</div></div><div><span>SMTP_USERNAME=your-email@example.com</span></div></div><div><div><div>27</div></div><div><span>SMTP_PASSWORD=your-email-password</span></div></div><div><div><div>28</div></div><div><span>SMTP_FROM_NAME=Hoppscotch</span></div></div><div><div><div>29</div></div><div><span>SMTP_FROM_EMAIL=no-reply@example.com</span></div></div><div><div><div>30</div></div><div>
</div></div><div><div><div>31</div></div><div><span>#-----------------------OAuth Config（可选）------------------------------#</span></div></div><div><div><div>32</div></div><div><span># GitHub OAuth</span></div></div><div><div><div>33</div></div><div><span># GITHUB_CLIENT_ID=your-github-client-id</span></div></div><div><div><div>34</div></div><div><span># GITHUB_CLIENT_SECRET=your-github-client-secret</span></div></div><div><div><div>35</div></div><div>
</div></div><div><div><div>36</div></div><div><span># Google OAuth</span></div></div><div><div><div>37</div></div><div><span># GOOGLE_CLIENT_ID=your-google-client-id</span></div></div><div><div><div>38</div></div><div><span># GOOGLE_CLIENT_SECRET=your-google-client-secret</span></div></div><div><div><div>39</div></div><div>
</div></div><div><div><div>40</div></div><div><span># Microsoft OAuth</span></div></div><div><div><div>41</div></div><div><span># MICROSOFT_CLIENT_ID=your-microsoft-client-id</span></div></div><div><div><div>42</div></div><div><span># MICROSOFT_CLIENT_SECRET=your-microsoft-client-secret</span></div></div><div><div><div>43</div></div><div><span>EOF</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>3. 创建 docker-compose.yml<a href="#3-创建-docker-composeyml"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>version</span><span>: </span><span>'3.8'</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>services</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>hoppscotch-db</span><span>:</span></div></div><div><div><div>5</div></div><div><span>    </span><span>image</span><span>: </span><span>postgres:15-alpine</span></div></div><div><div><div>6</div></div><div><span>    </span><span>container_name</span><span>: </span><span>hoppscotch-db</span></div></div><div><div><div>7</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>8</div></div><div><span>      </span><span>POSTGRES_USER</span><span>: </span><span>hoppscotch</span></div></div><div><div><div>9</div></div><div><span>      </span><span>POSTGRES_PASSWORD</span><span>: </span><span>hoppscotch</span></div></div><div><div><div>10</div></div><div><span>      </span><span>POSTGRES_DB</span><span>: </span><span>hoppscotch</span></div></div><div><div><div>11</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>- </span><span>hoppscotch-db-data:/var/lib/postgresql/data</span></div></div><div><div><div>13</div></div><div><span>    </span><span>networks</span><span>:</span></div></div><div><div><div>14</div></div><div><span><span>      </span></span><span>- </span><span>hoppscotch-network</span></div></div><div><div><div>15</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>  </span><span>hoppscotch-backend</span><span>:</span></div></div><div><div><div>18</div></div><div><span>    </span><span>image</span><span>: </span><span>hoppscotch/hoppscotch-backend:latest</span></div></div><div><div><div>19</div></div><div><span>    </span><span>container_name</span><span>: </span><span>hoppscotch-backend</span></div></div><div><div><div>20</div></div><div><span>    </span><span>depends_on</span><span>:</span></div></div><div><div><div>21</div></div><div><span><span>      </span></span><span>- </span><span>hoppscotch-db</span></div></div><div><div><div>22</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>23</div></div><div><span>      </span><span>DATABASE_URL</span><span>: </span><span>postgresql://hoppscotch:hoppscotch@hoppscotch-db:5432/hoppscotch</span></div></div><div><div><div>24</div></div><div><span>      </span><span>DATA_ENCRYPTION_KEY</span><span>: </span><span>${DATA_ENCRYPTION_KEY}</span></div></div><div><div><div>25</div></div><div><span>      </span><span>WHITELISTED_ORIGINS</span><span>: </span><span>${WHITELISTED_ORIGINS}</span></div></div><div><div><div>26</div></div><div><span>      </span><span>JWT_SECRET</span><span>: </span><span>${JWT_SECRET}</span></div></div><div><div><div>27</div></div><div><span>      </span><span>PASSWORD_RESET_SECRET</span><span>: </span><span>${PASSWORD_RESET_SECRET}</span></div></div><div><div><div>28</div></div><div><span>      </span><span>SMTP_HOST</span><span>: </span><span>${SMTP_HOST}</span></div></div><div><div><div>29</div></div><div><span>      </span><span>SMTP_PORT</span><span>: </span><span>${SMTP_PORT}</span></div></div><div><div><div>30</div></div><div><span>      </span><span>SMTP_USERNAME</span><span>: </span><span>${SMTP_USERNAME}</span></div></div><div><div><div>31</div></div><div><span>      </span><span>SMTP_PASSWORD</span><span>: </span><span>${SMTP_PASSWORD}</span></div></div><div><div><div>32</div></div><div><span>      </span><span>SMTP_FROM_NAME</span><span>: </span><span>${SMTP_FROM_NAME}</span></div></div><div><div><div>33</div></div><div><span>      </span><span>SMTP_FROM_EMAIL</span><span>: </span><span>${SMTP_FROM_EMAIL}</span></div></div><div><div><div>34</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>35</div></div><div><span><span>      </span></span><span>- </span><span>./config:/app/config</span></div></div><div><div><div>36</div></div><div><span>    </span><span>networks</span><span>:</span></div></div><div><div><div>37</div></div><div><span><span>      </span></span><span>- </span><span>hoppscotch-network</span></div></div><div><div><div>38</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>39</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>40</div></div><div><span><span>      </span></span><span>- </span><span>"3170:3170"</span></div></div><div><div><div>41</div></div><div>
</div></div><div><div><div>42</div></div><div><span>  </span><span>hoppscotch-frontend</span><span>:</span></div></div><div><div><div>43</div></div><div><span>    </span><span>image</span><span>: </span><span>hoppscotch/hoppscotch-frontend:latest</span></div></div><div><div><div>44</div></div><div><span>    </span><span>container_name</span><span>: </span><span>hoppscotch-frontend</span></div></div><div><div><div>45</div></div><div><span>    </span><span>depends_on</span><span>:</span></div></div><div><div><div>46</div></div><div><span><span>      </span></span><span>- </span><span>hoppscotch-backend</span></div></div><div><div><div>47</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>48</div></div><div><span>      </span><span>APP_URL</span><span>: </span><span>${APP_URL}</span></div></div><div><div><div>49</div></div><div><span>      </span><span>API_URL</span><span>: </span><span>${API_URL}</span></div></div><div><div><div>50</div></div><div><span>    </span><span>networks</span><span>:</span></div></div><div><div><div>51</div></div><div><span><span>      </span></span><span>- </span><span>hoppscotch-network</span></div></div><div><div><div>52</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>53</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>54</div></div><div><span><span>      </span></span><span>- </span><span>"3000:3000"</span></div></div><div><div><div>55</div></div><div>
</div></div><div><div><div>56</div></div><div><span>  </span><span>hoppscotch-admin</span><span>:</span></div></div><div><div><div>57</div></div><div><span>    </span><span>image</span><span>: </span><span>hoppscotch/hoppscotch-admin:latest</span></div></div><div><div><div>58</div></div><div><span>    </span><span>container_name</span><span>: </span><span>hoppscotch-admin</span></div></div><div><div><div>59</div></div><div><span>    </span><span>depends_on</span><span>:</span></div></div><div><div><div>60</div></div><div><span><span>      </span></span><span>- </span><span>hoppscotch-backend</span></div></div><div><div><div>61</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>62</div></div><div><span>      </span><span>VITE_API_URL</span><span>: </span><span>${API_URL}</span></div></div><div><div><div>63</div></div><div><span>    </span><span>networks</span><span>:</span></div></div><div><div><div>64</div></div><div><span><span>      </span></span><span>- </span><span>hoppscotch-network</span></div></div><div><div><div>65</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>66</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>67</div></div><div><span><span>      </span></span><span>- </span><span>"3100:3100"</span></div></div><div><div><div>68</div></div><div>
</div></div><div><div><div>69</div></div><div><span>volumes</span><span>:</span></div></div><div><div><div>70</div></div><div><span>  </span><span>hoppscotch-db-data</span><span>: </span><span>./hoppscotch-db-data</span></div></div><div><div><div>71</div></div><div>
</div></div><div><div><div>72</div></div><div><span>networks</span><span>:</span></div></div><div><div><div>73</div></div><div><span>  </span><span>hoppscotch-network</span><span>:</span></div></div><div><div><div>74</div></div><div><span>    </span><span>driver</span><span>: </span><span>bridge</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>4. 启动服务<a href="#4-启动服务"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 启动所有服务</span></div></div><div><div><div>2</div></div><div><span>docker-compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 查看服务状态</span></div></div><div><div><div>5</div></div><div><span>docker-compose</span><span> </span><span>ps</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 查看日志</span></div></div><div><div><div>8</div></div><div><span>docker-compose</span><span> </span><span>logs</span><span> </span><span>-f</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>5. 初始化数据库<a href="#5-初始化数据库"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 进入后端容器</span></div></div><div><div><div>2</div></div><div><span>docker</span><span> </span><span>exec</span><span> </span><span>-it</span><span> </span><span>hoppscotch-backend</span><span> </span><span>sh</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 运行数据库迁移</span></div></div><div><div><div>5</div></div><div><span>pnpm</span><span> </span><span>prisma</span><span> </span><span>migrate</span><span> </span><span>deploy</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 退出容器</span></div></div><div><div><div>8</div></div><div><span>exit</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>6. 访问应用<a href="#6-访问应用"><span>#</span></a></h4>

<table><thead><tr><th>服务</th><th>地址</th><th>说明</th></tr></thead><tbody><tr><td>主应用</td><td><a href="http://localhost:3000" target="_blank">http://localhost:3000</a></td><td>API测试主界面</td></tr><tr><td>管理后台</td><td><a href="http://localhost:3100" target="_blank">http://localhost:3100</a></td><td>管理员仪表盘</td></tr><tr><td>API服务</td><td><a href="http://localhost:3170" target="_blank">http://localhost:3170</a></td><td>后端API</td></tr></tbody></table><hr /></section></section></section>
<section><h2>⚙️ 高级配置<a href="#️-高级配置"><span>#</span></a></h2><section><h3>1. 配置 OAuth 登录<a href="#1-配置-oauth-登录"><span>#</span></a></h3><section><h4>GitHub OAuth<a href="#github-oauth"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 在 GitHub 创建 OAuth App: https://github.com/settings/developers</span></div></div><div><div><div>2</div></div><div><span># 回调地址: http://your-domain.com/api/auth/github/callback</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 修改 .env 文件</span></div></div><div><div><div>5</div></div><div><span>GITHUB_CLIENT_ID</span><span>=</span><span>your-github-client-id</span></div></div><div><div><div>6</div></div><div><span>GITHUB_CLIENT_SECRET</span><span>=</span><span>your-github-client-secret</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h3>2. 配置 HTTPS（使用 Nginx 反向代理）<a href="#2-配置-https使用-nginx-反向代理"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>server</span><span> {</span></div></div><div><div><div>2</div></div><div><span>   <span> </span></span><span>listen </span><span>80</span><span>;</span></div></div><div><div><div>3</div></div><div><span>   <span> </span></span><span>server_name </span><span>api.example.com;</span></div></div><div><div><div>4</div></div><div><span>    </span><span>return</span><span> </span><span>301</span><span> https://$</span><span>server_name</span><span>$</span><span>request_uri</span><span>;</span></div></div><div><div><div>5</div></div><div><span>}</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>server</span><span> {</span></div></div><div><div><div>8</div></div><div><span>   <span> </span></span><span>listen </span><span>443</span><span> ssl;</span></div></div><div><div><div>9</div></div><div><span>   <span> </span></span><span>server_name </span><span>api.example.com;</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>   <span> </span></span><span>ssl_certificate </span><span>/path/to/cert.pem;</span></div></div><div><div><div>12</div></div><div><span>   <span> </span></span><span>ssl_certificate_key </span><span>/path/to/key.pem;</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>    </span><span>location</span><span> / {</span></div></div><div><div><div>15</div></div><div><span>       <span> </span></span><span>proxy_pass </span><span>http://localhost:3000;</span></div></div><div><div><div>16</div></div><div><span>       <span> </span></span><span>proxy_set_header </span><span>Host $</span><span>host</span><span>;</span></div></div><div><div><div>17</div></div><div><span>       <span> </span></span><span>proxy_set_header </span><span>X-Real-IP $</span><span>remote_addr</span><span>;</span></div></div><div><div><div>18</div></div><div><span>       <span> </span></span><span>proxy_set_header </span><span>X-Forwarded-For $</span><span>proxy_add_x_forwarded_for</span><span>;</span></div></div><div><div><div>19</div></div><div><span>       <span> </span></span><span>proxy_set_header </span><span>X-Forwarded-Proto $</span><span>scheme</span><span>;</span></div></div><div><div><div>20</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span>    </span><span>location</span><span> /api/ {</span></div></div><div><div><div>23</div></div><div><span>       <span> </span></span><span>proxy_pass </span><span>http://localhost:3170/;</span></div></div><div><div><div>24</div></div><div><span>       <span> </span></span><span>proxy_set_header </span><span>Host $</span><span>host</span><span>;</span></div></div><div><div><div>25</div></div><div><span>       <span> </span></span><span>proxy_set_header </span><span>X-Real-IP $</span><span>remote_addr</span><span>;</span></div></div><div><div><div>26</div></div><div><span>       <span> </span></span><span>proxy_set_header </span><span>X-Forwarded-For $</span><span>proxy_add_x_forwarded_for</span><span>;</span></div></div><div><div><div>27</div></div><div><span>       <span> </span></span><span>proxy_set_header </span><span>X-Forwarded-Proto $</span><span>scheme</span><span>;</span></div></div><div><div><div>28</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>29</div></div><div>
</div></div><div><div><div>30</div></div><div><span>    </span><span>location</span><span> /admin/ {</span></div></div><div><div><div>31</div></div><div><span>       <span> </span></span><span>proxy_pass </span><span>http://localhost:3100/;</span></div></div><div><div><div>32</div></div><div><span>       <span> </span></span><span>proxy_set_header </span><span>Host $</span><span>host</span><span>;</span></div></div><div><div><div>33</div></div><div><span>       <span> </span></span><span>proxy_set_header </span><span>X-Real-IP $</span><span>remote_addr</span><span>;</span></div></div><div><div><div>34</div></div><div><span>       <span> </span></span><span>proxy_set_header </span><span>X-Forwarded-For $</span><span>proxy_add_x_forwarded_for</span><span>;</span></div></div><div><div><div>35</div></div><div><span>       <span> </span></span><span>proxy_set_header </span><span>X-Forwarded-Proto $</span><span>scheme</span><span>;</span></div></div><div><div><div>36</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>37</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>3. 配置 Redis 缓存（可选）<a href="#3-配置-redis-缓存可选"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 添加 Redis 服务到 docker-compose.yml</span></div></div><div><div><div>2</div></div><div><span>redis:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>image:</span><span> </span><span>redis:7-alpine</span></div></div><div><div><div>4</div></div><div><span>  </span><span>container_name:</span><span> </span><span>hoppscotch-redis</span></div></div><div><div><div>5</div></div><div><span>  </span><span>volumes:</span></div></div><div><div><div>6</div></div><div><span>    </span><span>-</span><span> </span><span>hoppscotch-redis-data:/data</span></div></div><div><div><div>7</div></div><div><span>  </span><span>networks:</span></div></div><div><div><div>8</div></div><div><span>    </span><span>-</span><span> </span><span>hoppscotch-network</span></div></div><div><div><div>9</div></div><div><span>  </span><span>restart:</span><span> </span><span>unless-stopped</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span># 修改 .env 文件添加 Redis 配置</span></div></div><div><div><div>12</div></div><div><span>REDIS_URL</span><span>=</span><span>redis://hoppscotch-redis:6379</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>📝 使用教程<a href="#-使用教程"><span>#</span></a></h2><section><h3>1. 创建账户<a href="#1-创建账户"><span>#</span></a></h3><p>访问 <code>http://localhost:3000</code>，点击”Sign Up”创建账户：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/9ac44033bfee4dfe91424c65b8e5b44420260612161045616.png" alt="" /></p></section><section><h3>2. 创建第一个请求<a href="#2-创建第一个请求"><span>#</span></a></h3><ol>
<li>点击左侧 ”+” 按钮创建新请求</li>
<li>选择 HTTP 方法（GET/POST/PUT/DELETE 等）</li>
<li>输入 API 地址</li>
<li>添加请求头和参数</li>
<li>点击”Send”发送请求</li>
</ol></section><section><h3>3. 创建集合<a href="#3-创建集合"><span>#</span></a></h3><ol>
<li>点击左侧”Collections”</li>
<li>点击”New Collection”</li>
<li>命名集合并添加描述</li>
<li>将请求拖入集合中</li>
</ol></section><section><h3>4. 配置环境变量<a href="#4-配置环境变量"><span>#</span></a></h3><ol>
<li>点击右上角环境图标</li>
<li>点击”Manage Environments”</li>
<li>创建新环境并添加变量</li>
<li>在请求中使用 <code>{{变量名}}</code> 引用</li>
</ol></section><section><h3>5. 团队协作<a href="#5-团队协作"><span>#</span></a></h3><ol>
<li>点击左侧”Teams”</li>
<li>点击”Create Team”创建团队</li>
<li>邀请成员加入</li>
<li>共享集合和工作空间</li>
</ol></section></section>
<section><h2>🔥 常见问题<a href="#-常见问题"><span>#</span></a></h2><section><h3>Q1: 容器启动失败怎么办？<a href="#q1-容器启动失败怎么办"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 查看日志</span></div></div><div><div><div>2</div></div><div><span>docker-compose</span><span> </span><span>logs</span><span> </span><span>hoppscotch-backend</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 常见问题：数据库连接失败</span></div></div><div><div><div>5</div></div><div><span># 确保数据库服务先启动，检查 DATABASE_URL 是否正确</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 常见问题：端口被占用</span></div></div><div><div><div>8</div></div><div><span># 修改 docker-compose.yml 中的端口映射</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Q2: 如何备份数据？<a href="#q2-如何备份数据"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 备份 PostgreSQL 数据库</span></div></div><div><div><div>2</div></div><div><span>docker</span><span> </span><span>exec</span><span> </span><span>-it</span><span> </span><span>hoppscotch-db</span><span> </span><span>pg_dump</span><span> </span><span>-U</span><span> </span><span>hoppscotch</span><span> </span><span>hoppscotch</span><span> &gt; </span><span>backup.sql</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 恢复数据库</span></div></div><div><div><div>5</div></div><div><span>docker</span><span> </span><span>exec</span><span> </span><span>-i</span><span> </span><span>hoppscotch-db</span><span> </span><span>psql</span><span> </span><span>-U</span><span> </span><span>hoppscotch</span><span> </span><span>hoppscotch</span><span> &lt; </span><span>backup.sql</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Q3: 如何更新版本？<a href="#q3-如何更新版本"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 停止服务</span></div></div><div><div><div>2</div></div><div><span>docker-compose</span><span> </span><span>down</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 拉取最新镜像</span></div></div><div><div><div>5</div></div><div><span>docker-compose</span><span> </span><span>pull</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 启动服务（会自动运行数据库迁移）</span></div></div><div><div><div>8</div></div><div><span>docker-compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Q4: 如何配置邮件通知？<a href="#q4-如何配置邮件通知"><span>#</span></a></h3><p>确保 <code>.env</code> 中的 SMTP 配置正确：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>SMTP_HOST</span><span>=</span><span>smtp.example.com</span></div></div><div><div><div>2</div></div><div><span>SMTP_PORT</span><span>=</span><span>587</span></div></div><div><div><div>3</div></div><div><span>SMTP_USERNAME</span><span>=</span><span>your-email@example.com</span></div></div><div><div><div>4</div></div><div><span>SMTP_PASSWORD</span><span>=</span><span>your-email-password</span></div></div><div><div><div>5</div></div><div><span>SMTP_FROM_NAME</span><span>=</span><span>Hoppscotch</span></div></div><div><div><div>6</div></div><div><span>SMTP_FROM_EMAIL</span><span>=</span><span>no-reply@example.com</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>📝 总结<a href="#-总结"><span>#</span></a></h2><p>Hoppscotch 是一款开源免费的 API 测试工具，功能媲美 Postman。通过 Docker 容器化部署，我们可以轻松搭建企业级私有 API 测试平台。本文介绍了两种部署方式：AIO 单容器适合快速体验，Docker Compose 多容器适合生产环境。配置上支持 OAuth 认证、SMTP 邮件、环境变量等完整功能，无论是 REST、GraphQL 还是 WebSocket 调试，都能高效完成。相比商业工具，Hoppscotch 不仅免费，还支持私有部署，数据安全可控，是团队协作的理想选择。感兴趣的小伙伴可以按照文中步骤实践，根据需求调整配置。今天的分享就到这里，我们下一篇文章见。</p></section>
<section><h2>🌟 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub 地址</strong>: <a href="https://github.com/hoppscotch/hoppscotch" target="_blank">https://github.com/hoppscotch/hoppscotch</a></p><p><strong>官方文档</strong>: <a href="https://docs.hoppscotch.io" target="_blank">https://docs.hoppscotch.io</a></p><p><strong>官方网站</strong>: <a href="https://hoppscotch.io" target="_blank">https://hoppscotch.io</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p><p><strong>项目特色</strong>: 开源免费、功能强大、支持多协议、团队协作、私有部署，是企业级 API 测试的首选工具！</p></section>
<section><h2>🎉 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你平时用什么工具测试 API？对 Hoppscotch 有什么期待？欢迎在评论区和我交流分享！</p><p>我会定期分享更多好用的开发工具和部署教程，记得关注我哦！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/ai/moneyprinterturbo-intro/</id>
      <title type="text">82万星！AI全自动做短视频/图文，躺平变现！</title>
      <published>2026-06-09T00:00:00.000Z</published>
      <updated>2026-06-09T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/ai/moneyprinterturbo-intro/"/>
      <summary type="text">GitHub 82万星爆款项目！MoneyPrinterTurbo让AI帮你全自动生成短视频，从文案到素材一键搞定，开启内容创作躺平模式</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！做短视频太累的看过来！<a href="#朋友们做短视频太累的看过来"><span>#</span></a></h2><p>想做短视频变现却被写文案、找素材、剪辑搞到崩溃？一条视频要花几小时，播放量还惨不忍睹？直到我发现了 <strong>MoneyPrinterTurbo</strong>——GitHub 82万星爆款神器！输入关键词，AI 全自动生成完整短视频，几分钟搞定，质量还超高！今天就带大家看看这个”躺平变现”神器。</p></section>
<section><h2>✨ 什么是 MoneyPrinterTurbo？<a href="#-什么是-moneyprinterturbo"><span>#</span></a></h2><p>MoneyPrinterTurbo 是一个基于 AI 的全自动短视频生成工具。只需提供一个视频主题或关键词，它就能自动完成视频文案撰写、视频素材搜索、字幕生成、背景音乐添加，最后合成一个高清的短视频。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/95a9f3061a484676913819b09e2f9eb820260609163436149.png" alt="" /></p></section>
<section><h2>🎯 核心特性<a href="#-核心特性"><span>#</span></a></h2><ul>
<li><strong>🚀 一键生成</strong>: 输入主题关键词，AI 全自动生成完整视频</li>
<li><strong>📝 智能文案</strong>: 支持 AI 自动生成文案，也可自定义编辑</li>
<li><strong>📹 多尺寸支持</strong>: 竖屏 9&lt;16&gt;（1080x1920）、横屏 16&lt;9&gt;（1920x1080）</li>
<li><strong>🔄 批量生成</strong>: 一次生成多个视频，选择最满意的发布</li>
<li><strong>🗣️ 多语音合成</strong>: 支持多种语音，可实时试听效果</li>
<li><strong>📜 智能字幕</strong>: 自动生成字幕，支持调整字体、位置、颜色、描边</li>
<li><strong>🎵 背景音乐</strong>: 随机或指定音乐，可调节音量</li>
<li><strong>🖼️ 高清素材</strong>: 无版权高清视频素材，也支持本地素材</li>
<li><strong>🤖 多模型支持</strong>: 支持 OpenAI、Claude、Gemini、DeepSeek、通义千问等 700+ 模型</li>
</ul></section>
<section><h2>🛠️ 技术栈<a href="#️-技术栈"><span>#</span></a></h2><section><h3>核心框架<a href="#核心框架"><span>#</span></a></h3><ul>
<li><strong>前端</strong>: Streamlit（Web 界面）+ FastAPI（API 接口）</li>
<li><strong>后端</strong>: Python 3.11</li>
<li><strong>视频处理</strong>: MoviePy 2.x</li>
<li><strong>字幕生成</strong>: Edge TTS / faster-whisper</li>
</ul></section><section><h3>AI 模型支持<a href="#ai-模型支持"><span>#</span></a></h3>

<table><thead><tr><th>类型</th><th>支持平台</th></tr></thead><tbody><tr><td>LLM</td><td>OpenAI、AIHubMix、Moonshot、Azure、gpt4free、one-api、通义千问、Google Gemini、Ollama、DeepSeek、MiniMax、文心一言、Pollinations、ModelScope</td></tr><tr><td>TTS</td><td>Edge TTS（免费）、Azure TTS V2（付费）</td></tr><tr><td>字幕</td><td>Edge TTS、faster-whisper</td></tr></tbody></table></section></section>
<section><h2>📦 安装方式<a href="#-安装方式"><span>#</span></a></h2><section><h3>Windows 一键启动包（推荐）<a href="#windows-一键启动包推荐"><span>#</span></a></h3><p>下载一键启动包，解压直接使用：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>下载地址：</span></div></div><div><div><div>2</div></div><div><span>- 百度网盘：https://pan.baidu.com/s/1wg0UaIyXpO3SqIpaq790SQ?pwd=sbqx</span></div></div><div><div><div>3</div></div><div><span>- Google Drive：https://drive.google.com/file/d/1HsbzfT7XunkrCrHw5ncUjFX8XX4zAuUh/view</span></div></div><div><div><div>4</div></div><div><span>- GitHub release：https://github.com/harry0703/MoneyPrinterTurbo/releases/tag/v1.2.9</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>使用步骤：</strong></p><ol>
<li>下载并解压（路径不要有中文、特殊字符、空格）</li>
<li>双击 <code>update.bat</code> 更新到最新版本</li>
<li>双击 <code>start.bat</code> 启动，自动打开浏览器</li>
</ol></section><section><h3>Docker 部署<a href="#docker-部署"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/harry0703/MoneyPrinterTurbo.git</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>MoneyPrinterTurbo</span></div></div><div><div><div>3</div></div><div><span>docker-compose</span><span> </span><span>up</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>访问地址：</p><ul>
<li>Web 界面：<a href="http://127.0.0.1:8501" target="_blank">http://127.0.0.1:8501</a></li>
<li>API 文档：<a href="http://127.0.0.1:8080/docs" target="_blank">http://127.0.0.1:8080/docs</a></li>
</ul></section></section>
<section><h2>🎬 使用教程<a href="#-使用教程"><span>#</span></a></h2><section><h3>步骤1：启动应用<a href="#步骤1启动应用"><span>#</span></a></h3><p>启动后会自动打开 Web 界面，界面简洁直观：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/dc60ac08f90f4eb19722f70f0da0c8b820260609165252923.png" alt="" /></p></section><section><h3>步骤2：配置参数<a href="#步骤2配置参数"><span>#</span></a></h3><p>在左侧配置面板设置：</p><ul>
<li><strong>视频标题</strong>: 输入主题关键词（如”如何增加生活的乐趣”）</li>
<li><strong>视频尺寸</strong>: 选择竖屏（9&lt;16&gt;）或横屏（16&lt;9&gt;）</li>
<li><strong>语音选择</strong>: 选择喜欢的声音类型</li>
<li><strong>背景音乐</strong>: 选择或上传背景音乐</li>
<li><strong>字幕设置</strong>: 设置字体、颜色、大小、描边</li>
</ul></section><section><h3>步骤3：生成视频<a href="#步骤3生成视频"><span>#</span></a></h3><p>点击「生成视频」按钮，等待几分钟：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>生成流程：</span></div></div><div><div><div>2</div></div><div><span>1. AI 生成视频文案</span></div></div><div><div><div>3</div></div><div><span>2. 搜索匹配的视频素材</span></div></div><div><div><div>4</div></div><div><span>3. 合成语音旁白</span></div></div><div><div><div>5</div></div><div><span>4. 生成字幕</span></div></div><div><div><div>6</div></div><div><span>5. 添加背景音乐</span></div></div><div><div><div>7</div></div><div><span>6. 合成完整视频</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤4：预览和导出<a href="#步骤4预览和导出"><span>#</span></a></h3><p>生成完成后可以预览效果，满意后点击下载即可：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/4b0f69a272cb43ce87f08f6926f390aa20260609170146043.png" alt="" />
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/e1564ee22dfe4bea90f97346ab5c8a8b20260609170224795.png" alt="" /></p></section></section>
<section><h2>🔥 我的使用感受<a href="#-我的使用感受"><span>#</span></a></h2><p>作为一个曾经被短视频创作折磨过的人，我必须说 MoneyPrinterTurbo 彻底改变了我的创作方式！</p><p>以前做一条视频，从构思到发布至少要几个小时，现在输入一个关键词，几分钟就能得到一个高质量的视频。我试过生成几条关于生活技巧的视频，文案写得很有深度，素材匹配也很精准，字幕和背景音乐搭配得恰到好处。</p><p>最让我惊喜的是批量生成功能。输入一个主题，可以一次性生成多个版本，然后选择效果最好的那个发布，大大提高了内容产出效率。</p><p>我用它生成的视频在抖音和B站发布，播放量比我以前手动做的还要高！现在每天花半小时就能生成好几条视频，真正实现了”躺平变现”的梦想！</p></section>
<section><h2>💡 使用场景<a href="#-使用场景"><span>#</span></a></h2><section><h3>1. 自媒体创作者<a href="#1-自媒体创作者"><span>#</span></a></h3><ul>
<li>快速产出大量内容</li>
<li>批量生成多个版本测试效果</li>
<li>降低创作门槛和时间成本</li>
</ul></section><section><h3>2. 企业营销<a href="#2-企业营销"><span>#</span></a></h3><ul>
<li>快速制作产品宣传视频</li>
<li>批量生成多平台适配视频</li>
<li>降低视频制作成本</li>
</ul></section><section><h3>3. 教育机构<a href="#3-教育机构"><span>#</span></a></h3><ul>
<li>自动生成教学视频</li>
<li>批量制作课程内容</li>
<li>提高内容产出效率</li>
</ul></section><section><h3>4. 个人兴趣<a href="#4-个人兴趣"><span>#</span></a></h3><ul>
<li>轻松制作生活记录视频</li>
<li>快速生成知识分享内容</li>
<li>记录生活点滴</li>
</ul></section></section>
<section><h2>📊 配置要求<a href="#-配置要求"><span>#</span></a></h2>

<table><thead><tr><th>配置项</th><th>最低配置</th><th>推荐配置</th></tr></thead><tbody><tr><td>CPU</td><td>4核</td><td>6-8核</td></tr><tr><td>内存</td><td>4GB</td><td>8GB+</td></tr><tr><td>GPU</td><td>非必需</td><td>4GB显存+</td></tr></tbody></table><blockquote><p><strong>小贴士</strong>: 如果主要使用云端 LLM 和在线素材，CPU 和内存更重要；如果启用本地 whisper 或批量生成，建议使用带 GPU 的配置。</p></blockquote></section>
<section><h2>📝 总结<a href="#-总结"><span>#</span></a></h2><p>MoneyPrinterTurbo 以”AI 驱动 + 自动化流水线”为核心，通过多模型支持与智能素材匹配，实现从主题输入到视频输出的全链路自动化。它支持 700+ AI 模型、多平台部署（Windows一键包、Docker、手动部署）和批量生成，无论是自媒体创作、企业营销还是教育内容，都能通过简单关键词快速产出高质量短视频。相比传统视频制作，效率提升几十倍，真正实现内容创作”躺平变现”。感兴趣的小伙伴可以按文中步骤实践，根据需求调整配置。今天的分享就到这里，我们下一篇文章见。</p></section>
<section><h2>🌟 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub 地址</strong>: <a href="https://github.com/harry0703/MoneyPrinterTurbo" target="_blank">https://github.com/harry0703/MoneyPrinterTurbo</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p><p><strong>项目特色</strong>: GitHub 82万星爆款，AI全自动生成短视频，支持多模型、多尺寸、批量生成，真正实现内容创作”躺平变现”！</p></section>
<section><h2>🎉 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你是不是已经跃跃欲试了？赶紧去 GitHub 下载体验吧！</p><p>你平时做短视频最头疼的是什么？用了 MoneyPrinterTurbo 后有什么感受？欢迎在评论区和我交流分享！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</a></li>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/dbx-intro/</id>
      <title type="text">GitHub 热门项目！DBX，15MB 搞定 40+ 数据库管理！</title>
      <published>2026-06-08T00:00:00.000Z</published>
      <updated>2026-06-08T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/dbx-intro/"/>
      <summary type="text">开源、轻量、跨平台数据库客户端，支持 MySQL、PostgreSQL、Redis、MongoDB 等 40+ 数据库，内置 AI 助手</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！数据库管理工具太占内存的看过来！<a href="#朋友们数据库管理工具太占内存的看过来"><span>#</span></a></h2><p>作为一个开发者，你是不是也经常遇到这样的困扰：电脑上装了 MySQL Workbench、Navicat、Redis Desktop Manager、MongoDB Compass…每个工具都要占用几百 MB 甚至上 GB 的内存，开个几个数据库管理工具，电脑就开始卡顿了。</p><p>更让人头疼的是，这些工具大多基于 Electron，打包出来动辄几百 MB，启动慢、占用高，用起来体验并不好。作为一个经常需要同时管理多种数据库的开发者，我太懂这种感受了！</p><p>直到最近发现了一个宝藏项目——<strong>DBX</strong>，彻底改变了我的数据库管理体验！这是一个基于 Tauri 2 + Vue 3 开发的开源数据库管理工具，整个安装包只有 15MB，却能支持 40+ 种数据库，简直不敢相信！</p><p>这两天这个项目在开发者圈子里特别火，今天我就来和大家好好唠唠这个神器，看看它是如何用 15MB 的体积，实现如此强大的功能的。</p></section>
<section><h2>✨ 什么是 DBX？<a href="#-什么是-dbx"><span>#</span></a></h2><p>DBX 是一个开源、轻量级、跨平台的数据库管理 GUI 客户端，由开发者 t8y2 创建并维护。它采用 Tauri 2 框架（Rust 后端）+ Vue 3 前端构建，核心目标是提供一个小巧快速、功能强大的数据库管理工具。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/8897c6e38a7144fcb0022212084488e020260608165611837.png" alt="" /></p></section>
<section><h2>🎯 核心特性<a href="#-核心特性"><span>#</span></a></h2><ul>
<li><strong>🚀 超轻量</strong>: 整个安装包仅 15MB，启动速度快，内存占用低</li>
<li><strong>📦 多数据库支持</strong>: 支持 40+ 种数据库，包括 MySQL、PostgreSQL、SQLite、Redis、MongoDB、DuckDB、ClickHouse、SQL Server、MariaDB、TiDB 等</li>
<li><strong>🔒 本地优先</strong>: 数据完全本地存储，无需联网，保护隐私安全</li>
<li><strong>🤖 AI 助手集成</strong>: 内置 AI 助手，支持自然语言转 SQL、SQL 解释等功能</li>
<li><strong>🎨 现代化 UI</strong>: 基于 Vue 3 构建，界面简洁美观，操作流畅</li>
<li><strong>💰 完全开源</strong>: Apache 2.0 许可证，完全免费使用</li>
<li><strong>🔧 高度可定制</strong>: 支持自定义主题、快捷键、查询模板等</li>
<li><strong>📊 强大功能</strong>: 支持数据浏览、编辑、导出、查询历史、SSH 隧道等</li>
</ul></section>
<section><h2>🛠️ 技术栈<a href="#️-技术栈"><span>#</span></a></h2><section><h3>后端<a href="#后端"><span>#</span></a></h3><ul>
<li><strong>框架</strong>: Tauri 2</li>
<li><strong>语言</strong>: Rust</li>
<li><strong>优势</strong>: 高性能、低内存占用、安全性强</li>
</ul></section><section><h3>前端<a href="#前端"><span>#</span></a></h3><ul>
<li><strong>框架</strong>: Vue 3</li>
<li><strong>语言</strong>: TypeScript</li>
<li><strong>构建</strong>: Vite</li>
<li><strong>优势</strong>: 响应式、组件化、开发效率高</li>
</ul></section><section><h3>数据库支持<a href="#数据库支持"><span>#</span></a></h3><ul>
<li><strong>关系型数据库</strong>: MySQL、PostgreSQL、SQLite、SQL Server、MariaDB、TiDB、DuckDB、ClickHouse 等</li>
<li><strong>NoSQL 数据库</strong>: Redis、MongoDB 等</li>
<li><strong>持续扩展</strong>: 社区驱动，不断增加新数据库支持</li>
</ul></section></section>
<section><h2>📦 安装方式<a href="#-安装方式"><span>#</span></a></h2><section><h3>Windows<a href="#windows"><span>#</span></a></h3><p><strong>方式一：下载安装包（推荐）</strong></p><p>访问 <a href="https://github.com/t8y2/dbx/releases" target="_blank">GitHub Releases</a> 下载最新版本的安装程序，双击运行即可。</p><p><strong>方式二：使用 Scoop 安装</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 添加 DBX 的 Scoop bucket</span></div></div><div><div><div>2</div></div><div><span>scoop</span><span> </span><span>bucket</span><span> </span><span>add</span><span> </span><span>dbx</span><span> </span><span>https://github.com/t8y2/scoop-bucket</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 安装 DBX</span></div></div><div><div><div>5</div></div><div><span>scoop</span><span> </span><span>install</span><span> </span><span>dbx</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>macOS<a href="#macos"><span>#</span></a></h3><p><strong>方式一：下载 DMG 文件</strong></p><p>访问 <a href="https://github.com/t8y2/dbx/releases" target="_blank">GitHub Releases</a> 下载 DMG 文件，拖拽到应用程序文件夹。</p><p>如果遇到”无法打开”的问题，可以：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 方法 1：移除隔离属性</span></div></div><div><div><div>2</div></div><div><span>xattr</span><span> </span><span>-cr</span><span> </span><span>/Applications/dbx.app</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 方法 2：系统设置中允许</span></div></div><div><div><div>5</div></div><div><span># 系统设置 → 隐私与安全性 → 仍要打开</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式二：使用 Homebrew 安装</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>brew</span><span> </span><span>install</span><span> </span><span>--cask</span><span> </span><span>dbx</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Linux<a href="#linux"><span>#</span></a></h3><p><strong>方式一：下载 AppImage</strong></p><p>访问 <a href="https://github.com/t8y2/dbx/releases" target="_blank">GitHub Releases</a> 下载 AppImage 文件，赋予执行权限后运行：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>chmod</span><span> </span><span>+x</span><span> </span><span>dbx-</span><span>*</span><span>.AppImage</span></div></div><div><div><div>2</div></div><div><span>./dbx-*.AppImage</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式二：使用 Flatpak 安装</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>flatpak</span><span> </span><span>install</span><span> </span><span>flathub</span><span> </span><span>io.github.t8y2.dbx</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Docker 部署<a href="#docker-部署"><span>#</span></a></h3><p>如果你更喜欢容器化部署：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>dbx</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image</span><span>: </span><span>t8y2/dbx</span></div></div><div><div><div>4</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>5</div></div><div><span><span>      </span></span><span>- </span><span>"4224:4224"</span></div></div><div><div><div>6</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>./data:/app/data</span></div></div><div><div><div>8</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后访问 <code>http://localhost:4224</code> 即可使用。</p></section></section>
<section><h2>🎬 快速上手<a href="#-快速上手"><span>#</span></a></h2><section><h3>1. 创建数据库连接<a href="#1-创建数据库连接"><span>#</span></a></h3><p>启动 DBX 后，点击左上角的「+」按钮创建新连接：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/8aa36039f9ad4468b39a31435af4efde20260608170156769.png" alt="" /></p><p>选择数据库类型（如 MySQL），填写连接信息：</p><ul>
<li><strong>主机</strong>: 数据库服务器地址</li>
<li><strong>端口</strong>: 数据库端口（MySQL 默认 3306）</li>
<li><strong>用户名</strong>: 数据库用户名</li>
<li><strong>密码</strong>: 数据库密码</li>
<li><strong>数据库</strong>: 要连接的数据库名（可选）</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/ebd2c5dddff9449ebefb50fc0c2c98b320260608170221750.png" alt="" /></p><p>点击「测试连接」确认配置正确，然后保存。</p></section><section><h3>2. 浏览和编辑数据<a href="#2-浏览和编辑数据"><span>#</span></a></h3><p>连接成功后，在左侧导航栏可以看到数据库结构：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/5bbaefc8c2f444aa9e9461732f59f55320260608165928159.png" alt="" /></p><p>点击任意表，可以：</p><ul>
<li><strong>查看数据</strong>: 以表格形式浏览数据</li>
<li><strong>编辑数据</strong>: 直接修改单元格内容</li>
<li><strong>筛选排序</strong>: 点击列头排序，使用筛选器过滤数据</li>
<li><strong>分页浏览</strong>: 支持自定义每页显示条数</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/5adfb271b1f549d588188c5861d9b7f020260608170455811.png" alt="" /></p></section><section><h3>3. 执行 SQL 查询<a href="#3-执行-sql-查询"><span>#</span></a></h3><p>点击顶部菜单的「SQL」标签，打开查询编辑器：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/5e078fadd42a49ef96696094c7e1b94820260608165959491.png" alt="" /></p><p>功能特性：</p><ul>
<li><strong>语法高亮</strong>: SQL 关键字自动高亮</li>
<li><strong>智能提示</strong>: 输入表名、字段名自动提示</li>
<li><strong>格式化</strong>: 一键美化 SQL 格式</li>
<li><strong>执行计划</strong>: 查看 SQL 执行计划</li>
<li><strong>结果导出</strong>: 支持导出为 CSV、JSON、Markdown 等格式</li>
</ul></section><section><h3>4. 使用 AI 助手<a href="#4-使用-ai-助手"><span>#</span></a></h3><p>DBX 内置了 AI 助手，可以帮助你：</p><p><strong>自然语言转 SQL</strong></p><p>在 AI 助手中输入：“查询所有用户，按注册时间倒序排列，只显示前 10 条”</p><p>AI 会生成：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>SELECT</span><span> * </span><span>FROM</span><span> users</span></div></div><div><div><div>2</div></div><div><span>ORDER BY</span><span> created_at </span><span>DESC</span></div></div><div><div><div>3</div></div><div><span>LIMIT</span><span> </span><span>10</span><span>;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>SQL 解释</strong></p><p>选中一段复杂的 SQL，点击「解释」按钮，AI 会用通俗语言解释这段 SQL 的作用。</p><p><strong>优化建议</strong></p><p>AI 还可以分析你的 SQL，提供性能优化建议。</p></section><section><h3>5. Redis 浏览器<a href="#5-redis-浏览器"><span>#</span></a></h3><p>对于 Redis 数据库，DBX 提供了专门的浏览器界面：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/1cc11cb20a614a2fae7380da888c2c9920260608170846198.png" alt="" /></p><p>支持：</p><ul>
<li><strong>模式匹配搜索</strong>: 使用通配符搜索 key</li>
<li><strong>全数据类型支持</strong>: String、Hash、List、Set、ZSet</li>
<li><strong>可视化编辑</strong>: 直接编辑 value 内容</li>
<li><strong>TTL 管理</strong>: 查看和修改过期时间</li>
</ul></section><section><h3>6. MongoDB 浏览器<a href="#6-mongodb-浏览器"><span>#</span></a></h3><p>对于 MongoDB 数据库支持：</p><ul>
<li><strong>文档增删改查</strong>: 完整的 CRUD 操作</li>
<li><strong>分页浏览</strong>: 高效浏览大量文档</li>
<li><strong>JSON 编辑</strong>: 原生 JSON 编辑支持</li>
<li><strong>聚合管道</strong>: 可视化构建聚合查询</li>
</ul></section></section>
<section><h2>🔥 我的使用感受<a href="#-我的使用感受"><span>#</span></a></h2><p>作为一个同时需要管理 MySQL、PostgreSQL、Redis、MongoDB 多种数据库的全栈开发者，DBX 真的彻底改变了我的工作流。</p><p>以前我的桌面上要开四五个不同的数据库管理工具，每个都占用几百 MB 内存，电脑风扇呼呼转。现在只需要一个 DBX，15MB 的体积，内存占用只有原来的零头，速度还更快了。</p><p>最让我惊喜的是它的 AI 助手功能。有时候忘记某个复杂查询怎么写，直接用自然语言描述需求，AI 就能生成准确的 SQL，还能解释现有查询的逻辑，简直是学习 SQL 的神器！</p><p>界面设计也非常舒服，没有传统数据库工具那种复杂的感觉，操作逻辑清晰，新手也能快速上手。深色模式对夜间开发特别友好，长时间使用眼睛也不累。</p><p>前几天我用它优化了一个慢查询，AI 助手分析了执行计划后，建议我添加一个复合索引，查询时间从 2 秒降到了 50 毫秒，效果立竿见影！</p></section>
<section><h2>💡 与其他工具对比<a href="#-与其他工具对比"><span>#</span></a></h2>

<table><thead><tr><th>特性</th><th>DBX</th><th>Navicat</th><th>DataGrip</th><th>DBeaver</th></tr></thead><tbody><tr><td>安装包大小</td><td>15MB</td><td>300MB+</td><td>500MB+</td><td>200MB+</td></tr><tr><td>内存占用</td><td>低</td><td>高</td><td>高</td><td>中</td></tr><tr><td>启动速度</td><td>快</td><td>慢</td><td>慢</td><td>中</td></tr><tr><td>价格</td><td>免费</td><td>付费</td><td>付费</td><td>免费 + 付费</td></tr><tr><td>AI 助手</td><td>✅</td><td>❌</td><td>✅</td><td>❌</td></tr><tr><td>开源</td><td>✅</td><td>❌</td><td>❌</td><td>✅</td></tr></tbody></table><p>从对比可以看出，DBX 在保持轻量的同时，功能并不逊色，而且还有 AI 助手加持，性价比超高。</p></section>
<section><h2>📝 总结<a href="#-总结"><span>#</span></a></h2><p>今天主要带大家了解了 DBX 这个开源数据库管理工具的完整功能和使用流程，该工具以”Tauri 2 + Vue 3”为核心技术优势，结合多数据库管理需求，通过 Rust 后端与现代化前端框架，形成了一套从轻量级安装包到全功能数据库管理的全链路解决方案。通过这套实践方案，开发者能够高效突破传统数据库工具占用高、启动慢的痛点——借助简洁的连接配置、直观的数据浏览、强大的 SQL 编辑器、智能的 AI 助手，无需安装多个重型工具，就能快速管理 40+ 种数据库（如本次演示的 MySQL、Redis、MongoDB）。无论是关系型数据库查询、NoSQL 数据浏览，还是 SSH 隧道连接、查询历史管理，都能通过统一界面完成，极大提升开发效率。在实际应用中，该工具不仅内存占用低、启动速度快，还完全免费开源，适配性远优于传统商业软件；特别是通过 AI 助手集成，有效解决了复杂 SQL 编写和学习的难题。同时，方案具备良好的扩展性——小伙伴们可以基于此扩展更多数据库类型支持，如 Oracle、Cassandra、Elasticsearch 等，进一步发挥轻量级工具在本地开发、远程运维、团队协作等领域的应用价值。感兴趣的小伙伴可以按照文中提供的步骤进行实践，根据实际数据库类型调整连接配置。今天的分享就到这里结束了，我们下一篇文章见。</p></section>
<section><h2>🌟 项目资源<a href="#-项目资源"><span>#</span></a></h2><p><strong>GitHub 地址</strong>: <a href="https://github.com/t8y2/dbx" target="_blank">https://github.com/t8y2/dbx</a></p><p><strong>官网</strong>: <a href="https://dbxio.com" target="_blank">https://dbxio.com</a></p><p><strong>Discord 社区</strong>: <a href="https://discord.gg/W7NyVDRt6a" target="_blank">https://discord.gg/W7NyVDRt6a</a></p><p><strong>QQ 群</strong>: 1087880322</p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p><p><strong>项目特色</strong>: 15MB 超小体积，支持 40+ 种数据库，内置 AI 助手，完全开源免费，本地优先保护隐私，是开发者必备的数据库管理神器。</p></section>
<section><h2>🎉 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你是不是已经跃跃欲试了？赶紧去 GitHub 下载体验一下这个轻量的数据库管理工具吧！</p><p>你平时都用哪些数据库管理工具？对 DBX 有什么期待？欢迎在评论区和我交流分享！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/X5APtop581xUNqIwcSM8_g?token=2029917947&amp;lang=zh_CN" target="_blank">离线OCR神器！这个工具让图片文字轻松提取</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/docker/trwebocr-intro/</id>
      <title type="text">离线OCR神器！这个工具让图片文字轻松提取</title>
      <published>2026-06-01T00:00:00.000Z</published>
      <updated>2026-06-01T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/docker/trwebocr-intro/"/>
      <summary type="text">支持多语言，精准识别，完全本地化，保护隐私</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！需要提取图片文字的看过来！<a href="#朋友们需要提取图片文字的看过来"><span>#</span></a></h2><p>看到一张图片里有重要文字，想提取出来却没办法；或者需要识别身份证、名片上的信息，手动输入太麻烦…</p><p>今天给大家推荐一个神器——<strong>TrWebOCR</strong>，一个完全离线的OCR文字识别工具。用了它之后，提取图片文字再也不用求人了！</p></section>
<section><h2>什么是 TrWebOCR？<a href="#什么是-trwebocr"><span>#</span></a></h2><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/89fa13dda4d64958bf6eece71284f7daTrWebOCR%E4%BB%8B%E7%BB%8D.png" alt="" />
TrWebOCR 是一个完全离线的OCR文字识别工具，支持多语言，识别准确率高，可以私有化部署，保护隐私。</p></section>
<section><h2>为什么推荐 TrWebOCR？<a href="#为什么推荐-trwebocr"><span>#</span></a></h2><section><h3>1️⃣ 完全离线，隐私安全<a href="#1️⃣-完全离线隐私安全"><span>#</span></a></h3><p><strong>这是我最看重的一点！</strong> 所有文字识别都在本地浏览器中完成，图片数据不会上传到任何服务器。</p><ul>
<li><strong>隐私保护</strong>：处理身份证、合同、机密文档等敏感内容时，不用担心数据泄露</li>
<li><strong>无需网络</strong>：即使断网也能正常使用，出差旅行必备</li>
<li><strong>数据自主</strong>：所有识别结果都保存在本地，完全掌控自己的数据</li>
</ul></section><section><h3>2️⃣ 多语言支持，覆盖广泛<a href="#2️⃣-多语言支持覆盖广泛"><span>#</span></a></h3><p>TrWebOCR 支持多种语言识别，满足不同场景需求：</p><ul>
<li><strong>中文</strong>：完美支持简体中文和繁体中文</li>
<li><strong>英文</strong>：支持大小写字母和数字识别</li>
<li><strong>日文/韩文</strong>：支持日文汉字和平假名、韩文</li>
<li><strong>混合语言</strong>：支持一张图片中多种语言混合识别</li>
</ul></section><section><h3>3️⃣ 精准识别，效果出色<a href="#3️⃣-精准识别效果出色"><span>#</span></a></h3><p>基于 PaddleOCR 引擎，识别准确率非常高：</p><ul>
<li><strong>印刷体识别</strong>：书籍、报纸、海报等印刷文字，识别率超过 99%</li>
<li><strong>手写体识别</strong>：支持部分手写体识别（工整手写效果更佳）</li>
<li><strong>复杂场景</strong>：支持倾斜、模糊、低光照等复杂场景的文字识别</li>
<li><strong>多栏识别</strong>：智能分析文档布局，支持多栏文字识别</li>
</ul></section><section><h3>4️⃣ 部署简单，开箱即用<a href="#4️⃣-部署简单开箱即用"><span>#</span></a></h3><p>无论是个人使用还是团队部署，都非常简单：</p><ul>
<li><strong>Docker 一键部署</strong>：一条命令即可启动，无需复杂配置</li>
<li><strong>轻量级</strong>：镜像体积小，启动速度快，占用资源少</li>
<li><strong>跨平台</strong>：支持 Windows、macOS、Linux 等多种系统</li>
<li><strong>API 接口</strong>：提供 RESTful API，方便集成到其他系统</li>
</ul></section><section><h3>5️⃣ 功能丰富，实用便捷<a href="#5️⃣-功能丰富实用便捷"><span>#</span></a></h3><p>除了基础识别功能，还有很多实用特性：</p><ul>
<li><strong>批量识别</strong>：支持一次上传多张图片批量识别</li>
<li><strong>结果导出</strong>：支持复制、下载识别结果，支持多种格式</li>
<li><strong>实时预览</strong>：上传图片后实时显示识别结果</li>
<li><strong>移动端适配</strong>：支持手机浏览器访问，随时随地识别</li>
</ul></section><section><h3>6️⃣ 完全开源，免费使用<a href="#6️⃣-完全开源免费使用"><span>#</span></a></h3><p>TrWebOCR 是开源项目，完全免费：</p><ul>
<li><strong>代码透明</strong>：所有代码开源可审计，安全可靠</li>
<li><strong>社区活跃</strong>：开发者社区积极维护，持续更新迭代</li>
<li><strong>自由定制</strong>：可以根据自己的需求二次开发和定制</li>
</ul></section></section>
<section><h2>如何使用 TrWebOCR？<a href="#如何使用-trwebocr"><span>#</span></a></h2><section><h3>步骤1：下载并安装 TrWebOCR<a href="#步骤1下载并安装-trwebocr"><span>#</span></a></h3><p>首先，你需要下载并安装 TrWebOCR。TrWebOCR 支持 Docker 部署，这是最简单的方式。</p></section><section><h3>步骤2：配置 Docker Compose<a href="#步骤2配置-docker-compose"><span>#</span></a></h3><p>创建一个 <code>docker-compose.yml</code> 文件，内容如下：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>version</span><span>: </span><span>'3'</span></div></div><div><div><div>2</div></div><div><span>services</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>trwebocr</span><span>:</span></div></div><div><div><div>4</div></div><div><span>    </span><span>image</span><span>: </span><span>mmmz/trwebocr:latest</span></div></div><div><div><div>5</div></div><div><span>    </span><span>container_name</span><span>: </span><span>trwebocr</span></div></div><div><div><div>6</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>7</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>8</div></div><div><span><span>      </span></span><span>- </span><span>"18089:8089"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/a90a1318cbbb46d8860ccc26541b4eff20260601161256095.png" alt="" /></p></section><section><h3>步骤3：启动 TrWebOCR<a href="#步骤3启动-trwebocr"><span>#</span></a></h3><p>在终端中运行以下命令启动 TrWebOCR：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker-compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/161bce7459fc4de1be29f2eca6188dd320260601161228931.png" alt="" /></p></section><section><h3>步骤4：访问 TrWebOCR<a href="#步骤4访问-trwebocr"><span>#</span></a></h3><p>打开浏览器，访问 <code>http://localhost:8080</code>，你就可以看到 TrWebOCR 的界面了。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/03eecae1ef4a4fdf990552f32e71edb720260601161443614.png" alt="" /></p></section><section><h3>步骤5：开始识别<a href="#步骤5开始识别"><span>#</span></a></h3><p>点击上传按钮，选择要识别的图片，TrWebOCR 会自动识别图片中的文字。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/06/fc1eb62f08324e8199244d3403c92fb020260601161604295.png" alt="" /></p></section></section>
<section><h2>常见问题<a href="#常见问题"><span>#</span></a></h2><p>Q: TrWebOCR 支持哪些语言？
A: TrWebOCR 支持中文、英文、日文、韩文等多种语言。</p><p>Q: TrWebOCR 可以离线使用吗？
A: 可以，TrWebOCR 的所有功能都可以离线使用，不需要联网。</p><p>Q: TrWebOCR 的识别准确率如何？
A: TrWebOCR 的识别准确率非常高，可以满足大部分场景的需求。</p><p>Q: TrWebOCR 支持哪些图片格式？
A: TrWebOCR 支持 JPG、PNG、PDF 等多种格式。</p></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>学生党</strong>：提取教材上的文字，方便做笔记</li>
<li><strong>职场人士</strong>：处理扫描件、合同等文档</li>
<li><strong>设计师</strong>：提取图片中的文字参考</li>
<li><strong>任何人</strong>：需要提取图片文字的场景</li>
</ul></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ul>
<li><strong>图片质量影响识别效果</strong>：图片越清晰，识别准确率越高。</li>
<li><strong>首次启动需要加载模型</strong>：第一次启动 TrWebOCR 时，需要加载识别模型，可能需要一些时间，请耐心等待。</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 TrWebOCR 感兴趣，可以访问它的 GitHub 仓库：<a href="https://github.com/alisen39/TrWebOCR" target="_blank">https://github.com/alisen39/TrWebOCR</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你有没有遇到过需要提取图片文字的场景？使用 TrWebOCR 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/-6ioc1mDtG6vCPJDICIQ_g?token=2029917947&amp;lang=zh_CN" target="_blank">自建图床又一选择？这个工具让你打造个人图片分享平台！</a></li>
<li><a href="https://mp.weixin.qq.com/s/ZFVqlTkQNUjskgBo75dxvw?token=2029917947&amp;lang=zh_CN" target="_blank">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/chevereto-intro/</id>
      <title type="text">想要自建图床？这个工具让你打造个人图片分享平台！</title>
      <published>2026-05-29T00:00:00.000Z</published>
      <updated>2026-05-29T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/chevereto-intro/"/>
      <summary type="text">图床服务、图片分享、外链支持，打造个人图片平台</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！想要自建图床的看过来！<a href="#朋友们想要自建图床的看过来"><span>#</span></a></h2><p>不想依赖第三方图床；需要稳定的图片外链；想打造个人图片分享平台…</p><p>今天给大家推荐一个神器——<strong>Chevereto</strong>，一个开源的图床服务工具。自从用了它，我的图片分享终于自由了！</p></section>
<section><h2>什么是 Chevereto？<a href="#什么是-chevereto"><span>#</span></a></h2><p>Chevereto 是一个开源的图床服务工具，它可以让你搭建自己的图片分享平台，支持图片上传和外链分享。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/7d86c569ec054be48244fcda94180c9c20260529145837268.png" alt="" /></p></section>
<section><h2>为什么推荐 Chevereto？<a href="#为什么推荐-chevereto"><span>#</span></a></h2><section><h3>1️⃣ 图床服务<a href="#1️⃣-图床服务"><span>#</span></a></h3><p>专业的图床功能：</p><ul>
<li>支持批量上传</li>
<li>支持图片压缩</li>
<li>支持多种格式</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/784a53a046914fb78df82a9bf095339420260529150441082.png" alt="" /></p></section><section><h3>2️⃣ 外链支持<a href="#2️⃣-外链支持"><span>#</span></a></h3><p>方便分享图片：</p><ul>
<li>支持直接外链</li>
<li>支持多种链接格式</li>
<li>支持一键复制</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/eda1d293cc1d4b778f75518937431e9120260529150455915.png" alt="" /></p></section><section><h3>3️⃣ 多端支持<a href="#3️⃣-多端支持"><span>#</span></a></h3><p>随时随地访问：</p><ul>
<li>支持 Web 端访问</li>
<li>支持移动端访问</li>
<li>支持 API 访问</li>
</ul></section><section><h3>4️⃣ 用户管理<a href="#4️⃣-用户管理"><span>#</span></a></h3><p>支持多用户：</p><ul>
<li>支持用户注册</li>
<li>支持权限管理</li>
<li>支持访问统计</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/4936eb72eb5a40ff940455ff102e01db20260529145933611.png" alt="" /></p></section><section><h3>5️⃣ 完全开源<a href="#5️⃣-完全开源"><span>#</span></a></h3><p>Chevereto 是开源项目，完全免费使用：</p><ul>
<li>代码透明可审计</li>
<li>支持自定义修改</li>
<li>社区活跃持续更新</li>
</ul></section></section>
<section><h2>如何使用 Chevereto？<a href="#如何使用-chevereto"><span>#</span></a></h2><section><h3>步骤1：部署 Chevereto<a href="#步骤1部署-chevereto"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>database</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image</span><span>: </span><span>mariadb:jammy</span></div></div><div><div><div>4</div></div><div><span>    </span><span>networks</span><span>:</span></div></div><div><div><div>5</div></div><div><span><span>      </span></span><span>- </span><span>chevereto</span></div></div><div><div><div>6</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>/你的本地路径/database:/var/lib/mysql</span><span>  </span><span># 数据库也放本地</span></div></div><div><div><div>8</div></div><div><span>    </span><span>restart</span><span>: </span><span>always</span></div></div><div><div><div>9</div></div><div><span>    </span><span>healthcheck</span><span>:</span></div></div><div><div><div>10</div></div><div><span>      </span><span>test</span><span>: [</span><span>"CMD"</span><span>, </span><span>"healthcheck.sh"</span><span>, </span><span>"--su-mysql"</span><span>, </span><span>"--connect"</span><span>]</span></div></div><div><div><div>11</div></div><div><span>      </span><span>interval</span><span>: </span><span>10s</span></div></div><div><div><div>12</div></div><div><span>      </span><span>timeout</span><span>: </span><span>5s</span></div></div><div><div><div>13</div></div><div><span>      </span><span>retries</span><span>: </span><span>3</span></div></div><div><div><div>14</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>15</div></div><div><span>      </span><span>MYSQL_ROOT_PASSWORD</span><span>: </span><span>password</span></div></div><div><div><div>16</div></div><div><span>      </span><span>MYSQL_DATABASE</span><span>: </span><span>chevereto</span></div></div><div><div><div>17</div></div><div><span>      </span><span>MYSQL_USER</span><span>: </span><span>chevereto</span></div></div><div><div><div>18</div></div><div><span>      </span><span>MYSQL_PASSWORD</span><span>: </span><span>user_database_password</span></div></div><div><div><div>19</div></div><div>
</div></div><div><div><div>20</div></div><div><span>  </span><span>php</span><span>:</span></div></div><div><div><div>21</div></div><div><span>    </span><span>image</span><span>: </span><span>chevereto/chevereto:latest</span></div></div><div><div><div>22</div></div><div><span>    </span><span>networks</span><span>:</span></div></div><div><div><div>23</div></div><div><span><span>      </span></span><span>- </span><span>chevereto</span></div></div><div><div><div>24</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>25</div></div><div><span><span>      </span></span><span>- </span><span>/你的本地路径/images:/var/www/html/images</span><span>  </span><span># 图片存在这里</span></div></div><div><div><div>26</div></div><div><span>    </span><span>restart</span><span>: </span><span>always</span></div></div><div><div><div>27</div></div><div><span>    </span><span>depends_on</span><span>:</span></div></div><div><div><div>28</div></div><div><span>      </span><span>database</span><span>:</span></div></div><div><div><div>29</div></div><div><span>        </span><span>condition</span><span>: </span><span>service_healthy</span></div></div><div><div><div>30</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>31</div></div><div><span><span>      </span></span><span>- </span><span>"8080:80"</span></div></div><div><div><div>32</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>33</div></div><div><span>      </span><span>CHEVERETO_DB_HOST</span><span>: </span><span>database</span></div></div><div><div><div>34</div></div><div><span>      </span><span>CHEVERETO_DB_USER</span><span>: </span><span>chevereto</span></div></div><div><div><div>35</div></div><div><span>      </span><span>CHEVERETO_DB_PASS</span><span>: </span><span>user_database_password</span></div></div><div><div><div>36</div></div><div><span>      </span><span>CHEVERETO_DB_PORT</span><span>: </span><span>3306</span></div></div><div><div><div>37</div></div><div><span>      </span><span>CHEVERETO_DB_NAME</span><span>: </span><span>chevereto</span></div></div><div><div><div>38</div></div><div><span>      </span><span>CHEVERETO_HOSTNAME</span><span>: </span><span>hostname.com</span></div></div><div><div><div>39</div></div><div><span>      </span><span>CHEVERETO_HOSTNAME_PATH</span><span>: </span><span>/</span></div></div><div><div><div>40</div></div><div><span>      </span><span>CHEVERETO_HTTPS</span><span>: </span><span>0</span></div></div><div><div><div>41</div></div><div><span>      </span><span>CHEVERETO_MAX_POST_SIZE</span><span>: </span><span>2G</span></div></div><div><div><div>42</div></div><div><span>      </span><span>CHEVERETO_MAX_UPLOAD_SIZE</span><span>: </span><span>2G</span></div></div><div><div><div>43</div></div><div>
</div></div><div><div><div>44</div></div><div><span># 下面这部分 volumes 全部删掉！！</span></div></div><div><div><div>45</div></div><div><span># volumes:</span></div></div><div><div><div>46</div></div><div><span>#   database:</span></div></div><div><div><div>47</div></div><div><span>#   storage:</span></div></div><div><div><div>48</div></div><div>
</div></div><div><div><div>49</div></div><div><span>networks</span><span>:</span></div></div><div><div><div>50</div></div><div><span>  </span><span>chevereto</span><span>:</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>步骤2：启动服务<a href="#步骤2启动服务"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker-compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤3：配置图床<a href="#步骤3配置图床"><span>#</span></a></h3><p>访问 <code>http://localhost:8080</code>，完成初始化配置。</p></section><section><h3>步骤4：上传图片<a href="#步骤4上传图片"><span>#</span></a></h3><p>开始上传和分享你的图片！</p></section></section>
<section><h2>常见问题<a href="#常见问题"><span>#</span></a></h2><p>Q: Chevereto 需要什么配置？
A: Chevereto 对硬件要求不高，建议至少 2GB 内存。</p><p>Q: 支持哪些图片格式？
A: 支持 JPG、PNG、GIF 等常见格式。</p><p>Q: 需要联网吗？
A: 自建部署的话可以离线使用，但分享功能需要联网。</p><p>Q: 支持远程访问吗？
A: 支持，需要配置端口映射或使用反向代理。</p></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><ol>
<li>图床服务很稳定</li>
<li>外链功能很实用</li>
<li>管理功能很完善</li>
<li>开源免费，性价比很高</li>
</ol></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>博主</strong>：需要图片外链</li>
<li><strong>开发者</strong>：需要共享截图</li>
<li><strong>设计师</strong>：分享设计作品</li>
<li><strong>任何人</strong>：想要自建图床</li>
</ul></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ul>
<li><strong>存储容量</strong>：图片文件需要存储空间</li>
<li><strong>带宽考虑</strong>：外链会消耗带宽</li>
<li><strong>内容管理</strong>：注意管理上传内容</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 Chevereto 感兴趣，可以访问它的 GitHub 仓库：<a href="https://github.com/Chevereto/Chevereto" target="_blank">https://github.com/Chevereto/Chevereto</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们会选择GitHub做图床还是用Chevereto呢？</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=2054933560&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/xzF0cKZVAlU2Orzb_Qx9Bg?token=2054933560&amp;lang=zh_CN" target="_blank">替代Notion的最佳选择！这个开源工具太惊艳了</a></li>
<li><a href="https://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2054933560&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/piclist-github-intro/</id>
      <title type="text">保姆级教程！用PicList+GitHub搭建免费图床，超详细配置指南！</title>
      <published>2026-05-28T00:00:00.000Z</published>
      <updated>2026-05-28T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/piclist-github-intro/"/>
      <summary type="text">PicList、GitHub、图床、免费图床、图片托管</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！写博客的小伙伴看过来！<a href="#朋友们写博客的小伙伴看过来"><span>#</span></a></h2><p>写博客时图片托管是个大问题；免费图床不稳定；付费图床太贵…</p><p>今天给大家带来一个完美解决方案——<strong>PicList + GitHub 免费图床</strong>！这是我一直在用的图床方案，稳定又免费，配置也很简单，跟着我一步步来，包你学会！</p></section>
<section><h2>什么是 PicList？<a href="#什么是-piclist"><span>#</span></a></h2><p>PicList 是一款强大的云存储图床管理工具，支持多种云存储平台，包括 GitHub、Gitee、阿里云OSS、腾讯云COS等。它提供了简洁的界面和强大的功能，让图片上传和管理变得非常方便。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/f3467685b4c248809c9c78e23530f39020260528113800908.png" alt="" /></p></section>
<section><h2>为什么选择 PicList + GitHub？<a href="#为什么选择-piclist--github"><span>#</span></a></h2><section><h3>1️⃣ 完全免费<a href="#1️⃣-完全免费"><span>#</span></a></h3><p>GitHub 提供免费的仓库存储，对于个人博客使用完全足够。</p></section><section><h3>2️⃣ 稳定可靠<a href="#2️⃣-稳定可靠"><span>#</span></a></h3><p>GitHub 作为全球最大的代码托管平台，稳定性毋庸置疑。</p></section><section><h3>3️⃣ 访问速度快<a href="#3️⃣-访问速度快"><span>#</span></a></h3><p>配合 jsDelivr CDN，图片加载速度非常快。</p></section><section><h3>4️⃣ 永久存储<a href="#4️⃣-永久存储"><span>#</span></a></h3><p>只要 GitHub 不倒闭，你的图片就永远存在。</p></section><section><h3>5️⃣ 支持自定义域名<a href="#5️⃣-支持自定义域名"><span>#</span></a></h3><p>可以配置自定义域名，让图片链接更美观。</p></section></section>
<section><h2>准备工作<a href="#准备工作"><span>#</span></a></h2><p>在开始配置之前，我们需要准备以下东西：</p><ol>
<li><strong>一个 GitHub 账号</strong>（没有的话去注册一个）</li>
<li><strong>下载 PicList</strong>（官网：<a href="https://piclist.cn/app#%E4%B8%8B%E8%BD%BD%E5%AE%89%E8%A3%85%EF%BC%89" target="_blank">https://piclist.cn/app#下载安装）</a></li>
</ol></section>
<section><h2>详细配置教程<a href="#详细配置教程"><span>#</span></a></h2><section><h3>步骤1：创建 GitHub 仓库<a href="#步骤1创建-github-仓库"><span>#</span></a></h3><p>首先，我们需要在 GitHub 上创建一个专门用于存放图片的仓库。</p><ol>
<li>打开 GitHub 官网：<a href="https://github.com/,%E8%AE%BF%E9%97%AE%E4%B8%8D%E4%BA%86%E7%9A%84%E8%AF%9D%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%5BSteamTools" target="_blank">https://github.com/,访问不了的话，可以参考[SteamTools</a> 让你一键加速GitHub和Steam，告别网络问题](<a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=1876705190&amp;lang=zh_CN" target="_blank">https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=1876705190&amp;lang=zh_CN</a>) 这篇文章来访问github官网</li>
<li>登录你的账号</li>
<li>点击右上角的 <code>+</code> 号，选择 <code>New repository</code></li>
<li>填写仓库信息：
<ul>
<li><strong>Repository name</strong>：输入仓库名称，比如 <code>images</code> 或 <code>blog-images</code></li>
<li><strong>Description</strong>：可以填写描述，比如 <code>博客图片仓库</code></li>
<li><strong>Visibility</strong>：选择 <code>Public</code>（公开仓库才能被访问）</li>
<li>勾选 <code>Add a README file</code>（可选）</li>
</ul>
</li>
<li>点击 <code>Create repository</code> 创建仓库</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/7ed0ba58ea6a4cb3b60d76f8feee1ddb20260528113944893.png" alt="" /></p></section><section><h3>步骤2：生成 GitHub Access Token<a href="#步骤2生成-github-access-token"><span>#</span></a></h3><p>接下来，我们需要生成一个 Access Token，用于 PicList 访问你的 GitHub 仓库。</p><ol>
<li>点击右上角你的头像，选择 <code>Settings</code>
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/37ef650d19ab4a968ddff815bd9ddcb020260528114250532.png" alt="" /></li>
<li>在左侧菜单中找到 <code>Developer settings</code>
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/173fff3bd9804ecbb13981dd4cf03b7a20260528114319044.png" alt="" /></li>
<li>点击 <code>Personal access tokens</code></li>
<li>点击 <code>Tokens (classic)</code>（注意：一定要选 classic 类型）</li>
<li>点击 <code>Generate new token</code>
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/7640ece829a445b59eb022b2c9fef12c20260528114514710.png" alt="" /></li>
<li>填写信息：
<ul>
<li><strong>Note</strong>：输入描述，比如 <code>PicList Token</code></li>
<li><strong>Expiration</strong>：选择 token 的有效期，建议选 <code>No expiration</code>（永不过期）</li>
<li><strong>Select scopes</strong>：勾选以下权限：
<ul>
<li><code>repo</code>（完全控制仓库）</li>
<li><code>workflow</code>（可选，如果需要）</li>
</ul>
</li>
</ul>
</li>
<li>点击 <code>Generate token</code>
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/06d54edb6332494e8f13097119e73bee20260528114631369.png" alt="" /></li>
<li><strong>重要</strong>：复制生成的 token，这个 token 只会显示一次，一定要保存好！</li>
</ol></section><section><h3>步骤3：下载并安装 PicList<a href="#步骤3下载并安装-piclist"><span>#</span></a></h3><ol>
<li>访问 PicList 官网：<a href="https://piclist.cn/" target="_blank">https://piclist.cn/</a></li>
<li>根据你的系统下载对应的版本（Windows/macOS/Linux）</li>
<li>安装并打开 PicList</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/907647640bda4a9c9a3e46c5b6dfa5aa20260528114728332.png" alt="" /></p></section><section><h3>步骤4：配置 PicList 图床<a href="#步骤4配置-piclist-图床"><span>#</span></a></h3><p>打开 PicList 后，我们来配置 GitHub 图床。</p><ol>
<li>点击左侧菜单栏的 <code>图床设置</code></li>
<li>在图床列表中，找到 <code>GitHub</code>，点击进入配置页面
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/de6a38692dc14f11baa77f2034a0cc1620260528114805303.png" alt="" /></li>
<li>填写配置信息：</li>
</ol><section><h4>仓库配置<a href="#仓库配置"><span>#</span></a></h4><ul>
<li><strong>仓库所有者</strong>：你的 GitHub 用户名（比如 <code>username</code>）</li>
<li><strong>仓库名称</strong>：你刚创建的仓库名（比如 <code>images</code>）</li>
<li><strong>分支</strong>：默认 <code>main</code> 或 <code>master</code>（看你仓库的默认分支）</li>
<li><strong>Token</strong>：粘贴你刚才生成的 Access Token</li>
<li><strong>路径</strong>：图片存放的目录，比如 <code>images/</code>（注意后面要有斜杠）</li>
<li><strong>自定义域名</strong>：
<ul>
<li>默认留空，使用 GitHub 原生域名</li>
<li>如果想使用 jsDelivr CDN，填 <code>https://cdn.jsdelivr.net/gh/用户名/仓库名</code></li>
<li>比如：<code>https://gcore.jsdelivr.net/gh/wangbin-blog/images@main</code></li>
</ul>
</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/a6d611b1a62749458a2fc725e7520b7d20260528114944849.png" alt="" /></p></section><section><h4>其他配置<a href="#其他配置"><span>#</span></a></h4><ul>
<li><strong>存储区域</strong>：默认即可</li>
<li><strong>超时时间</strong>：默认 30 秒即可</li>
<li><strong>文件命名</strong>：选择你喜欢的命名方式，推荐 <code>时间戳</code> 或 <code>原文件名</code></li>
</ul><ol>
<li>点击 <code>测试上传</code>，如果显示上传成功，说明配置正确！</li>
</ol></section></section><section><h3>步骤5：设置默认图床<a href="#步骤5设置默认图床"><span>#</span></a></h3><ol>
<li>配置完成后，回到图床列表</li>
<li>找到你刚配置的 GitHub 图床</li>
<li>点击右侧的 <code>设为默认</code></li>
<li>这样每次上传图片都会默认使用这个图床</li>
</ol><p><img alt="" /></p></section></section>
<section><h2>使用 PicList 上传图片<a href="#使用-piclist-上传图片"><span>#</span></a></h2><p>配置完成后，使用就非常简单了！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/9f2e6c9dfa4a475880ba370487724b9220260528134230904.png" alt="" /></p><section><h3>方法1：拖拽上传<a href="#方法1拖拽上传"><span>#</span></a></h3><ol>
<li>打开 PicList 的主界面</li>
<li>直接将图片拖拽到界面中</li>
<li>上传完成后，会自动复制图片链接到剪贴板</li>
</ol></section><section><h3>方法2：快捷键上传<a href="#方法2快捷键上传"><span>#</span></a></h3><ol>
<li>点击右下角的 PicList 图标</li>
<li>选择 <code>上传图片</code></li>
<li>选择要上传的图片即可</li>
</ol></section><section><h3>方法3：右键菜单上传<a href="#方法3右键菜单上传"><span>#</span></a></h3><ol>
<li>在文件管理器中右键点击图片</li>
<li>选择 <code>PicList 上传图片</code></li>
</ol></section><section><h3>方法4：剪贴板上传<a href="#方法4剪贴板上传"><span>#</span></a></h3><ol>
<li>使用截图工具截取图片（比如 Win+Shift+S）</li>
<li>按下 <code>Ctrl+V</code>（或 <code>Cmd+V</code>）直接粘贴到 PicList</li>
<li>图片会自动上传并复制链接</li>
</ol></section></section>
<section><h2>自定义链接格式<a href="#自定义链接格式"><span>#</span></a></h2><p>如果你想自定义图片链接的格式，可以这样设置：</p><ol>
<li>进入图床设置页面</li>
<li>找到 <code>链接格式</code> 设置</li>
<li>可以自定义输出的链接格式，支持多种格式：
<ul>
<li>Markdown 格式：<code>![图片描述](图片链接)</code></li>
<li>HTML 格式：<code>&lt;img src="图片链接" alt="图片描述"&gt;</code></li>
<li>纯链接格式：<code>图片链接</code></li>
</ul>
</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/9ef10003a1e24621ae144ad2d890b33b20260528134312385.png" alt="" /></p></section>
<section><h2>使用 jsDelivr CDN 加速<a href="#使用-jsdelivr-cdn-加速"><span>#</span></a></h2><p>为了让图片加载更快，强烈推荐使用 jsDelivr CDN：</p><ol>
<li>
<p>在 GitHub 图床配置中，将 <code>自定义域名</code> 设置为：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://cdn.jsdelivr.net/gh/用户名/仓库名</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>比如：<code>https://cdn.jsdelivr.net/gh/wangbin/blog-images</code></p>
</li>
<li>
<p>jsDelivr 的优点：</p>
<ul>
<li>全球 CDN 加速</li>
<li>自动缓存</li>
<li>支持 HTTPS</li>
<li>完全免费</li>
</ul>
</li>
</ol></section>
<section><h2>常见问题<a href="#常见问题"><span>#</span></a></h2><p>Q: 为什么上传失败？
A: 请检查以下几点：</p><ol>
<li>Token 是否正确</li>
<li>Token 是否有 repo 权限</li>
<li>仓库是否为公开（Public）</li>
<li>网络是否正常</li>
</ol><p>Q: 图片链接无法访问？
A: 请检查：</p><ol>
<li>仓库是否为公开</li>
<li>文件路径是否正确</li>
<li>自定义域名是否配置正确</li>
</ol><p>Q: 可以使用私有仓库吗？
A: 不建议使用私有仓库，因为私有仓库的图片无法被外部访问。</p><p>Q: 存储空间有限制吗？
A: GitHub 免费版每个仓库有 1GB 空间限制，对于博客图片完全足够。</p><p>Q: 如何批量上传图片？
A: PicList 支持批量选择多张图片上传，直接拖拽多张图片即可。</p><p>Q: 如何管理已上传的图片？
A: 在 PicList 中点击左侧的 <code>相册</code>，可以查看和管理所有已上传的图片。</p></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>我使用 PicList + GitHub 图床已经好多年了，非常稳定：</p><ol>
<li><strong>上传速度快</strong>：拖拽上传非常方便</li>
<li><strong>链接格式多样</strong>：支持多种格式，复制即用</li>
<li><strong>管理方便</strong>：相册功能可以查看和管理所有图片</li>
<li><strong>完全免费</strong>：不用花一分钱</li>
</ol></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ul>
<li><strong>仓库设为公开</strong>：必须将仓库设置为 Public，否则图片无法被访问</li>
<li><strong>保护好 Token</strong>：Token 相当于你的密码，不要泄露给别人</li>
<li><strong>定期备份</strong>：虽然 GitHub 很稳定，但建议定期备份重要图片</li>
<li><strong>图片命名</strong>：建议使用有意义的文件名，方便管理</li>
</ul></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>使用 PicList + GitHub 搭建免费图床非常简单，总结一下步骤：</p><ol>
<li>创建 GitHub 公开仓库</li>
<li>生成 Access Token</li>
<li>配置 PicList</li>
<li>开始上传图片！</li>
</ol><p>这是一个非常完美的图床方案，推荐给所有需要图片托管的小伙伴！</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时都用什么图床？有没有遇到过图片链接失效的问题？欢迎在评论区分享你的经验！</p><p>如果你在配置过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=2054933560&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/xzF0cKZVAlU2Orzb_Qx9Bg?token=2054933560&amp;lang=zh_CN" target="_blank">替代Notion的最佳选择！这个开源工具太惊艳了</a></li>
<li><a href="https://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2054933560&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/bulk-crap-uninstaller-intro/</id>
      <title type="text">Windows卸载工具！这个工具让卸载软件更彻底！</title>
      <published>2026-05-27T00:00:00.000Z</published>
      <updated>2026-05-27T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/bulk-crap-uninstaller-intro/"/>
      <summary type="text">Windows卸载、批量卸载、软件清理、系统优化，Windows必备工具</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！Windows用户看过来！<a href="#朋友们windows用户看过来"><span>#</span></a></h2><p>卸载软件不彻底；残留文件难清理；想要批量卸载…</p><p>今天给大家推荐一个超级好用的工具——<strong>Bulk Crap Uninstaller</strong>，一个开源的Windows批量卸载工具。自从用了它，我的系统变得更干净了！</p></section>
<section><h2>什么是 Bulk Crap Uninstaller？<a href="#什么是-bulk-crap-uninstaller"><span>#</span></a></h2><p>Bulk Crap Uninstaller（简称BCUninstaller）是一个开源的Windows软件卸载工具，它可以批量卸载多个程序，清理残留文件和注册表项，是Windows系统清理的必备工具。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/b10d5539b1464fe896cee1dc09cb703d20260527111256991.png" alt="" /></p></section>
<section><h2>为什么推荐 Bulk Crap Uninstaller？<a href="#为什么推荐-bulk-crap-uninstaller"><span>#</span></a></h2><section><h3>1️⃣ 批量卸载<a href="#1️⃣-批量卸载"><span>#</span></a></h3><p>批量处理：</p><ul>
<li>支持批量选择多个程序</li>
<li>支持一键卸载多个软件</li>
<li>支持批量删除残留文件</li>
</ul></section><section><h3>2️⃣ 彻底清理<a href="#2️⃣-彻底清理"><span>#</span></a></h3><p>彻底卸载：</p><ul>
<li>支持清理残留文件</li>
<li>支持清理注册表项</li>
<li>支持清理空文件夹</li>
</ul></section><section><h3>3️⃣ 智能检测<a href="#3️⃣-智能检测"><span>#</span></a></h3><p>智能识别：</p><ul>
<li>支持检测捆绑软件</li>
<li>支持检测广告软件</li>
<li>支持检测恶意软件</li>
</ul></section><section><h3>4️⃣ 用户友好<a href="#4️⃣-用户友好"><span>#</span></a></h3><p>友好界面：</p><ul>
<li>支持图形界面</li>
<li>支持搜索过滤</li>
<li>支持排序功能</li>
</ul></section><section><h3>5️⃣ 完全开源<a href="#5️⃣-完全开源"><span>#</span></a></h3><p>BCUninstaller 是开源项目，完全免费使用：</p><ul>
<li>代码透明可审计</li>
<li>支持自定义修改</li>
<li>社区活跃持续更新</li>
</ul></section></section>
<section><h2>如何使用 Bulk Crap Uninstaller？<a href="#如何使用-bulk-crap-uninstaller"><span>#</span></a></h2><section><h3>步骤1：下载安装<a href="#步骤1下载安装"><span>#</span></a></h3><p>BCUninstaller 是<strong>便携软件</strong>，无需安装，下载即可使用：</p><ol>
<li>访问 GitHub 发布页：<a href="https://github.com/Klocman/Bulk-Crap-Uninstaller/releases" target="_blank">https://github.com/Klocman/Bulk-Crap-Uninstaller/releases</a></li>
<li>下载最新版本的 <code>BCUninstaller_x64.zip</code>（64位系统）或 <code>BCUninstaller_x86.zip</code>（32位系统）</li>
<li>解压到任意目录，双击 <code>BCUninstaller.exe</code> 即可运行
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/04eb42d9964648c9a01f0d54413eaa2720260527111714745.png" alt="" /></li>
</ol></section><section><h3>步骤2：首次启动与扫描<a href="#步骤2首次启动与扫描"><span>#</span></a></h3><p>打开软件后，BCUninstaller 会自动扫描系统，列出所有已安装的程序。扫描完成后，你会看到：</p><ul>
<li><strong>程序列表</strong>：显示所有已安装软件的名称、版本、大小、安装日期</li>
<li><strong>分类标签</strong>：顶部有「All」「User」「System」等标签，可快速筛选</li>
<li><strong>搜索框</strong>：支持按程序名称快速搜索
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/04ec0558a81e4a87983547c0bb56689320260527105231521.png" alt="" /></li>
</ul></section><section><h3>步骤3：选择要卸载的程序<a href="#步骤3选择要卸载的程序"><span>#</span></a></h3><p>选择程序的几种方式：</p><ol>
<li><strong>手动勾选</strong>：点击程序左侧的复选框</li>
<li><strong>批量选择</strong>：按住 <code>Ctrl</code> 或 <code>Shift</code> 键多选</li>
<li><strong>智能筛选</strong>：
<ul>
<li>点击「Junk」标签，筛选捆绑软件和广告软件</li>
<li>使用搜索框搜索特定程序
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/527fa5da20e94b9b8b17232621c5f67220260527105806337.png" alt="" /></li>
</ul>
</li>
</ol></section><section><h3>步骤4：开始批量卸载<a href="#步骤4开始批量卸载"><span>#</span></a></h3><ol>
<li>确认选中的程序无误后，点击顶部工具栏的「卸载」按钮，也可以选择「静默卸载」模式，这样会自动卸载所有选中的程序，不会弹出确认窗口提示。</li>
<li>在弹出的确认窗口中，再次确认卸载操作，点击「继续」。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/84f1c54a0fd6455b8c1cede2e332270720260527110014580.png" alt="" /></li>
<li>BCUninstaller 会依次运行每个程序的卸载程序
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/3a02be3ea5594fcb932d0883d27a586e20260527110148168.png" alt="" /></li>
<li>卸载完成后，BCUninstaller 会自动刷新程序列表，显示已卸载的程序。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/93cd867bbf1c4734bbbfb705997b3cd920260527110249066.png" alt="" /></li>
</ol></section><section><h3>步骤5：清理残留文件<a href="#步骤5清理残留文件"><span>#</span></a></h3><p>卸载完成后，BCUninstaller 会自动检测并清理残留：
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/41685219c71e459b97671194d36c576a20260527110339825.png" alt="" /></p><ol>
<li>勾选「Delete leftover files and registry entries」选项</li>
<li>点击「Cleanup」按钮</li>
<li>软件会扫描并删除残留的文件夹、文件和注册表项
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/6bd5dc3146334046b18dd88e93689df420260527110413745.png" alt="" /></li>
</ol></section><section><h3>步骤6：高级功能<a href="#步骤6高级功能"><span>#</span></a></h3><p><strong>强力卸载模式</strong>：</p><ul>
<li>对于无法正常卸载的顽固软件，右键点击程序，选择「Force Uninstall」</li>
<li>强力卸载会强制删除程序目录和注册表项</li>
</ul><p><strong>导出列表</strong>：</p><ul>
<li>点击「File」→「Export to CSV」，可导出已安装程序列表</li>
</ul><p><strong>刷新扫描</strong>：</p><ul>
<li>点击「Refresh」按钮，重新扫描系统</li>
</ul></section></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>Windows用户</strong>：清理系统</li>
<li><strong>电脑小白</strong>：简单操作</li>
<li><strong>系统管理员</strong>：批量管理</li>
<li><strong>任何人</strong>：需要卸载软件</li>
</ul></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ul>
<li><strong>备份数据</strong>：卸载前注意备份重要数据</li>
<li><strong>谨慎操作</strong>：注意选择要卸载的程序</li>
<li><strong>重启系统</strong>：卸载后建议重启系统</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 BCUninstaller 感兴趣，可以访问它的 GitHub：<a href="https://github.com/Klocman/Bulk-Crap-Uninstaller" target="_blank">https://github.com/Klocman/Bulk-Crap-Uninstaller</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时怎么卸载Windows软件？有没有用过 BCUninstaller？使用后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/0XXshpYjMd1lSXUxl9Jb2g?token=1876705190&amp;lang=zh_CN" target="_blank">上班摸鱼神器！这个工具让老板以为你在疯狂加班</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=2054933560&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/xzF0cKZVAlU2Orzb_Qx9Bg?token=2054933560&amp;lang=zh_CN" target="_blank">替代Notion的最佳选择！这个开源工具太惊艳了</a></li>
<li><a href="https://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2054933560&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a>
（注：文章部分信息来源于项目官方文档和个人使用体验）</li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/docker-packager-intro/</id>
      <title type="text">Docker打包神器！这个Electron工具让镜像管理更高效！</title>
      <published>2026-05-27T00:00:00.000Z</published>
      <updated>2026-05-27T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/docker-packager-intro/"/>
      <summary type="text">Docker、镜像打包、Electron、桌面工具，开发必备</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！Docker用户看过来！<a href="#朋友们docker用户看过来"><span>#</span></a></h2><p>镜像构建太复杂；多个环境配置难管理；想要一键打包导出…</p><p>今天给大家推荐一个神器——<strong>docker-packager</strong>，一个开源的Electron桌面工具，专门用于管理多个Docker镜像打包配置，让镜像构建和导出变得轻松简单！</p></section>
<section><h2>什么是 docker-packager？<a href="#什么是-docker-packager"><span>#</span></a></h2><p>docker-packager 是一个基于 <strong>Electron + React + TypeScript</strong> 开发的桌面应用，用于管理多个 Docker 镜像打包配置，并将镜像构建后导出为 <code>.tar</code> 文件。它支持多项目、多环境管理，支持 x64/arm64 架构打包，是 Docker 开发者的必备工具。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/3efb97819e734d24b67c7db4e2c4689620260527141935427.png" alt="" /></p></section>
<section><h2>为什么推荐 docker-packager？<a href="#为什么推荐-docker-packager"><span>#</span></a></h2><section><h3>1️⃣ 多项目管理<a href="#1️⃣-多项目管理"><span>#</span></a></h3><p>管理多个项目：</p><ul>
<li>支持添加多个项目配置</li>
<li>每个项目可配置多个环境（开发/测试/生产）</li>
<li>环境独立配置镜像名、Tag、目标架构</li>
</ul></section><section><h3>2️⃣ 一键打包<a href="#2️⃣-一键打包"><span>#</span></a></h3><p>简单的打包流程：</p><ul>
<li>支持单环境打包</li>
<li>支持批量顺序打包</li>
<li>支持批量并行打包</li>
<li>实时日志标签页展示</li>
</ul></section><section><h3>3️⃣ 多平台支持<a href="#3️⃣-多平台支持"><span>#</span></a></h3><p>跨平台构建：</p><ul>
<li>支持 x64 / arm64 架构打包</li>
<li>支持 Windows/macOS/Linux</li>
<li>底层执行 <code>docker build</code> 和 <code>docker save</code></li>
</ul></section><section><h3>4️⃣ 智能功能<a href="#4️⃣-智能功能"><span>#</span></a></h3><p>实用功能：</p><ul>
<li>预览 Docker 构建与导出命令</li>
<li>Docker Desktop 状态检测与启动</li>
<li>配置自动备份与历史还原</li>
<li>任务停止、输出文件复制与打开</li>
</ul></section><section><h3>5️⃣ 完全开源<a href="#5️⃣-完全开源"><span>#</span></a></h3><p>docker-packager 是开源项目，完全免费使用：</p><ul>
<li>代码透明可审计</li>
<li>支持自定义修改</li>
<li>社区活跃持续更新</li>
</ul></section></section>
<section><h2>如何使用 docker-packager？<a href="#如何使用-docker-packager"><span>#</span></a></h2><section><h3>步骤1：环境准备<a href="#步骤1环境准备"><span>#</span></a></h3><p>首先确保安装了以下依赖：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 1. 安装 Node.js 20+</span></div></div><div><div><div>2</div></div><div><span># 访问 https://nodejs.org/ 下载安装</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 2. 安装 Docker Desktop</span></div></div><div><div><div>5</div></div><div><span># 访问 https://www.docker.com/ 下载安装</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 验证 Docker</span></div></div><div><div><div>8</div></div><div><span>docker</span><span> </span><span>version</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤2：获取源码<a href="#步骤2获取源码"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/chongchong59699/docker-packager.git</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>docker-packager</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤3：开发运行<a href="#步骤3开发运行"><span>#</span></a></h3><p>进入 Electron 应用目录并启动开发环境：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>electron</span></div></div><div><div><div>2</div></div><div><span>npm</span><span> </span><span>install</span></div></div><div><div><div>3</div></div><div><span>npm</span><span> </span><span>run</span><span> </span><span>dev</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><code>npm run dev</code> 会启动 Vite 与 Electron 开发环境，打开应用界面。</p></section><section><h3>步骤4：打包发布<a href="#步骤4打包发布"><span>#</span></a></h3><section><h4>Windows Portable 版本<a href="#windows-portable-版本"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>electron</span></div></div><div><div><div>2</div></div><div><span>npm</span><span> </span><span>run</span><span> </span><span>pack:win</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>输出目录：<code>electron/release-build/&lt;timestamp&gt;/</code></p></section><section><h4>Windows 安装包<a href="#windows-安装包"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>electron</span></div></div><div><div><div>2</div></div><div><span>npm</span><span> </span><span>run</span><span> </span><span>pack:win:installer</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>macOS / Linux<a href="#macos--linux"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>electron</span></div></div><div><div><div>2</div></div><div><span>npm</span><span> </span><span>run</span><span> </span><span>pack:mac</span></div></div><div><div><div>3</div></div><div><span>npm</span><span> </span><span>run</span><span> </span><span>pack:linux</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h3>步骤5：使用应用<a href="#步骤5使用应用"><span>#</span></a></h3><p>打开应用后，你可以：</p><ol>
<li><strong>管理项目</strong>：添加多个项目配置</li>
<li><strong>配置环境</strong>：为每个项目添加不同环境（开发/测试/生产）</li>
<li><strong>设置参数</strong>：配置镜像名、Tag、目标架构（x64/arm64）、输出文件</li>
<li><strong>预览命令</strong>：查看 Docker 构建与导出命令预览</li>
<li><strong>开始打包</strong>：
<ul>
<li>单环境打包</li>
<li>批量顺序打包</li>
<li>批量并行打包
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/24b8798ad58046f388ee5569cda47cd920260527142550571.png" alt="" /></li>
</ul>
</li>
</ol></section><section><h3>步骤6：核心命令说明<a href="#步骤6核心命令说明"><span>#</span></a></h3><p>应用执行的核心命令等价于：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 构建镜像</span></div></div><div><div><div>2</div></div><div><span>docker</span><span> </span><span>build</span><span> </span><span>--platform</span><span> </span><span>&lt;platform&gt;</span><span> </span><span>-t</span><span> </span><span>&lt;image&gt;:&lt;tag&gt;</span><span> </span><span>.</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 导出为 tar 文件</span></div></div><div><div><div>5</div></div><div><span>docker</span><span> </span><span>save</span><span> </span><span>-o</span><span> </span><span>&lt;output.tar&gt;</span><span> </span><span>&lt;image&gt;:&lt;tag&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>架构映射：</p><ul>
<li><code>x64</code> / <code>x86_64</code> → <code>linux/amd64</code></li>
<li><code>arm64</code> / <code>arm</code> → <code>linux/arm64</code></li>
</ul></section><section><h3>步骤7：配置管理<a href="#步骤7配置管理"><span>#</span></a></h3><p>配置文件保存在 Electron <code>userData</code> 目录下的 <code>config/projects.json</code>：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"projects"</span><span>: [</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>4</div></div><div><span>      </span><span>"id"</span><span>: </span><span>"demo-service"</span><span>,</span></div></div><div><div><div>5</div></div><div><span>      </span><span>"name"</span><span>: </span><span>"Demo Service"</span><span>,</span></div></div><div><div><div>6</div></div><div><span>      </span><span>"path"</span><span>: </span><span>"E:</span><span>\\</span><span>project</span><span>\\</span><span>demo-service"</span><span>,</span></div></div><div><div><div>7</div></div><div><span>      </span><span>"environments"</span><span>: [</span></div></div><div><div><div>8</div></div><div><span><span>        </span></span><span>{</span></div></div><div><div><div>9</div></div><div><span>          </span><span>"id"</span><span>: </span><span>"prod"</span><span>,</span></div></div><div><div><div>10</div></div><div><span>          </span><span>"name"</span><span>: </span><span>"正式环境"</span><span>,</span></div></div><div><div><div>11</div></div><div><span>          </span><span>"image"</span><span>: </span><span>"demo-service"</span><span>,</span></div></div><div><div><div>12</div></div><div><span>          </span><span>"tag"</span><span>: </span><span>"1.0.0"</span><span>,</span></div></div><div><div><div>13</div></div><div><span>          </span><span>"architecture"</span><span>: </span><span>"x86_64"</span><span>,</span></div></div><div><div><div>14</div></div><div><span>          </span><span>"output"</span><span>: </span><span>"demo-service-1.0.0-x86_64.tar"</span></div></div><div><div><div>15</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>16</div></div><div><span><span>      </span></span><span>]</span></div></div><div><div><div>17</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>18</div></div><div><span><span>  </span></span><span>]</span></div></div><div><div><div>19</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section>
<section><h2>常见问题<a href="#常见问题"><span>#</span></a></h2><p>Q: 找不到 docker 命令怎么办？
A: 请安装 Docker Desktop，并确认 <code>docker</code> 已加入 PATH，运行 <code>docker version</code> 验证。</p><p>Q: Docker 未启动怎么办？
A: 可以在应用顶部点击”启动 Docker”，也可以手动启动 Docker Desktop，等待 daemon 就绪后再打包。</p><p>Q: Electron 打包失败怎么办？
A: 先执行 <code>npm install &amp;&amp; npm run build</code> 确认依赖和构建正常。Windows 签名相关问题可关闭强制签名。</p><p>Q: 打包后图标未生效怎么办？
A: 应用图标维护在 <code>electron/resources/icon.ico</code>，Windows 打包时由 <code>electron-builder.yml</code> 的 <code>win.icon</code> 配置。</p></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><ol>
<li><strong>界面友好</strong>：Electron 应用界面美观，操作直观</li>
<li><strong>管理方便</strong>：多项目多环境管理一目了然</li>
<li><strong>打包高效</strong>：批量并行打包节省大量时间</li>
<li><strong>功能实用</strong>：配置自动备份、命令预览等功能很贴心</li>
</ol></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>Docker开发者</strong>：需要频繁构建镜像</li>
<li><strong>运维人员</strong>：管理多个项目的镜像打包</li>
<li><strong>团队</strong>：统一管理项目的Docker配置</li>
<li><strong>个人开发者</strong>：简化镜像构建流程</li>
</ul></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ul>
<li><strong>环境要求</strong>：需要 Node.js 20+ 和 Docker Desktop</li>
<li><strong>配置备份</strong>：配置文件会自动备份，定期检查备份目录</li>
<li><strong>资源占用</strong>：并行打包时注意 CPU 和内存占用</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 docker-packager 感兴趣，可以访问它的 GitHub：<a href="https://github.com/chongchong59699/docker-packager" target="_blank">https://github.com/chongchong59699/docker-packager</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时怎么管理Docker镜像？有没有用过类似的桌面工具？使用后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=2054933560&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/xzF0cKZVAlU2Orzb_Qx9Bg?token=2054933560&amp;lang=zh_CN" target="_blank">替代Notion的最佳选择！这个开源工具太惊艳了</a></li>
<li><a href="https://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2054933560&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/docker/moodist-intro/</id>
      <title type="text">环境音效神器！这个工具让我的工作更专注</title>
      <published>2026-05-25T00:00:00.000Z</published>
      <updated>2026-05-25T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/docker/moodist-intro/"/>
      <summary type="text">免费开源可混搭的环境音效工具，提升工作效率和专注力</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>你有没有遇到过这些场景？</p><p>工作时环境太吵，无法集中注意力；想要营造氛围，却找不到合适的音效；市面上的音效软件太贵…</p><p>今天给大家推荐一个神器——<strong>Moodist</strong>，一个免费开源可混搭的环境音效工具。用了它之后，我的工作效率提升了很多！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/da06d0a593bc41e493feb23dbfedeb5cbanner.png" alt="" /></p></section>
<section><h2>为什么选择 Moodist？<a href="#为什么选择-moodist"><span>#</span></a></h2><section><h3>1️⃣ 完全免费<a href="#1️⃣-完全免费"><span>#</span></a></h3><p>没有任何隐藏费用，所有功能全部免费使用。</p></section><section><h3>2️⃣ 音效丰富<a href="#2️⃣-音效丰富"><span>#</span></a></h3><p>提供多种环境音效，满足不同场景需求。</p></section><section><h3>3️⃣ 完全开源<a href="#3️⃣-完全开源"><span>#</span></a></h3><p>代码完全开源，你可以自己定制和扩展。</p></section><section><h3>4️⃣ 功能强大<a href="#4️⃣-功能强大"><span>#</span></a></h3><p>支持音效混搭、定时关闭、音量调节等功能。</p></section><section><h3>5️⃣ 跨平台<a href="#5️⃣-跨平台"><span>#</span></a></h3><p>支持多种操作系统。</p></section></section>
<section><h2>主要功能介绍<a href="#主要功能介绍"><span>#</span></a></h2><section><h3>🎵 音效库<a href="#-音效库"><span>#</span></a></h3><ul>
<li>提供多种环境音效</li>
<li>包括白噪音、森林、雨声、咖啡馆等</li>
<li>可以自定义音效</li>
</ul></section><section><h3>🎚️ 音效混搭<a href="#️-音效混搭"><span>#</span></a></h3><ul>
<li>可以同时播放多种音效</li>
<li>支持音量独立调节</li>
<li>可以保存音效组合</li>
</ul></section><section><h3>⏱️ 定时功能<a href="#️-定时功能"><span>#</span></a></h3><ul>
<li>支持定时关闭</li>
<li>可以设置倒计时</li>
<li>支持睡眠模式</li>
</ul></section><section><h3>📱 多端支持<a href="#-多端支持"><span>#</span></a></h3><ul>
<li>支持 Web 端访问</li>
<li>支持桌面端应用</li>
<li>可以作为浏览器插件</li>
</ul></section><section><h3>🔄 同步功能<a href="#-同步功能"><span>#</span></a></h3><ul>
<li>支持音效组合同步</li>
<li>可以保存和分享配置</li>
<li>支持云端备份</li>
</ul></section></section>
<section><h2>怎么部署？<a href="#怎么部署"><span>#</span></a></h2><p>部署非常简单，用 Docker 一键搞定：</p><p><strong>使用 Docker 命令</strong>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span>  </span><span>--name</span><span> </span><span>moodist</span><span>  </span><span>-p</span><span> </span><span>8080:8080</span><span>  </span><span>ghcr.io/remvze/moodist:latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后访问 <a href="http://localhost:8080" target="_blank">http://localhost:8080</a> 就能使用了。</p><p><strong>使用 Docker Compose（推荐）</strong>：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>moodist</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image</span><span>: </span><span>ghcr.io/remvze/moodist:latest</span></div></div><div><div><div>4</div></div><div><span>    </span><span>container_name</span><span>: </span><span>moodist</span></div></div><div><div><div>5</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>6</div></div><div><span><span>      </span></span><span>- </span><span>"8080:8080"</span></div></div><div><div><div>7</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span><span>  </span><span># 可选，推荐加上，让容器自动重启</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>启动服务：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后访问 <a href="http://localhost:8080" target="_blank">http://localhost:8080</a> 就能使用了。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/90a0ea6b761e497cb8a01d1000f1295520260525140225609.png" alt="" /></p></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ol>
<li><strong>学生党</strong>：学习时营造专注氛围</li>
<li><strong>职场人士</strong>：工作时提高效率</li>
<li><strong>创作者</strong>：激发灵感，提升创造力</li>
<li><strong>任何人</strong>：想要一个更好的工作或学习环境</li>
</ol></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>Moodist 是一个非常优秀的开源环境音效工具，功能强大、音效丰富、完全免费。如果你想要提高专注力，一定要试试它！</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你平时工作或学习时喜欢什么环境音效？欢迎在评论区分享！</p><hr /><p><strong>项目地址</strong>：<a href="https://github.com/remvze/moodist" target="_blank">https://github.com/remvze/moodist</a></p><p><strong>官方网站</strong>：<a href="https://moodist.mvze.net/" target="_blank">https://moodist.mvze.net/</a></p><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/0XXshpYjMd1lSXUxl9Jb2g?token=1876705190&amp;lang=zh_CN" target="_blank">上班摸鱼神器！这个工具让老板以为你在疯狂加班</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=2054933560&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/xzF0cKZVAlU2Orzb_Qx9Bg?token=2054933560&amp;lang=zh_CN" target="_blank">替代Notion的最佳选择！这个开源工具太惊艳了</a></li>
<li><a href="https://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2054933560&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/projectsend-intro/</id>
      <title type="text">文件分发神器！这个工具让文件分享更安全</title>
      <published>2026-05-25T00:00:00.000Z</published>
      <updated>2026-05-25T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/projectsend-intro/"/>
      <summary type="text">安全分发文件并精准控制权限，让文件分享更可控</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！需要安全分享文件的看过来！<a href="#朋友们需要安全分享文件的看过来"><span>#</span></a></h2><p>有没有遇到过这些问题：</p><p><strong>文件分享不安全？</strong><br />
<strong>无法控制文件访问权限？</strong><br />
<strong>需要追踪文件下载情况？</strong></p><p>今天给大家推荐一个神器——<strong>ProjectSend</strong>，一个安全的文件分发工具，让文件分享更可控！</p></section>
<section><h2>什么是 ProjectSend？<a href="#什么是-projectsend"><span>#</span></a></h2><p>ProjectSend 是一个开源的文件分发工具，可以帮助你安全地分享文件给特定用户，支持权限控制、下载追踪等功能。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/3374b81f77134e97a22fb38f64b6814620260526140953896.png" alt="" /></p></section>
<section><h2>为什么推荐 ProjectSend？<a href="#为什么推荐-projectsend"><span>#</span></a></h2><section><h3>1️⃣ 权限控制<a href="#1️⃣-权限控制"><span>#</span></a></h3><p>可以精确控制谁可以访问文件。</p></section><section><h3>2️⃣ 下载追踪<a href="#2️⃣-下载追踪"><span>#</span></a></h3><p>追踪文件的下载情况，记录下载日志。</p></section><section><h3>3️⃣ 文件加密<a href="#3️⃣-文件加密"><span>#</span></a></h3><p>支持文件加密，保护文件安全。</p></section><section><h3>4️⃣ 多用户支持<a href="#4️⃣-多用户支持"><span>#</span></a></h3><p>支持多用户使用，适合团队协作。</p></section><section><h3>5️⃣ 完全开源<a href="#5️⃣-完全开源"><span>#</span></a></h3><p>代码开源，可以自己部署使用。</p></section></section>
<section><h2>如何使用 ProjectSend？<a href="#如何使用-projectsend"><span>#</span></a></h2><section><h3>步骤1：安装 ProjectSend<a href="#步骤1安装-projectsend"><span>#</span></a></h3><p>使用 Docker 部署（<strong>推荐</strong>）：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>version</span><span>: </span><span>"3"</span></div></div><div><div><div>2</div></div><div><span>services</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>projectsend</span><span>:</span></div></div><div><div><div>4</div></div><div><span>    </span><span>image</span><span>: </span><span>lscr.io/linuxserver/projectsend:latest</span></div></div><div><div><div>5</div></div><div><span>    </span><span>container_name</span><span>: </span><span>projectsend</span></div></div><div><div><div>6</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>PUID=1000</span></div></div><div><div><div>8</div></div><div><span><span>      </span></span><span>- </span><span>PGID=1000</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>- </span><span>TZ=Etc/UTC</span></div></div><div><div><div>10</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>- </span><span>./config:/config</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>- </span><span>./data:/data</span></div></div><div><div><div>13</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>14</div></div><div><span><span>      </span></span><span>- </span><span>18880:80</span></div></div><div><div><div>15</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>也可以上github，下载release版本。使用源码部署，这里就以docker-compose为例。</p></section><section><h3>步骤2：启动服务<a href="#步骤2启动服务"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker-compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤3：访问 ProjectSend<a href="#步骤3访问-projectsend"><span>#</span></a></h3><p>打开浏览器，访问 <code>http://localhost:18880</code>。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/19e66f45c4374335a179dce5d578337420260526140637126.png" alt="" /></p></section><section><h3>步骤4：配置系统<a href="#步骤4配置系统"><span>#</span></a></h3><p>按照向导配置数据库和管理员账号。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/8371c93f337d45f2b55fcd7cf7814abb20260526140741366.png" alt="" /></p></section><section><h3>步骤5：上传文件<a href="#步骤5上传文件"><span>#</span></a></h3><p>上传文件，设置访问权限和用户。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/da1af647e0404cfeb63097c8d85bf7a820260526140931056.png" alt="" /></p></section></section>
<section><h2>常见问题<a href="#常见问题"><span>#</span></a></h2><p>Q: ProjectSend 支持哪些权限控制？
A: 支持设置用户访问权限、下载次数限制、过期时间等。</p><p>Q: ProjectSend 可以追踪下载记录吗？
A: 支持，记录每个文件的下载日志。</p><p>Q: ProjectSend 需要付费吗？
A: 完全免费，开源软件。</p><p>Q: ProjectSend 支持文件加密吗？
A: 支持，上传的文件可以加密存储。</p></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>我用 ProjectSend 分享文件，体验非常好：</p><ol>
<li>权限控制精细，安全可靠</li>
<li>下载追踪，方便管理</li>
<li>文件加密，保护隐私</li>
<li>多用户支持，适合团队</li>
<li>开源免费，没有任何限制</li>
</ol></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>企业用户</strong>：安全分享企业文件</li>
<li><strong>团队用户</strong>：协作分享项目文件</li>
<li><strong>教育机构</strong>：分享学习资料</li>
<li><strong>普通用户</strong>：安全分享重要文件</li>
</ul></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ul>
<li><strong>安全配置</strong>：设置强密码，启用 HTTPS</li>
<li><strong>权限管理</strong>：合理设置用户权限</li>
<li><strong>定期备份</strong>：定期备份数据，防止丢失</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>GitHub：<a href="https://github.com/projectsend/projectsend" target="_blank">https://github.com/projectsend/projectsend</a><br />
官网地址：<a href="https://www.projectsend.org/" target="_blank">https://www.projectsend.org/</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你平时如何分享敏感文件？有没有遇到过安全问题？欢迎在评论区分享！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/0XXshpYjMd1lSXUxl9Jb2g?token=1876705190&amp;lang=zh_CN" target="_blank">上班摸鱼神器！这个工具让老板以为你在疯狂加班</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=2054933560&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/xzF0cKZVAlU2Orzb_Qx9Bg?token=2054933560&amp;lang=zh_CN" target="_blank">替代Notion的最佳选择！这个开源工具太惊艳了</a></li>
<li><a href="https://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2054933560&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/tinyrdm-intro/</id>
      <title type="text">Redis管理神器！这个工具让你的数据操作更高效</title>
      <published>2026-05-22T00:00:00.000Z</published>
      <updated>2026-05-22T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/tinyrdm-intro/"/>
      <summary type="text">轻量级、跨平台、功能强大，支持SSH隧道和Docker部署，开发者必备</summary>
      <content type="html"><![CDATA[<section><h2>🔴 朋友们！Redis管理工具选对了吗？看过来！<a href="#-朋友们redis管理工具选对了吗看过来"><span>#</span></a></h2><p>作为一个开发者，每天都要和 Redis 打交道：</p><p><strong>查看数据太麻烦，命令行记不住？</strong><br />
<strong>连接远程服务器太复杂，还要配置SSH？</strong><br />
<strong>数据量大了卡顿，列表加载半天？</strong></p><p>今天给大家推荐一个神器——<strong>Tiny RDM</strong>，一个现代化的轻量级 Redis 桌面管理器！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/185bde273d1b4422b4cce3e2ae1e05dbTiny%20RDM%20Redis%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7%E5%AE%A3%E4%BC%A0%E5%9B%BE.png" alt="" /></p></section>
<section><h2>🎯 什么是 Tiny RDM？<a href="#-什么是-tiny-rdm"><span>#</span></a></h2><p>Tiny RDM 是一个基于 Wails 框架开发的现代轻量级跨平台 Redis 桌面管理器，支持 Mac、Windows、Linux，还可以通过 Docker 部署 Web 版本。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/c95b560cd5dd4403ae0c257b0786e06e20260522102250956.png" alt="" /></p></section>
<section><h2>✨ 为什么推荐 Tiny RDM？<a href="#-为什么推荐-tiny-rdm"><span>#</span></a></h2><section><h3>1️⃣ 轻量级设计<a href="#1️⃣-轻量级设计"><span>#</span></a></h3><p>基于 Webview2 技术，不内嵌浏览器，启动快、占用内存少。</p></section><section><h3>2️⃣ 多连接方式支持<a href="#2️⃣-多连接方式支持"><span>#</span></a></h3><ul>
<li>✅ SSH Tunnel（SSH 隧道）</li>
<li>✅ SSL/TLS 加密连接</li>
<li>✅ Sentinel 模式</li>
<li>✅ Cluster 集群模式</li>
<li>✅ HTTP 代理 / SOCKS5 代理</li>
</ul></section><section><h3>3️⃣ 可视化数据操作<a href="#3️⃣-可视化数据操作"><span>#</span></a></h3><p>支持多种数据类型的 CRUD 操作：</p><ul>
<li>📝 String（字符串）</li>
<li>📋 List（列表）</li>
<li>🗂️ Hash（哈希）</li>
<li>📦 Set（集合）</li>
<li>📊 Sorted Set（有序集合）</li>
<li>🔄 Stream（流）</li>
</ul></section><section><h3>4️⃣ 强大的功能特性<a href="#4️⃣-强大的功能特性"><span>#</span></a></h3><ul>
<li>🔍 <strong>SCAN 分段加载</strong>：轻松处理百万级 key</li>
<li>📋 <strong>命令历史日志</strong>：记录所有操作</li>
<li>⚡ <strong>命令行模式</strong>：支持直接输入命令</li>
<li>🐢 <strong>慢日志查看</strong>：优化性能问题</li>
<li>🔄 <strong>发布/订阅</strong>：实时消息监听</li>
<li>📤 <strong>数据导入导出</strong>：方便数据迁移</li>
</ul></section><section><h3>5️⃣ 跨平台支持<a href="#5️⃣-跨平台支持"><span>#</span></a></h3><p>支持 Windows、macOS、Linux，还可以通过 Docker 部署 Web 版本！</p></section></section>
<section><h2>🚀 安装方式<a href="#-安装方式"><span>#</span></a></h2><section><h3>方式1：下载桌面客户端<a href="#方式1下载桌面客户端"><span>#</span></a></h3><p>访问 <a href="https://github.com/tiny-craft/tiny-rdm/releases" target="_blank">GitHub Releases</a> 下载对应平台的安装包：</p><ul>
<li><strong>Windows</strong>：<code>.exe</code> 安装包</li>
<li><strong>macOS</strong>：<code>.dmg</code> 镜像或 <code>.zip</code> 压缩包</li>
<li><strong>Linux</strong>：<code>.deb</code>、<code>.rpm</code> 或 AppImage</li>
</ul><p><strong>macOS 注意事项</strong>：如果安装后无法打开，执行以下命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>xattr</span><span> </span><span>-d</span><span> </span><span>com.apple.quarantine</span><span> </span><span>/Applications/Tiny</span><span>\ </span><span>RDM.app</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>或者上它的<a href="https://www.tinyrdm.com/zh/" target="_blank">官网</a>下载：
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/e263357b62634f05a5a52642bb860aae20260522102357928.png" alt="" /></p></section><section><h3>方式2：Docker 部署 Web 版本（适合服务端部署）<a href="#方式2docker-部署-web-版本适合服务端部署"><span>#</span></a></h3><p><strong>使用 Docker Compose（推荐）</strong>：</p><p>创建 <code>docker-compose.yml</code> 文件：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>tinyrdm</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image</span><span>: </span><span>ghcr.io/tiny-craft/tiny-rdm:latest</span></div></div><div><div><div>4</div></div><div><span>    </span><span>container_name</span><span>: </span><span>tinyrdm</span></div></div><div><div><div>5</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>6</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>"8086:8086"</span></div></div><div><div><div>8</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>- </span><span>ADMIN_USERNAME=admin</span></div></div><div><div><div>10</div></div><div><span><span>      </span></span><span>- </span><span>ADMIN_PASSWORD=tinyrdm</span></div></div><div><div><div>11</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>- </span><span>./data:/app/tinyrdm</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>启动服务：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>访问 <code>http://localhost:8086</code>，使用配置的账号密码登录。</p><p><strong>使用 Docker 命令</strong>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>--name</span><span> </span><span>tinyrdm</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>-p</span><span> </span><span>8086:8086</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>-e</span><span> </span><span>ADMIN_USERNAME=admin</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>-e</span><span> </span><span>ADMIN_PASSWORD=tinyrdm</span><span> </span><span>\</span></div></div><div><div><div>5</div></div><div><span>  </span><span>-v</span><span> </span><span>./data:/app/tinyrdm</span><span> </span><span>\</span></div></div><div><div><div>6</div></div><div><span>  </span><span>ghcr.io/tiny-craft/tiny-rdm:latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>🎮 使用教程<a href="#-使用教程"><span>#</span></a></h2><section><h3>步骤1：创建连接<a href="#步骤1创建连接"><span>#</span></a></h3><p>打开 Tiny RDM，点击左上角 “New Connection”：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/0dd66c3bbc33441889e6827d5eff828a20260522102815115.png" alt="" /></p></section><section><h3>步骤2：配置连接信息<a href="#步骤2配置连接信息"><span>#</span></a></h3><p>根据你的 Redis 服务器类型选择连接方式：</p><p><strong>普通连接</strong>：</p><ul>
<li>Host: 服务器地址</li>
<li>Port: 端口（默认 6379）</li>
<li>Password: 密码（如果有）
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/d0530bc84042403ba8a7cf8fe83b41fc20260522102942917.png" alt="" /></li>
</ul><p><strong>SSH 隧道连接</strong>：</p><ul>
<li>SSH Host: SSH 服务器地址</li>
<li>SSH Port: SSH 端口（默认 22）</li>
<li>SSH Username: 用户名</li>
<li>SSH Password/Key: 密码或密钥
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/93dc6cf20c9644d1ac729b2abf6a345520260522103015696.png" alt="" /></li>
</ul></section><section><h3>步骤3：管理数据<a href="#步骤3管理数据"><span>#</span></a></h3><p>连接成功后，你可以：</p><ol>
<li><strong>浏览 Key</strong>：左侧显示所有 key，支持搜索和过滤</li>
<li><strong>查看/编辑值</strong>：点击 key 查看详细内容，支持多种显示格式</li>
<li><strong>执行命令</strong>：使用底部命令行输入 Redis 命令</li>
<li><strong>批量操作</strong>：支持批量删除、导出等操作
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/f158581fb80942afaf0aca3bea72d73120260522103123014.png" alt="" /></li>
</ol></section><section><h3>步骤4：高级功能<a href="#步骤4高级功能"><span>#</span></a></h3><ul>
<li><strong>命令监控</strong>：实时查看执行的命令</li>
<li><strong>慢日志</strong>：查看慢查询命令</li>
<li><strong>发布/订阅</strong>：订阅频道接收消息</li>
<li><strong>数据导入导出</strong>：JSON 格式导入导出</li>
</ul></section></section>
<section><h2>📊 功能对比<a href="#-功能对比"><span>#</span></a></h2>

<table><thead><tr><th>功能</th><th>Tiny RDM</th><th>Redis Desktop Manager</th></tr></thead><tbody><tr><td>轻量级</td><td>✅ 非常轻量</td><td>❌ 较重</td></tr><tr><td>跨平台</td><td>✅ 全平台 + Web</td><td>✅ 桌面端</td></tr><tr><td>SSH 隧道</td><td>✅ 支持</td><td>❌ 不支持</td></tr><tr><td>集群模式</td><td>✅ 支持</td><td>✅ 支持</td></tr><tr><td>命令行</td><td>✅ 内置</td><td>✅ 支持</td></tr><tr><td>慢日志</td><td>✅ 支持</td><td>✅ 支持</td></tr><tr><td>开源免费</td><td>✅ 开源 GPL</td><td>❌ 收费</td></tr></tbody></table></section>
<section><h2>💡 实用技巧<a href="#-实用技巧"><span>#</span></a></h2><section><h3>技巧1：快速搜索 Key<a href="#技巧1快速搜索-key"><span>#</span></a></h3><p>使用 <code>*</code> 通配符搜索：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>user:*</span></div></div><div><div><div>2</div></div><div><span>order:*:status</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>技巧2：批量操作<a href="#技巧2批量操作"><span>#</span></a></h3><p>选中多个 key，右键选择批量删除或导出。</p></section><section><h3>技巧3：自定义解码器<a href="#技巧3自定义解码器"><span>#</span></a></h3><p>支持自定义数据编解码器，处理特殊格式的数据。</p></section><section><h3>技巧4：连接配置导入导出<a href="#技巧4连接配置导入导出"><span>#</span></a></h3><p>可以导出连接配置，方便在多台设备间同步。</p></section></section>
<section><h2>🛠️ 我的使用体验<a href="#️-我的使用体验"><span>#</span></a></h2><p>用了 Tiny RDM 之后：</p><p>✅ <strong>效率提升</strong>：可视化操作比命令行快太多<br />
✅ <strong>稳定性好</strong>：处理百万级 key 不卡顿<br />
✅ <strong>功能齐全</strong>：SSH 隧道、集群模式都支持<br />
✅ <strong>跨平台</strong>：在家用 macOS，公司用 Windows，无缝切换<br />
✅ <strong>开源免费</strong>：不用再找破解版了</p></section>
<section><h2>📦 项目地址<a href="#-项目地址"><span>#</span></a></h2><ul>
<li><strong>GitHub</strong>：<a href="https://github.com/tiny-craft/tiny-rdm" target="_blank">https://github.com/tiny-craft/tiny-rdm</a></li>
<li><strong>官网</strong>：<a href="https://tinyrdm.com/" target="_blank">https://tinyrdm.com/</a></li>
<li><strong>文档</strong>：<a href="https://tinyrdm.com/guide/" target="_blank">https://tinyrdm.com/guide/</a></li>
</ul></section>
<section><h2>💬 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你平时用什么工具管理 Redis？有没有遇到过什么痛点？</p><p>欢迎在评论区分享你的使用体验！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=2054933560&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/xzF0cKZVAlU2Orzb_Qx9Bg?token=2054933560&amp;lang=zh_CN" target="_blank">替代Notion的最佳选择！这个开源工具太惊艳了</a></li>
<li><a href="https://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2054933560&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/hexo-to-firefly-migration/</id>
      <title type="text">从Hexo到Astro Firefly：我的博客迁移之旅</title>
      <published>2026-05-21T00:00:00.000Z</published>
      <updated>2026-05-21T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/hexo-to-firefly-migration/"/>
      <summary type="text">详细对比Hexo与Astro框架，分享完整迁移过程和Firefly主题的Vercel/Cloudflare部署教程</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！还在纠结博客框架选择吗？看过来！<a href="#朋友们还在纠结博客框架选择吗看过来"><span>#</span></a></h2><p>作为一个写了几年博客的技术博主，我最近完成了从 <strong>Hexo</strong> 到 <strong>Astro Firefly</strong> 的迁移。今天就来和大家分享一下这次迁移的全过程，包括两个框架的对比、迁移步骤以及部署经验。</p></section>
<section><h2>为什么要从 Hexo 迁移到 Astro？<a href="#为什么要从-hexo-迁移到-astro"><span>#</span></a></h2><section><h3>📊 框架对比<a href="#-框架对比"><span>#</span></a></h3>

<table><thead><tr><th>特性</th><th>Hexo</th><th>Astro Firefly</th></tr></thead><tbody><tr><td><strong>技术栈</strong></td><td>Node.js + EJS/Pug</td><td>Astro + Svelte + Tailwind CSS</td></tr><tr><td><strong>构建速度</strong></td><td>中等</td><td>极快（增量构建）</td></tr><tr><td><strong>加载速度</strong></td><td>一般</td><td>超快（零JS默认）</td></tr><tr><td><strong>SEO优化</strong></td><td>依赖插件</td><td>内置优化</td></tr><tr><td><strong>开发体验</strong></td><td>静态渲染</td><td>混合渲染（SSR/SSG）</td></tr><tr><td><strong>生态系统</strong></td><td>插件丰富但陈旧</td><td>现代化且活跃</td></tr><tr><td><strong>TypeScript</strong></td><td>支持有限</td><td>原生支持</td></tr><tr><td><strong>热更新</strong></td><td>较慢</td><td>毫秒级响应</td></tr></tbody></table></section><section><h3>✨ Astro 的核心优势<a href="#-astro-的核心优势"><span>#</span></a></h3><ol>
<li><strong>更快的构建速度</strong>：Astro 的增量构建让开发体验大幅提升</li>
<li><strong>更好的性能</strong>：默认零 JS，首屏加载极快</li>
<li><strong>现代化技术栈</strong>：支持 React、Vue、Svelte 等多种框架</li>
<li><strong>内置优化</strong>：自动代码分割、图片优化、SEO 友好</li>
</ol></section></section>
<section><h2>🚀 迁移过程详解<a href="#-迁移过程详解"><span>#</span></a></h2><section><h3>步骤1：环境准备<a href="#步骤1环境准备"><span>#</span></a></h3><p>首先确保你的环境满足要求：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 检查 Node.js 版本（需 ≥ 22）</span></div></div><div><div><div>2</div></div><div><span>node</span><span> </span><span>-v</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 安装 pnpm（推荐）</span></div></div><div><div><div>5</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>-g</span><span> </span><span>pnpm</span></div></div><div><div><div>6</div></div><div><span>pnpm</span><span> </span><span>-v</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤2：Fork Firefly 仓库<a href="#步骤2fork-firefly-仓库"><span>#</span></a></h3><p>在 GitHub 上 Fork Firefly 仓库到你的账户。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Fork Firefly 仓库地址</span></div></div><div><div><div>2</div></div><div><span>https://github.com/CuteLeaf/Firefly</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/cdc4b989e4ae4098ab8213c341ca5bde20260521095656809.png" alt="" /></p></section><section><h3>步骤3：初始化 Firefly 项目<a href="#步骤3初始化-firefly-项目"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 克隆仓库（建议先 Fork 到自己的仓库）</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/你的用户名/Firefly.git</span></div></div><div><div><div>3</div></div><div><span>cd</span><span> </span><span>Firefly</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># 安装依赖</span></div></div><div><div><div>6</div></div><div><span>pnpm</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/cb9bae2000d5441ead76cbbb7856aca120260521095824658.png" alt="" /></p></section><section><h3>步骤4：配置博客基础信息<a href="#步骤4配置博客基础信息"><span>#</span></a></h3><p>编辑 <code>src/config/siteConfig.ts</code>：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>// 站点基础配置</span></div></div><div><div><div>2</div></div><div><span>export</span><span> </span><span>const</span><span> </span><span>SITE_CONFIG</span><span> </span><span>=</span><span> {</span></div></div><div><div><div>3</div></div><div><span>  </span><span>name</span><span>:</span><span> </span><span>"你的博客名称"</span><span>,</span></div></div><div><div><div>4</div></div><div><span>  </span><span>title</span><span>:</span><span> </span><span>"你的博客标题"</span><span>,</span></div></div><div><div><div>5</div></div><div><span>  </span><span>description</span><span>:</span><span> </span><span>"你的博客描述"</span><span>,</span></div></div><div><div><div>6</div></div><div><span>  </span><span>lang</span><span>:</span><span> </span><span>"zh_CN"</span><span>,</span></div></div><div><div><div>7</div></div><div><span>  </span><span>url</span><span>:</span><span> </span><span>"https://你的域名.com"</span><span>,</span></div></div><div><div><div>8</div></div><div><span>  </span><span>// ... 其他配置</span></div></div><div><div><div>9</div></div><div><span>};</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/4149e220b3334eb5a9edc731eee8577e20260521095929644.png" alt="" /></p></section><section><h3>步骤5：迁移文章内容<a href="#步骤5迁移文章内容"><span>#</span></a></h3><p>Hexo 的文章通常在 <code>source/_posts/</code> 目录，需要迁移到 Astro 的 <code>src/content/posts/</code> 目录。</p><p><strong>Frontmatter 转换示例：</strong></p><p><strong>Hexo 格式：</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>文章标题</span></div></div><div><div><div>3</div></div><div><span>date</span><span>: </span><span>2024-01-01 12:00:00</span></div></div><div><div><div>4</div></div><div><span>tags</span><span>: [</span><span>标签1</span><span>, </span><span>标签2</span><span>]</span></div></div><div><div><div>5</div></div><div><span>category</span><span>: </span><span>分类</span></div></div><div><div><div>6</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>Firefly 格式：</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>文章标题</span></div></div><div><div><div>3</div></div><div><span>published</span><span>: </span><span>2024-01-01</span></div></div><div><div><div>4</div></div><div><span>description</span><span>: </span><span>文章描述</span></div></div><div><div><div>5</div></div><div><span>image</span><span>: </span><span>./cover.jpg</span><span> </span><span># 或使用 "api" 启用随机封面</span></div></div><div><div><div>6</div></div><div><span>tags</span><span>: [</span><span>标签1</span><span>, </span><span>标签2</span><span>]</span></div></div><div><div><div>7</div></div><div><span>category</span><span>: </span><span>分类</span></div></div><div><div><div>8</div></div><div><span>draft</span><span>: </span><span>false</span></div></div><div><div><div>9</div></div><div><span>pinned</span><span>: </span><span>false</span></div></div><div><div><div>10</div></div><div><span>comment</span><span>: </span><span>true</span></div></div><div><div><div>11</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤6：处理图片和静态资源<a href="#步骤6处理图片和静态资源"><span>#</span></a></h3><p>将 Hexo 的 <code>source/images/</code> 迁移到 Astro 的 <code>public/</code> 目录。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 复制图片资源</span></div></div><div><div><div>2</div></div><div><span>cp</span><span> </span><span>-r</span><span> </span><span>../hexo-blog/source/images/</span><span>*</span><span> </span><span>public/images/</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤7：配置导航栏<a href="#步骤7配置导航栏"><span>#</span></a></h3><p>编辑 <code>src/config/navBarConfig.ts</code> 配置导航菜单组件.</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/b9212667022545b8886af01a23e00ae520260521100628467.png" alt="" /></p></section><section><h3>步骤7：配置侧边栏<a href="#步骤7配置侧边栏"><span>#</span></a></h3><p>和 <code>src/config/sidebarConfig.ts</code> 配置侧边栏组件。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/ef6a9cd05ce34e86a9058354194cc5cf20260521100648999.png" alt="" /></p><blockquote><p>更多个性化配置，请参考 <a href="https://docs-firefly.cuteleaf.cn/zh/guide/getting-started.html" target="_blank">Firefly 主题文档</a>。</p></blockquote></section><section><h3>步骤7：本地测试<a href="#步骤7本地测试"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 启动开发服务器</span></div></div><div><div><div>2</div></div><div><span>pnpm</span><span> </span><span>dev</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 构建生产版本</span></div></div><div><div><div>5</div></div><div><span>pnpm</span><span> </span><span>build</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 预览构建结果</span></div></div><div><div><div>8</div></div><div><span>pnpm</span><span> </span><span>preview</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>🛠️ 部署实战：Vercel + Cloudflare<a href="#️-部署实战vercel--cloudflare"><span>#</span></a></h2><ol>
<li><strong>登录 Vercel</strong>，点击 “New Project”</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/8a3cdc1e1d934f07a6c8a03f32554f5320260521100912249.png" alt="" />
2. <strong>导入仓库</strong>，选择你的 Firefly 仓库
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/f4c2c559dee449c9b36ef4c7d8f6a97520260521101013015.png" alt="" />
3. <strong>配置项目(默认已配置好，确认即可)</strong>：</p><ul>
<li>Framework Preset: <code>Astro</code></li>
<li>Root Directory: <code>./</code></li>
<li>Build Command: <code>pnpm run build</code></li>
<li>Output Directory: <code>dist</code></li>
</ul><ol>
<li>
<p><strong>点击 Deploy</strong>，等待部署完成
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/c768809f0d044b509565f28c6ba1282a20260521101141040.png" alt="" /></p>
</li>
<li>
<p><strong>配置域名</strong>（可选）：Vercel 域名在国内访问速度较慢，建议配置自定义域名。这里以 Cloudflare 为例，配置域名后即可访问。</p>
<ul>
<li>购买域名（如果还没有）</li>
<li>打开刚部署好的 Vercel 项目，点击 “Domains” 选项卡，添加自定义域名。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/98704c5b27164911a28cf76dbe8a5c7120260521101525124.png" alt="" /></li>
<li>在 Cloudflare 控制台添加自定义域名</li>
<li>配置 DNS 记录，将域名指向 Vercel 提供的 IP 地址
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/eb5c92a973e64e03a856a2063b3a0a5120260521102241129.png" alt="" /></li>
<li>等待 DNS 记录生效（通常需要 10-30 分分钟）</li>
</ul>
</li>
<li>
<p><strong>必应IndexNow</strong>（可选）：</p>
<ul>
<li>去 <a href="https://www.bing.com/webmasters/indexnow" target="_blank">必应 IndexNow</a> 点击 “Get Started” 按钮
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/e92aabbaa5e6409ba65dc65940c9cb6b20260521102743483.png" alt="" /></li>
<li>在打开的页面中，下滑到页面底部，有一个<code>Generate API Key</code> 区域，点击 “Generate” 按钮，即可获取 新的API Key，复制该 Key 到剪贴板，
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/8eff80d5a1694ef5a9af679f0633ae4c20260521103129108.png" alt="" /></li>
<li>然后到<code>blog根目录/public/</code>文件夹下创建一个<code>apikey.txt</code>文件，将复制的API Key 放入文件中,注意txt文件名也为key的内容。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/3fb2f67824b942d29a6831fa54032d2620260521103109073.png" alt="" /></li>
<li>安装必应 IndexNow 插件,在根目录执行<code>pnpm install astro-indexnow</code></li>
<li>配置插件,在<code>blog/astro.config.mjs</code>中添加以下内容：</li>
</ul>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>//  引入 IndexNow 插件</span></div></div><div><div><div>2</div></div><div><span>import</span><span> </span><span>indexnow</span><span> </span><span>from</span><span> </span><span>'astro-indexnow'</span><span>;</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>// 新增 IndexNow</span></div></div><div><div><div>6</div></div><div><span>indexnow</span><span>({</span></div></div><div><div><div>7</div></div><div><span>key</span><span>:</span><span> </span><span>'7axxxxxxxxxxxxxxxxxxxb43c1'</span><span>, </span><span>// 你的Key</span></div></div><div><div><div>8</div></div><div><span>// 可选：指定引擎（默认必应+Yandex）</span></div></div><div><div><div>9</div></div><div><span>keyLocation</span><span>:</span><span> </span><span>'/7axxxxxxxxxxxxxxxxxxxb43c1.txt'</span><span>,</span></div></div><div><div><div>10</div></div><div><span>// 可选：提交引擎（默认 Bing、Yandex）</span></div></div><div><div><div>11</div></div><div><span>engines</span><span>:</span><span> [</span><span>'bing'</span><span>, </span><span>'yandex'</span><span>],</span></div></div><div><div><div>12</div></div><div><span>// engines: ['bing']</span></div></div><div><div><div>13</div></div><div><span>})</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/6ccb713eabd1444f99b74e5fcbd79ec620260521103531704.png" alt="" /></p>
<ul>
<li>这么操作完后，每次执行<code>pnpm run build</code>，即可自动提交 IndexNow 插件（本地执行不会推送哦）</li>
</ul>
</li>
</ol></section>
<section><h2>🎨 Firefly 主题特色功能<a href="#-firefly-主题特色功能"><span>#</span></a></h2><section><h3>1. 双侧边栏布局<a href="#1-双侧边栏布局"><span>#</span></a></h3><p>Firefly 支持单侧边栏和双侧边栏配置，可以放置日历、目录、音乐播放器等组件。</p></section><section><h3>2. 多种文章布局<a href="#2-多种文章布局"><span>#</span></a></h3><p>支持列表布局、网格布局、瀑布流布局，可在配置文件中自由切换。</p></section><section><h3>3. 个性化配置<a href="#3-个性化配置"><span>#</span></a></h3><ul>
<li>主题色自定义（360° 色相调节）</li>
<li>亮暗色模式自动切换</li>
<li>自定义字体和壁纸</li>
<li>樱花飘落等动画特效</li>
</ul></section><section><h3>4. 功能丰富<a href="#4-功能丰富"><span>#</span></a></h3><ul>
<li>全文搜索（Pagefind）</li>
<li>文章置顶和推荐</li>
<li>评论系统集成</li>
<li>友链和相册功能</li>
</ul></section></section>
<section><h2>💡 迁移注意事项<a href="#-迁移注意事项"><span>#</span></a></h2><ol>
<li><strong>备份数据</strong>：迁移前务必备份 Hexo 博客的所有文件</li>
<li><strong>URL 重定向</strong>：如果文章 URL 结构变化，需要配置重定向规则</li>
<li><strong>评论迁移</strong>：如果使用 Disqus 等评论系统，需要迁移评论数据</li>
<li><strong>SEO 保留</strong>：确保文章的永久链接不变，或设置 301 重定向</li>
<li><strong>测试验证</strong>：迁移后全面测试各项功能是否正常</li>
</ol></section>
<section><h2>📝 总结<a href="#-总结"><span>#</span></a></h2><p>从 Hexo 迁移到 Astro Firefly 是一次非常愉快的体验：</p><ol>
<li><strong>开发体验提升</strong>：热更新速度极快，TypeScript 支持完善</li>
<li><strong>性能大幅提升</strong>：首屏加载时间减少了 60%+</li>
<li><strong>功能更加丰富</strong>：Firefly 主题提供了很多开箱即用的功能</li>
<li><strong>部署更加便捷</strong>：Vercel 和 Cloudflare 都提供了很好的支持</li>
</ol><p>如果你也在考虑迁移博客，不妨试试 Astro Firefly，相信你会喜欢上它的！</p></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><ul>
<li><strong>Firefly 主题</strong>：<a href="https://github.com/CuteLeaf/Firefly" target="_blank">https://github.com/CuteLeaf/Firefly</a></li>
<li><strong>在线预览</strong>：<a href="https://blog.huhaha.vip/">https://blog.huhaha.vip/</a></li>
<li><strong>使用文档</strong>：<a href="https://docs-firefly.cuteleaf.cn/" target="_blank">https://docs-firefly.cuteleaf.cn/</a></li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你现在使用的是什么博客框架？有没有考虑过迁移？欢迎在评论区分享你的想法！</p><p>如果你在迁移过程中遇到了什么问题，也可以在评论区留言，我会尽力帮助你！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=2054933560&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/xzF0cKZVAlU2Orzb_Qx9Bg?token=2054933560&amp;lang=zh_CN" target="_blank">替代Notion的最佳选择！这个开源工具太惊艳了</a></li>
<li><a href="https://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2054933560&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
</ul><p>（注：文章部分信息来源于 Firefly 官方文档和个人迁移经验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/genact-intro/</id>
      <title type="text">上班摸鱼神器！这个工具让老板以为你在疯狂加班</title>
      <published>2026-05-21T00:00:00.000Z</published>
      <updated>2026-05-21T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/genact-intro/"/>
      <summary type="text">模拟代码编译、系统启动、黑客界面等10+场景，让同事惊叹你的工作效率</summary>
      <content type="html"><![CDATA[<section><h2>👨💻 打工人摸鱼神器！老板再也看不出你在划水！<a href="#-打工人摸鱼神器老板再也看不出你在划水"><span>#</span></a></h2><p>作为一名合格的打工人，摸鱼是必备技能。但是——</p><p><strong>老板突然走到身后怎么办？</strong><br />
<strong>同事投来好奇的目光怎么办？</strong><br />
<strong>工作完成了想刷会儿手机怎么办？</strong></p><p>别慌！今天给大家推荐一个神器——<strong>Genact</strong>，让你的终端秒变”高端工作现场”！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/99fa782e7f304727ba988d6018ae8f45Genact%E4%B8%8A%E7%8F%AD%E6%91%B8%E9%B1%BC%E7%A5%9E%E5%99%A8.png" alt="" /></p></section>
<section><h2>🎭 什么是 Genact？<a href="#-什么是-genact"><span>#</span></a></h2><p>Genact 是一个开源的终端”演戏”工具，它能模拟各种工作场景：</p><ul>
<li>🚀 代码编译中…</li>
<li>📥 大型文件下载…</li>
<li>💻 系统启动日志…</li>
<li>🔐 黑客破解界面…</li>
<li>🐧 Linux 内核编译…</li>
</ul><p>运行之后，你的终端会疯狂输出各种专业的内容，看起来就像在执行什么超级复杂的任务！</p></section>
<section><h2>🎬 场景演示效果<a href="#-场景演示效果"><span>#</span></a></h2><section><h3>场景1：代码编译模式<a href="#场景1代码编译模式"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[COMPILER] 正在编译 Linux 内核...</span></div></div><div><div><div>2</div></div><div><span>[CC] arch/x86/kernel/entry_64.o</span></div></div><div><div><div>3</div></div><div><span>[CC] arch/x86/kernel/process_64.o</span></div></div><div><div><div>4</div></div><div><span>[CC] arch/x86/kernel/ptrace_64.o</span></div></div><div><div><div>5</div></div><div><span>[LD] vmlinux.o</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>OBJCOPY arch/x86/boot/compressed/vmlinux</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>Building, stage 2... [78%]</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/13cc37456e034a97a3d903875bfae31820260521174134517.png" alt="" /></p></section><section><h3>场景2：黑客破解模式<a href="#场景2黑客破解模式"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[HACKER] 正在入侵主服务器...</span></div></div><div><div><div>2</div></div><div><span>[SCAN] 端口扫描中... 22, 80, 443, 3306...</span></div></div><div><div><div>3</div></div><div><span>[CIPHER] 正在破解 RSA-2048 加密...</span></div></div><div><div><div>4</div></div><div><span>[ROOT] 获取管理员权限成功！</span></div></div><div><div><div>5</div></div><div><span>[UPLOAD] 正在上传数据... [████████████████] 94%</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/fa88a96aa0db42c390569cbc7200b5a020260521174002196.png" alt="" /></p></section><section><h3>场景3：系统启动模式<a href="#场景3系统启动模式"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[BIOS] Phoenix SecureCore(tm) Setup Utility</span></div></div><div><div><div>2</div></div><div><span>[POST] 内存检测: 16384MB OK</span></div></div><div><div><div>3</div></div><div><span>[GRUB] Loading Linux 6.5.0-rc1...</span></div></div><div><div><div>4</div></div><div><span>[INIT] 挂载根文件系统...</span></div></div><div><div><div>5</div></div><div><span>[NETWORK] eth0: 192.168.1.100/24</span></div></div><div><div><div>6</div></div><div><span>[LOGIN] 欢迎来到 Ubuntu 22.04 LTS</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/e7a4e150c23449fa9faaa0b9174ec3f720260521174228038.png" alt="" /></p></section></section>
<section><h2>🚀 全平台安装教程<a href="#-全平台安装教程"><span>#</span></a></h2><section><h3>Windows 用户<a href="#windows-用户"><span>#</span></a></h3><p><strong>方法1：使用 Scoop 安装（推荐）</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 如果没有安装 Scoop，先安装</span></div></div><div><div><div>2</div></div><div><span>Set-ExecutionPolicy</span><span><span> RemoteSigned </span><span>-</span><span>Scope CurrentUser</span></span></div></div><div><div><div>3</div></div><div><span><span>iwr </span><span>-</span><span>useb get.scoop.sh | iex</span></span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># 安装 Genact</span></div></div><div><div><div>6</div></div><div><span>scoop install genact</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方法2：下载预编译二进制</strong></p><ol>
<li>访问 <a href="https://github.com/svenstaro/genact/releases" target="_blank">GitHub Releases</a></li>
<li>下载 <code>genact-1.5.1-x86_64-pc-windows-msvc.exe</code></li>
<li>直接双击运行即可</li>
</ol></section><section><h3>macOS 用户<a href="#macos-用户"><span>#</span></a></h3><p><strong>方法1：使用 Homebrew 安装（推荐）</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>brew</span><span> </span><span>install</span><span> </span><span>genact</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方法2：使用 Port 安装（推荐）</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>port</span><span> </span><span>install</span><span> </span><span>genact</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Linux 用户<a href="#linux-用户"><span>#</span></a></h3><p><strong>通用方法 - 从 GitHub Releases 安装（推荐）</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>chmod</span><span> </span><span>+x</span><span> </span><span>genact-linux</span></div></div><div><div><div>2</div></div><div><span>./genact-linux</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>🎮 使用指南<a href="#-使用指南"><span>#</span></a></h2><section><h3>基本用法<a href="#基本用法"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 直接运行（随机场景）</span></div></div><div><div><div>2</div></div><div><span>genact</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 指定场景运行</span></div></div><div><div><div>5</div></div><div><span>genact</span><span> </span><span>--scenario</span><span> </span><span>compiler</span></div></div><div><div><div>6</div></div><div><span>genact</span><span> </span><span>--scenario</span><span> </span><span>download</span></div></div><div><div><div>7</div></div><div><span>genact</span><span> </span><span>--scenario</span><span> </span><span>boot</span></div></div><div><div><div>8</div></div><div><span>genact</span><span> </span><span>--scenario</span><span> </span><span>hacker</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>可选参数<a href="#可选参数"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 列出所有可用场景</span></div></div><div><div><div>2</div></div><div><span>genact</span><span> </span><span>--list</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 静音模式（无声音）</span></div></div><div><div><div>5</div></div><div><span>genact</span><span> </span><span>--quiet</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 指定速度（slow/normal/fast）</span></div></div><div><div><div>8</div></div><div><span>genact</span><span> </span><span>--speed</span><span> </span><span>fast</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 随机切换场景</span></div></div><div><div><div>11</div></div><div><span>genact</span><span> </span><span>--random</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>场景列表<a href="#场景列表"><span>#</span></a></h3>

<table><thead><tr><th>场景名称</th><th>效果描述</th></tr></thead><tbody><tr><td><code>compiler</code></td><td>模拟代码编译</td></tr><tr><td><code>download</code></td><td>模拟文件下载</td></tr><tr><td><code>boot</code></td><td>模拟系统启动</td></tr><tr><td><code>hacker</code></td><td>黑客破解界面</td></tr><tr><td><code>matrix</code></td><td>黑客帝国数字雨</td></tr><tr><td><code>antivirus</code></td><td>杀毒软件扫描</td></tr><tr><td><code>coffee</code></td><td>咖啡机制作中</td></tr><tr><td><code>simcity</code></td><td>SimCity 城市建造</td></tr><tr><td><code>weather</code></td><td>天气播报</td></tr><tr><td><code>cow</code></td><td>会说话的牛</td></tr></tbody></table></section></section>
<section><h2>⚠️ 使用注意事项<a href="#️-使用注意事项"><span>#</span></a></h2><ol>
<li><strong>演技要到位</strong>：不要盯着屏幕傻笑，假装很专注的样子</li>
<li><strong>音量控制</strong>：某些场景会有声音效果，记得静音</li>
<li><strong>适度使用</strong>：摸鱼虽好，可不要贪杯哦</li>
<li><strong>团队氛围</strong>：如果团队氛围好可以玩玩，严肃场合慎用</li>
</ol></section>
<section><h2>🎉 我的使用体验<a href="#-我的使用体验"><span>#</span></a></h2><p>用了 Genact 之后：</p><p>✅ <strong>安全感提升</strong>：老板路过再也不慌了<br />
✅ <strong>同事羡慕</strong>：“你在编译什么大型项目？”<br />
✅ <strong>趣味性增加</strong>：工作之余多了很多乐趣<br />
✅ <strong>完全无害</strong>：只是模拟输出，不执行任何操作</p></section>
<section><h2>📦 项目地址<a href="#-项目地址"><span>#</span></a></h2><p>GitHub：<a href="https://github.com/svenstaro/genact" target="_blank">https://github.com/svenstaro/genact</a><br />
Star 数：⭐ 10k+</p></section>
<section><h2>💬 互动时间<a href="#-互动时间"><span>#</span></a></h2><p>你平时上班怎么摸鱼？有没有被老板抓到过？<br />
使用 Genact 后有什么搞笑的经历？</p><p>欢迎在评论区分享你的故事！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=2054933560&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/xzF0cKZVAlU2Orzb_Qx9Bg?token=2054933560&amp;lang=zh_CN" target="_blank">替代Notion的最佳选择！这个开源工具太惊艳了</a></li>
<li><a href="https://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2054933560&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/docker/affine-intro/</id>
      <title type="text">替代Notion的最佳选择！这个开源工具太惊艳了</title>
      <published>2026-05-15T00:00:00.000Z</published>
      <updated>2026-05-15T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/docker/affine-intro/"/>
      <summary type="text">集文档管理与白板协作于一体，完全开源，数据本地化</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！寻找 Notion 替代品的看过来！<a href="#朋友们寻找-notion-替代品的看过来"><span>#</span></a></h2><p>Notion 虽然好用，但服务器在国外，访问速度慢；而且数据存在别人那里，总觉得不安全；最重要的是，免费版功能有限…</p><p>今天给大家推荐一个神器——<strong>AFFiNE</strong>，一个完全开源的笔记和协作工具。用了它之后，我果断放弃了 Notion！</p></section>
<section><h2>什么是 AFFiNE？<a href="#什么是-affine"><span>#</span></a></h2><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/859ecf9da84f4f0fa6b3249028919b2520260518090042142.png" alt="" />
AFFiNE 是一个完全开源的笔记和协作工具，集文档管理、白板协作、任务管理于一体，数据本地化，安全可靠。</p></section>
<section><h2>为什么推荐 AFFiNE？<a href="#为什么推荐-affine"><span>#</span></a></h2><section><h3>1️⃣ 完全开源<a href="#1️⃣-完全开源"><span>#</span></a></h3><p>代码完全开源，你可以自己部署，数据安全有保障。</p></section><section><h3>2️⃣ 功能强大<a href="#2️⃣-功能强大"><span>#</span></a></h3><p>集文档管理、白板协作、任务管理于一体，功能不输 Notion。</p></section><section><h3>3️⃣ 数据本地化<a href="#3️⃣-数据本地化"><span>#</span></a></h3><p>所有数据都存在本地，不用担心隐私泄露。</p></section><section><h3>4️⃣ 离线可用<a href="#4️⃣-离线可用"><span>#</span></a></h3><p>支持离线使用，随时随地都能工作。</p></section><section><h3>5️⃣ 颜值在线<a href="#5️⃣-颜值在线"><span>#</span></a></h3><p>界面设计非常现代简洁，使用体验很棒。</p></section></section>
<section><h2>如何使用 AFFiNE？<a href="#如何使用-affine"><span>#</span></a></h2><section><h3>步骤1：下载并安装 AFFiNE<a href="#步骤1下载并安装-affine"><span>#</span></a></h3><p>首先，你需要下载并安装 AFFiNE。AFFiNE 支持 Docker 部署，这是最简单的方式。</p></section><section><h3>步骤2：配置 Docker Compose<a href="#步骤2配置-docker-compose"><span>#</span></a></h3><p>创建一个 <code>docker-compose.yml</code> 文件，内容如下：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>name</span><span>: </span><span>affine</span></div></div><div><div><div>2</div></div><div><span>services</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>affine</span><span>:</span></div></div><div><div><div>4</div></div><div><span>    </span><span>image</span><span>: </span><span>ghcr.io/toeverything/affine:${AFFINE_REVISION:-stable}</span></div></div><div><div><div>5</div></div><div><span>    </span><span>container_name</span><span>: </span><span>affine_server</span></div></div><div><div><div>6</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>'${PORT:-3010}:3010'</span></div></div><div><div><div>8</div></div><div><span>    </span><span>depends_on</span><span>:</span></div></div><div><div><div>9</div></div><div><span>      </span><span>redis</span><span>:</span></div></div><div><div><div>10</div></div><div><span>        </span><span>condition</span><span>: </span><span>service_healthy</span></div></div><div><div><div>11</div></div><div><span>      </span><span>postgres</span><span>:</span></div></div><div><div><div>12</div></div><div><span>        </span><span>condition</span><span>: </span><span>service_healthy</span></div></div><div><div><div>13</div></div><div><span>      </span><span>affine_migration</span><span>:</span></div></div><div><div><div>14</div></div><div><span>        </span><span>condition</span><span>: </span><span>service_completed_successfully</span></div></div><div><div><div>15</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>16</div></div><div><span>      </span><span># custom configurations</span></div></div><div><div><div>17</div></div><div><span><span>      </span></span><span>- </span><span>${UPLOAD_LOCATION}:/root/.affine/storage</span></div></div><div><div><div>18</div></div><div><span><span>      </span></span><span>- </span><span>${CONFIG_LOCATION}:/root/.affine/config</span></div></div><div><div><div>19</div></div><div><span>    </span><span>env_file</span><span>:</span></div></div><div><div><div>20</div></div><div><span><span>      </span></span><span>- </span><span>.env</span></div></div><div><div><div>21</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>22</div></div><div><span><span>      </span></span><span>- </span><span>REDIS_SERVER_HOST=redis</span></div></div><div><div><div>23</div></div><div><span><span>      </span></span><span>- </span><span>DATABASE_URL=postgresql://${DB_USERNAME}:${DB_PASSWORD}@postgres:5432/${DB_DATABASE:-affine}</span></div></div><div><div><div>24</div></div><div><span><span>      </span></span><span>- </span><span>AFFINE_INDEXER_ENABLED=false</span></div></div><div><div><div>25</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>26</div></div><div>
</div></div><div><div><div>27</div></div><div><span>  </span><span>affine_migration</span><span>:</span></div></div><div><div><div>28</div></div><div><span>    </span><span>image</span><span>: </span><span>ghcr.io/toeverything/affine:${AFFINE_REVISION:-stable}</span></div></div><div><div><div>29</div></div><div><span>    </span><span>container_name</span><span>: </span><span>affine_migration_job</span></div></div><div><div><div>30</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>31</div></div><div><span>      </span><span># custom configurations</span></div></div><div><div><div>32</div></div><div><span><span>      </span></span><span>- </span><span>${UPLOAD_LOCATION}:/root/.affine/storage</span></div></div><div><div><div>33</div></div><div><span><span>      </span></span><span>- </span><span>${CONFIG_LOCATION}:/root/.affine/config</span></div></div><div><div><div>34</div></div><div><span>    </span><span>command</span><span>: [</span><span>'sh'</span><span>, </span><span>'-c'</span><span>, </span><span>'node ./scripts/self-host-predeploy.js'</span><span>]</span></div></div><div><div><div>35</div></div><div><span>    </span><span>env_file</span><span>:</span></div></div><div><div><div>36</div></div><div><span><span>      </span></span><span>- </span><span>.env</span></div></div><div><div><div>37</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>38</div></div><div><span><span>      </span></span><span>- </span><span>REDIS_SERVER_HOST=redis</span></div></div><div><div><div>39</div></div><div><span><span>      </span></span><span>- </span><span>DATABASE_URL=postgresql://${DB_USERNAME}:${DB_PASSWORD}@postgres:5432/${DB_DATABASE:-affine}</span></div></div><div><div><div>40</div></div><div><span><span>      </span></span><span>- </span><span>AFFINE_INDEXER_ENABLED=false</span></div></div><div><div><div>41</div></div><div><span>    </span><span>depends_on</span><span>:</span></div></div><div><div><div>42</div></div><div><span>      </span><span>postgres</span><span>:</span></div></div><div><div><div>43</div></div><div><span>        </span><span>condition</span><span>: </span><span>service_healthy</span></div></div><div><div><div>44</div></div><div><span>      </span><span>redis</span><span>:</span></div></div><div><div><div>45</div></div><div><span>        </span><span>condition</span><span>: </span><span>service_healthy</span></div></div><div><div><div>46</div></div><div>
</div></div><div><div><div>47</div></div><div><span>  </span><span>redis</span><span>:</span></div></div><div><div><div>48</div></div><div><span>    </span><span>image</span><span>: </span><span>redis</span></div></div><div><div><div>49</div></div><div><span>    </span><span>container_name</span><span>: </span><span>affine_redis</span></div></div><div><div><div>50</div></div><div><span>    </span><span>healthcheck</span><span>:</span></div></div><div><div><div>51</div></div><div><span>      </span><span>test</span><span>: [</span><span>'CMD'</span><span>, </span><span>'redis-cli'</span><span>, </span><span>'--raw'</span><span>, </span><span>'incr'</span><span>, </span><span>'ping'</span><span>]</span></div></div><div><div><div>52</div></div><div><span>      </span><span>interval</span><span>: </span><span>10s</span></div></div><div><div><div>53</div></div><div><span>      </span><span>timeout</span><span>: </span><span>5s</span></div></div><div><div><div>54</div></div><div><span>      </span><span>retries</span><span>: </span><span>5</span></div></div><div><div><div>55</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>56</div></div><div>
</div></div><div><div><div>57</div></div><div><span>  </span><span>postgres</span><span>:</span></div></div><div><div><div>58</div></div><div><span>    </span><span>image</span><span>: </span><span>pgvector/pgvector:pg16</span></div></div><div><div><div>59</div></div><div><span>    </span><span>container_name</span><span>: </span><span>affine_postgres</span></div></div><div><div><div>60</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>61</div></div><div><span><span>      </span></span><span>- </span><span>${DB_DATA_LOCATION}:/var/lib/postgresql/data</span></div></div><div><div><div>62</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>63</div></div><div><span>      </span><span>POSTGRES_USER</span><span>: </span><span>${DB_USERNAME}</span></div></div><div><div><div>64</div></div><div><span>      </span><span>POSTGRES_PASSWORD</span><span>: </span><span>${DB_PASSWORD}</span></div></div><div><div><div>65</div></div><div><span>      </span><span>POSTGRES_DB</span><span>: </span><span>${DB_DATABASE:-affine}</span></div></div><div><div><div>66</div></div><div><span>      </span><span>POSTGRES_INITDB_ARGS</span><span>: </span><span>'--data-checksums'</span></div></div><div><div><div>67</div></div><div><span>      </span><span># you better set a password for you database</span></div></div><div><div><div>68</div></div><div><span>      </span><span># or you may add 'POSTGRES_HOST_AUTH_METHOD=trust' to ignore postgres security policy</span></div></div><div><div><div>69</div></div><div><span>      </span><span>POSTGRES_HOST_AUTH_METHOD</span><span>: </span><span>trust</span></div></div><div><div><div>70</div></div><div><span>    </span><span>healthcheck</span><span>:</span></div></div><div><div><div>71</div></div><div><span>      </span><span>test</span><span>:</span></div></div><div><div><div>72</div></div><div><span><span>        </span></span><span>[</span><span>'CMD'</span><span>, </span><span>'pg_isready'</span><span>, </span><span>'-U'</span><span>, </span><span>"${DB_USERNAME}"</span><span>, </span><span>'-d'</span><span>, </span><span>"${DB_DATABASE:-affine}"</span><span>]</span></div></div><div><div><div>73</div></div><div><span>      </span><span>interval</span><span>: </span><span>10s</span></div></div><div><div><div>74</div></div><div><span>      </span><span>timeout</span><span>: </span><span>5s</span></div></div><div><div><div>75</div></div><div><span>      </span><span>retries</span><span>: </span><span>5</span></div></div><div><div><div>76</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>步骤3：配置环境变量<a href="#步骤3配置环境变量"><span>#</span></a></h3><p>创建一个 <code>.env</code> 文件，内容如下：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>AFFINE_REVISION=stable</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>PORT=3010</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>DB_DATA_LOCATION=./pgdata</span></div></div><div><div><div>6</div></div><div><span>UPLOAD_LOCATION=./storage</span></div></div><div><div><div>7</div></div><div><span>CONFIG_LOCATION=./config</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span># 数据库链接信息,必填</span></div></div><div><div><div>10</div></div><div><span>DB_USERNAME=affine</span></div></div><div><div><div>11</div></div><div><span>DB_PASSWORD=affine</span></div></div><div><div><div>12</div></div><div><span>DB_DATABASE=affine</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤4：启动 AFFiNE<a href="#步骤4启动-affine"><span>#</span></a></h3><p>在终端中运行以下命令启动 AFFiNE：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker-compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/2f814cd3e960496997c8c83a821ab7d120260518091037035.png" alt="" /></p></section><section><h3>步骤5：访问 AFFiNE<a href="#步骤5访问-affine"><span>#</span></a></h3><p>打开浏览器，访问 <code>http://localhost:3010</code>，会自动跳转到注册页面，注册完成后会登录到后台管理页面，你就可以看到 AFFiNE 的界面了。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/a40bbe71653e48df92b1e54be4d515a520260519085431029.png" alt="" /></p></section><section><h3>步骤5：登录管理后台<a href="#步骤5登录管理后台"><span>#</span></a></h3><p>注册账号后，你就可以登录管理后台了,进行个性化配置
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/8e808671ad42414a89ac9789187f895f20260519085521996.png" alt="" /></p></section><section><h3>步骤6： 开始使用<a href="#步骤6-开始使用"><span>#</span></a></h3><p>访问 <code>http://localhost:3010</code>，你就可以开始创建文档、使用白板、管理任务了。先设置一下中文语言~~（习惯英语的可以忽略）~~，然后就可以开始愉快的写文档了，再页不用担心隐私问题。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/75d715d0855b4e28bf4aad31044724ee20260519090633363.png" alt="" /></p></section><section><h3>步骤7： 生成脑图<a href="#步骤7-生成脑图"><span>#</span></a></h3><p>并且还支持文档转脑图功能，你可以将文档转换为脑图，方便组织和分享知识。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/8ea5c8e9eb4644769be240367def7b7820260519091040545.png" alt="" /></p></section></section>
<section><h2>常见问题<a href="#常见问题"><span>#</span></a></h2><p>Q: AFFiNE 和 Notion 有什么区别？
A: AFFiNE 是开源的，数据本地化，更安全；Notion 是商业软件，数据存在云端。</p><p>Q: AFFiNE 支持哪些功能？
A: AFFiNE 支持文档编辑、白板协作、任务管理、知识关联等多种功能。</p><p>Q: AFFiNE 可以离线使用吗？
A: 可以，AFFiNE 支持离线使用，随时随地都能工作。</p><p>Q: AFFiNE 可以多人协作吗？
A: 可以，AFFiNE 支持多人实时协作，可以共享文档和白板。</p></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>我使用 AFFiNE 已经两个月了，效果真的非常好：</p><ol>
<li>界面简洁美观，使用体验很棒</li>
<li>功能强大，集文档、白板、任务于一体</li>
<li>数据本地化，不用担心隐私问题</li>
<li>离线可用，随时随地都能工作</li>
<li>完全免费开源，没有任何广告和限制</li>
</ol></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>学生党</strong>：整理学习笔记，构建知识体系</li>
<li><strong>职场人士</strong>：管理工作文档，协作办公</li>
<li><strong>团队协作</strong>：需要一个统一的协作平台</li>
<li><strong>隐私敏感者</strong>：不想把数据存在第三方平台</li>
<li><strong>任何人</strong>：想要一个强大的笔记和协作工具</li>
</ul></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ul>
<li><strong>首次启动需要初始化</strong>：第一次启动 AFFiNE 时，需要初始化数据库，可能需要一些时间，请耐心等待。</li>
<li><strong>定期备份数据</strong>：建议定期备份笔记数据，防止数据丢失。</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 AFFiNE 感兴趣，可以访问它的 GitHub 仓库：<a href="https://github.com/toeverything/AFFiNE" target="_blank">https://github.com/toeverything/AFFiNE</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你平时用什么笔记软件？有没有遇到过什么痛点？使用 AFFiNE 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=1568564712&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
<li><a href="https://mp.weixin.qq.com/s/XuPLBVFs3w0duR7o62tMrw?token=1568564712&amp;lang=zh_CN" target="_blank">8MB 大小！这款 WSL 管理工具让我彻底告别命令行</a></li>
<li><a href="https://mp.weixin.qq.com/s/LoWoeLGYmnSpTilqm1ovUQ?token=1568564712&amp;lang=zh_CN" target="_blank">揭秘！你刷到的热门短剧，可能都是这个软件做的</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/docker/appflowy-intro/</id>
      <title type="text">国产笔记软件之光！这个工具让Notion黯然失色</title>
      <published>2026-05-15T00:00:00.000Z</published>
      <updated>2026-05-15T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/docker/appflowy-intro/"/>
      <summary type="text">完全开源，数据本地化，功能强大，国产之光</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！想要国产笔记软件的看过来！<a href="#朋友们想要国产笔记软件的看过来"><span>#</span></a></h2><p>Notion 服务器在国外，访问慢；数据存在云端，不安全；或者想要一个国产的、数据本地化的笔记软件…</p><p>今天给大家推荐一个神器——<strong>AppFlowy</strong>，一个完全开源的国产笔记软件。用了它之后，我果断放弃了 Notion！</p></section>
<section><h2>什么是 AppFlowy？<a href="#什么是-appflowy"><span>#</span></a></h2><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/963efb84c71c42eb91c366b5d3044eff20260518135859936.png" alt="" />
AppFlowy 是一个完全开源的国产笔记软件，数据本地化，功能强大，界面美观，是 Notion 的绝佳替代品。</p></section>
<section><h2>为什么推荐 AppFlowy？<a href="#为什么推荐-appflowy"><span>#</span></a></h2><section><h3>1️⃣ 国产之光<a href="#1️⃣-国产之光"><span>#</span></a></h3><p>由国内团队开发，完全自主可控。</p></section><section><h3>2️⃣ 数据本地化<a href="#2️⃣-数据本地化"><span>#</span></a></h3><p>所有数据都存储在本地，不用担心隐私泄露。</p></section><section><h3>3️⃣ 功能强大<a href="#3️⃣-功能强大"><span>#</span></a></h3><p>支持文档编辑、白板协作、任务管理等功能。</p></section><section><h3>4️⃣ 界面美观<a href="#4️⃣-界面美观"><span>#</span></a></h3><p>界面设计现代简洁，使用体验很棒。</p></section><section><h3>5️⃣ 完全开源<a href="#5️⃣-完全开源"><span>#</span></a></h3><p>代码完全开源，免费使用。</p></section></section>
<section><h2>如何使用 AppFlowy？<a href="#如何使用-appflowy"><span>#</span></a></h2><section><h3>步骤1：下载并安装 AppFlowy<a href="#步骤1下载并安装-appflowy"><span>#</span></a></h3><p>首先，你需要下载并安装 AppFlowy。访问 AppFlowy 的下载页面，下载适合你系统的版本。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/34c4c75c8d134e3b93dae86e121e18ec20260518140018998.png" alt="" /></p></section><section><h3>步骤2：安装 AppFlowy<a href="#步骤2安装-appflowy"><span>#</span></a></h3><p>运行安装程序，按照提示完成安装。安装过程非常简单，几分钟就能搞定。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/178fcb240e8e46aaa850661ec8a5d0a520260518140352879.png" alt="" /></p></section><section><h3>步骤3：启动 AppFlowy<a href="#步骤3启动-appflowy"><span>#</span></a></h3><p>安装完成后，启动 AppFlowy，你就可以看到它的主界面了。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/a40cce75c049471a95e1fc0c18e690f620260518140700695.png" alt="" /></p></section><section><h3>步骤4：开始使用<a href="#步骤4开始使用"><span>#</span></a></h3><p>创建文档、使用白板、管理任务，AppFlowy 可以满足你的所有需求。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/ce7983f0443e4399858bbefe7531227c20260518140718790.png" alt="" /></p></section></section>
<section><h2>常见问题<a href="#常见问题"><span>#</span></a></h2><p>Q: AppFlowy 和 Notion 有什么区别？
A: AppFlowy 是国产软件，数据本地化，更安全；Notion 是商业软件，数据存在云端。</p><p>Q: AppFlowy 支持哪些功能？
A: AppFlowy 支持文档编辑、白板协作、任务管理、知识关联等多种功能。</p><p>Q: AppFlowy 可以离线使用吗？
A: 可以，AppFlowy 的所有功能都可以离线使用。</p><p>Q: AppFlowy 支持多平台吗？
A: 支持，AppFlowy 支持 Windows、macOS、Linux、iOS、Android 等多种平台。</p></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>我使用 AppFlowy 已经两个月了，效果真的非常好：</p><ol>
<li>界面美观，使用体验很棒</li>
<li>功能强大，集文档、白板、任务于一体</li>
<li>数据本地化，不用担心隐私问题</li>
<li>完全免费开源，没有任何广告和限制</li>
<li>国产软件，支持国产开源</li>
</ol></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>学生党</strong>：整理学习笔记，构建知识体系</li>
<li><strong>职场人士</strong>：管理工作文档，协作办公</li>
<li><strong>团队协作</strong>：需要一个统一的协作平台</li>
<li><strong>隐私敏感者</strong>：不想把数据存在第三方平台</li>
<li><strong>任何人</strong>：想要一个强大的笔记和协作工具</li>
</ul></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ul>
<li><strong>首次使用需要适应</strong>：界面和 Notion 略有不同，需要一点时间适应。</li>
<li><strong>定期备份数据</strong>：建议定期备份笔记数据，防止数据丢失。</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 AppFlowy 感兴趣，可以访问它的 GitHub 仓库：<a href="https://github.com/AppFlowy-IO/AppFlowy" target="_blank">https://github.com/AppFlowy-IO/AppFlowy</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你平时用什么笔记软件？有没有遇到过数据安全的问题？使用 AppFlowy 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=1568564712&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
<li><a href="https://mp.weixin.qq.com/s/XuPLBVFs3w0duR7o62tMrw?token=1568564712&amp;lang=zh_CN" target="_blank">8MB 大小！这款 WSL 管理工具让我彻底告别命令行</a></li>
<li><a href="https://mp.weixin.qq.com/s/LoWoeLGYmnSpTilqm1ovUQ?token=1568564712&amp;lang=zh_CN" target="_blank">揭秘！你刷到的热门短剧，可能都是这个软件做的</a></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/docker/memos-intro/</id>
      <title type="text">极简备忘录神器！这个工具让记录变得简单</title>
      <published>2026-05-15T00:00:00.000Z</published>
      <updated>2026-05-15T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/docker/memos-intro/"/>
      <summary type="text">轻量级，无冗余，专注记录，完全开源</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！想要极简备忘录工具的看过来！<a href="#朋友们想要极简备忘录工具的看过来"><span>#</span></a></h2><p>市面上的备忘录软件功能太复杂，很多功能用不到；或者想要一个简单纯粹的记录工具…</p><p>今天给大家推荐一个神器——<strong>Memos</strong>，一个极简的备忘录工具。用了它之后，记录变得前所未有的简单！</p></section>
<section><h2>什么是 Memos？<a href="#什么是-memos"><span>#</span></a></h2><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/3e0198309b1b4e60a7cf1c2d1642373720260518141547734.png" alt="" />
Memos 是一个极简的备忘录工具，专注于记录和分享，没有多余的功能，让你专注于内容本身。</p></section>
<section><h2>为什么推荐 Memos？<a href="#为什么推荐-memos"><span>#</span></a></h2><section><h3>1️⃣ 极简设计<a href="#1️⃣-极简设计"><span>#</span></a></h3><p>界面简洁，没有多余的功能，专注记录。</p></section><section><h3>2️⃣ Markdown 支持<a href="#2️⃣-markdown-支持"><span>#</span></a></h3><p>支持 Markdown 格式，让笔记更加美观。</p></section><section><h3>3️⃣ 轻松分享<a href="#3️⃣-轻松分享"><span>#</span></a></h3><p>一键分享笔记，支持生成链接。</p></section><section><h3>4️⃣ 部署简单<a href="#4️⃣-部署简单"><span>#</span></a></h3><p>用 Docker 一键就能部署，几分钟搞定。</p></section><section><h3>5️⃣ 完全开源<a href="#5️⃣-完全开源"><span>#</span></a></h3><p>代码完全开源，免费使用。</p></section></section>
<section><h2>如何使用 Memos？<a href="#如何使用-memos"><span>#</span></a></h2><section><h3>步骤1：下载并安装 Memos<a href="#步骤1下载并安装-memos"><span>#</span></a></h3><p>首先，你需要下载并安装 Memos。Memos 支持 Docker 部署，这是最简单的方式。</p></section><section><h3>步骤2：配置 Docker Compose<a href="#步骤2配置-docker-compose"><span>#</span></a></h3><p>创建一个 <code>docker-compose.yml</code> 文件，内容如下：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>memos</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image</span><span>: </span><span>neosmemo/memos:stable</span></div></div><div><div><div>4</div></div><div><span>    </span><span>container_name</span><span>: </span><span>memos</span></div></div><div><div><div>5</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>6</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>"5230:5230"</span></div></div><div><div><div>8</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>- </span><span>./data:/var/opt/memos</span></div></div><div><div><div>10</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>11</div></div><div><span>      </span><span>MEMOS_PORT</span><span>: </span><span>5230</span></div></div><div><div><div>12</div></div><div><span>      </span><span>MEMOS_DRIVER</span><span>: </span><span>sqlite</span></div></div><div><div><div>13</div></div><div><span>      </span><span># 设置为公共网址MEMOS_INSTANCE_URL</span></div></div><div><div><div>14</div></div><div><span>      </span><span>MEMOS_INSTANCE_URL</span><span>: </span><span>https://memos.example.com</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤3：启动 Memos<a href="#步骤3启动-memos"><span>#</span></a></h3><p>在终端中运行以下命令启动 Memos：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker-compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤4：访问 Memos<a href="#步骤4访问-memos"><span>#</span></a></h3><p>打开浏览器，访问 <code>http://localhost:5230</code>，你就可以看到 Memos 的界面了。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/abfc913aa01148b9939ac9f7492dc81520260518143024509.png" alt="" /></p><blockquote><p>注意：首次运行时，第一个用户将成为主机管理员，可以配置注册、认证、存储及其他全局设置。一定要记录好密码哦。</p></blockquote></section><section><h3>步骤5：开始记录<a href="#步骤5开始记录"><span>#</span></a></h3><p>输入账号密码后会进入首页，点击新建按钮，开始记录你的笔记。支持 Markdown 格式，让笔记更加美观。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/f4903ff741c042889b900ce6d0aaa9ce20260518143354717.png" alt="" /></p></section></section>
<section><h2>如果不想docker部署，怎么办<a href="#如果不想docker部署怎么办"><span>#</span></a></h2><section><h3>当你不想在栈里用 Docker 或已经直接在主机上管理服务时，可以直接以安装文件安装 Memos。<a href="#当你不想在栈里用-docker-或已经直接在主机上管理服务时可以直接以安装文件安装-memos"><span>#</span></a></h3><p>支持的平台：</p><ul>
<li>Linux: <code>amd64</code>、<code>arm64</code>、<code>armv7</code></li>
<li>macOS: 英特尔和苹果芯片</li>
<li>Windows: <code>amd64</code></li>
</ul><p>下载地址：<a href="https://github.com/usememos/memos/releases/" target="_blank">https://github.com/usememos/memos/releases/</a>
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/58cfb825d9ff4391aa815a4fc4f5406720260518144350508.png" alt="" /></p></section></section>
<section><h2>常见问题<a href="#常见问题"><span>#</span></a></h2><p>Q: Memos 支持 Markdown 吗？
A: 支持，Memos 完全支持 Markdown 格式。</p><p>Q: Memos 可以分享笔记吗？
A: 可以，Memos 支持一键分享，生成分享链接。</p><p>Q: Memos 可以离线使用吗？
A: 可以，Memos 的所有功能都可以离线使用。</p><p>Q: Memos 的数据存储在哪里？
A: Memos 的数据存储在本地，你可以自己备份和管理。</p></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>我使用 Memos 已经一段时间了，效果真的非常好：</p><ol>
<li>界面简洁，没有多余的功能，专注记录</li>
<li>支持 Markdown，笔记更加美观</li>
<li>部署简单，几分钟就能搞定</li>
<li>数据本地化，不用担心隐私问题</li>
<li>完全免费开源，没有任何广告和限制</li>
</ol></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>学生党</strong>：记录学习笔记</li>
<li><strong>职场人士</strong>：记录工作事项</li>
<li><strong>写作者</strong>：记录灵感和想法</li>
<li><strong>任何人</strong>：想要一个简单的笔记工具</li>
</ul></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ul>
<li><strong>定期备份数据</strong>：建议定期备份笔记数据，防止数据丢失。</li>
<li><strong>注意数据安全</strong>：虽然数据存储在本地，但也要注意数据安全。</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 Memos 感兴趣，可以访问它的 GitHub 仓库：<a href="https://github.com/usememos/memos" target="_blank">https://github.com/usememos/memos</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你平时用什么笔记工具？有没有遇到过功能太复杂的问题？使用 Memos 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/n2TVXOYqL5-dPWz5ABTqOA?token=1568564712&amp;lang=zh_CN" target="_blank">国产笔记软件之光！这个工具让Notion黯然失色</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=1568564712&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
<li><a href="https://mp.weixin.qq.com/s/XuPLBVFs3w0duR7o62tMrw?token=1568564712&amp;lang=zh_CN" target="_blank">8MB 大小！这款 WSL 管理工具让我彻底告别命令行</a></li>
<li><a href="https://mp.weixin.qq.com/s/LoWoeLGYmnSpTilqm1ovUQ?token=1568564712&amp;lang=zh_CN" target="_blank">揭秘！你刷到的热门短剧，可能都是这个软件做的</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/docker/searxng-intro/</id>
      <title type="text">隐私保护搜索引擎！这个工具让你的搜索更安全</title>
      <published>2026-05-15T00:00:00.000Z</published>
      <updated>2026-05-15T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/docker/searxng-intro/"/>
      <summary type="text">完全开源，不追踪用户，聚合多引擎，保护隐私</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！担心搜索隐私泄露的看过来！<a href="#朋友们担心搜索隐私泄露的看过来"><span>#</span></a></h2><p>使用搜索引擎时，搜索历史被记录，隐私得不到保护；或者想要一个不追踪用户的搜索引擎…</p><p>今天给大家推荐一个神器——<strong>SearXNG</strong>，一个完全开源的隐私保护搜索引擎。用了它之后，我的搜索终于安全了！</p></section>
<section><h2>什么是 SearXNG？<a href="#什么是-searxng"><span>#</span></a></h2><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/10e9e1e9ba4e41eb98678d5d68ed1f1720260520162312126.png" alt="" />
SearXNG 是一个分布式的元搜索引擎，用户可以通过它在多个搜索引擎中同时查询，而不会暴露自己的隐私。它是对原始 Searx 项目的分支，改进了性能、功能和用户体验。</p><ul>
<li>元搜索引擎：SearXNG 并不直接提供搜索结果，而是将用户的查询分发到多个搜索引擎（如 Google、Bing、DuckDuckGo 等），然后汇总这些结果。</li>
<li>开源：SearXNG 是完全开源的，任何人都可以自由下载、修改和部署。</li>
<li>注重隐私：它不会保存用户的 IP 地址、搜索历史或其他个人信息。</li>
</ul></section>
<section><h2>为什么推荐 SearXNG？<a href="#为什么推荐-searxng"><span>#</span></a></h2><section><h3>1️⃣ 隐私保护<a href="#1️⃣-隐私保护"><span>#</span></a></h3><p>不追踪用户，不记录搜索历史，保护隐私。</p></section><section><h3>2️⃣ 多引擎聚合<a href="#2️⃣-多引擎聚合"><span>#</span></a></h3><p>聚合多个搜索引擎的结果，提供更全面的搜索结果。</p></section><section><h3>3️⃣ 完全开源<a href="#3️⃣-完全开源"><span>#</span></a></h3><p>代码完全开源，你可以自己部署，安全可靠。</p></section><section><h3>4️⃣ 部署简单<a href="#4️⃣-部署简单"><span>#</span></a></h3><p>用 Docker 一键就能部署，几分钟搞定。</p></section><section><h3>5️⃣ 完全免费<a href="#5️⃣-完全免费"><span>#</span></a></h3><p>没有任何费用，永久免费使用。</p></section></section>
<section><h2>如何使用 SearXNG？<a href="#如何使用-searxng"><span>#</span></a></h2><section><h3>步骤1：下载并安装 SearXNG<a href="#步骤1下载并安装-searxng"><span>#</span></a></h3><p>首先，你需要下载并安装 SearXNG。SearXNG 支持 Docker 部署，这是最简单的方式。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/e30f28813ae34d5c8946ac1916224d9320260520165822335.png" alt="" /></p></section><section><h3>步骤2：配置 Docker Compose<a href="#步骤2配置-docker-compose"><span>#</span></a></h3><p>创建一个 <code>docker-compose.yml</code> 文件，内容如下：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># Read the documentation before using the `docker-compose.yml` file:</span></div></div><div><div><div>2</div></div><div><span># https://docs.searxng.org/admin/installation-docker.html</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>name</span><span>: </span><span>searxng</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>services</span><span>:</span></div></div><div><div><div>7</div></div><div><span>  </span><span>core</span><span>:</span></div></div><div><div><div>8</div></div><div><span>    </span><span>container_name</span><span>: </span><span>searxng-core</span></div></div><div><div><div>9</div></div><div><span>    </span><span>image</span><span>: </span><span>docker.io/searxng/searxng:${SEARXNG_VERSION:-latest}</span></div></div><div><div><div>10</div></div><div><span>    </span><span>restart</span><span>: </span><span>always</span></div></div><div><div><div>11</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>- </span><span>${SEARXNG_HOST:+${SEARXNG_HOST}:}${SEARXNG_PORT:-8080}:${SEARXNG_PORT:-8080}</span></div></div><div><div><div>13</div></div><div><span>    </span><span>env_file</span><span>: </span><span>./.env</span></div></div><div><div><div>14</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>15</div></div><div><span><span>      </span></span><span>- </span><span>./core-config/:/etc/searxng/:Z</span></div></div><div><div><div>16</div></div><div><span><span>      </span></span><span>- </span><span>core-data:/var/cache/searxng/</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>  </span><span>valkey</span><span>:</span></div></div><div><div><div>19</div></div><div><span>    </span><span>container_name</span><span>: </span><span>searxng-valkey</span></div></div><div><div><div>20</div></div><div><span>    </span><span>image</span><span>: </span><span>docker.io/valkey/valkey:9-alpine</span></div></div><div><div><div>21</div></div><div><span>    </span><span>command</span><span>: </span><span>valkey-server --save 30 1 --loglevel warning</span></div></div><div><div><div>22</div></div><div><span>    </span><span>restart</span><span>: </span><span>always</span></div></div><div><div><div>23</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>24</div></div><div><span><span>      </span></span><span>- </span><span>valkey-data:/data/</span></div></div><div><div><div>25</div></div><div>
</div></div><div><div><div>26</div></div><div><span>volumes</span><span>:</span></div></div><div><div><div>27</div></div><div><span>  </span><span>core-data</span><span>:</span></div></div><div><div><div>28</div></div><div><span>  </span><span>valkey-data</span><span>:</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>创建一个<code>.env</code>文件，内容如下：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Use a specific version tag. E.g. "latest" or "2026.3.25-541c6c3cb".</span></div></div><div><div><div>2</div></div><div><span>#SEARXNG_VERSION=latest</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 监听ip</span></div></div><div><div><div>5</div></div><div><span>#SEARXNG_HOST=[::]</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 启动端口</span></div></div><div><div><div>8</div></div><div><span>SEARXNG_PORT</span><span>=</span><span>8080</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤3：启动 SearXNG<a href="#步骤3启动-searxng"><span>#</span></a></h3><p>在终端中运行以下命令启动 SearXNG：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker-compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/23edd903c7ab4e36886412d8abe8df2020260520163808668.png" alt="" /></p></section><section><h3>步骤4：访问 SearXNG<a href="#步骤4访问-searxng"><span>#</span></a></h3><p>打开浏览器，访问 <code>http://localhost:8080</code>，你就可以看到 SearXNG 的界面了。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/f91197862384492ebb95e7149210c76720260520164715842.png" alt="" /></p></section><section><h3>步骤5：开始搜索<a href="#步骤5开始搜索"><span>#</span></a></h3><p>输入关键词，开始搜索吧！SearXNG 会聚合多个搜索引擎的结果。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/7af9b6f4a3a34a82b668b7efe00982f320260520165157616.png" alt="" /></p></section></section>
<section><h2>常见问题<a href="#常见问题"><span>#</span></a></h2><p>Q: SearXNG 会追踪用户吗？
A: 不会，SearXNG 不追踪用户，不记录搜索历史。</p><p>Q: SearXNG 聚合哪些搜索引擎？
A: SearXNG 聚合 Google、Bing、DuckDuckGo 等多个搜索引擎。</p><p>Q: SearXNG 可以自定义吗？
A: 可以，SearXNG 支持自定义配置和主题。</p><p>Q: SearXNG 需要联网吗？
A: 需要，SearXNG 需要联网获取搜索结果。</p></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><ol>
<li>搜索结果全面，聚合多个引擎</li>
<li>隐私保护，不用担心被追踪</li>
<li>界面简洁，使用体验很棒</li>
<li>部署简单，几分钟就能搞定</li>
<li>完全免费开源，没有任何广告和限制</li>
</ol></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>隐私敏感者</strong>：担心搜索历史被记录</li>
<li><strong>开发者</strong>：需要一个干净的搜索环境</li>
<li><strong>任何人</strong>：想要一个隐私保护的搜索引擎</li>
</ul></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ul>
<li><strong>首次启动需要配置</strong>：第一次启动需要配置一些参数。</li>
<li><strong>可能需要梯子</strong>：某些搜索引擎在国内访问可能受限（当然你可以只使用国内的搜索引擎）。</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 SearXNG 感兴趣，可以访问它的 GitHub 仓库：<a href="https://github.com/searxng/searxng" target="_blank">https://github.com/searxng/searxng</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你平时用什么搜索引擎？有没有担心过隐私问题？使用 SearXNG 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=2054933560&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/xzF0cKZVAlU2Orzb_Qx9Bg?token=2054933560&amp;lang=zh_CN" target="_blank">替代Notion的最佳选择！这个开源工具太惊艳了</a></li>
<li><a href="https://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2054933560&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/ai/toonflow-intro/</id>
      <title type="text">揭秘！你刷到的热门短剧，可能都是这个软件做的</title>
      <published>2026-05-15T00:00:00.000Z</published>
      <updated>2026-05-15T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/ai/toonflow-intro/"/>
      <summary type="text">一个人也能做专业短剧，效率提升10倍，普通人也能当导演！</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>你有没有刷到过这样的短视频？</p><p>画面精美、剧情紧凑、更新频繁，一看就是”专业团队”制作的。但你知道吗？很多爆款短剧其实是<strong>一个人用AI工具做出来的</strong>！</p><p>今天就来揭秘这个”爆款制造机”——<strong>Toonflow</strong>。那些让你欲罢不能的短剧，很可能就是用它做的！</p><p>以前做短剧需要编剧、导演、画师、剪辑师一整个团队，现在有了 Toonflow，一个人+一台电脑就能搞定，效率提升了10倍不止！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/a458952817e64c4a8ae8aefcd277bfa820260515144445789.png" alt="" /></p></section>
<section><h2>什么是 Toonflow？<a href="#什么是-toonflow"><span>#</span></a></h2><p>简单说，Toonflow 就是一个<strong>文字转视频的神器</strong>。你只需要输入文字描述，它就能自动帮你生成完整的视频。</p><p><strong>核心功能：</strong></p><ul>
<li>✅ 输入想法，自动写剧本</li>
<li>✅ 剧本变画面，自动生成动画</li>
<li>✅ 一键加字幕、音效、背景音乐</li>
<li>✅ 支持多种风格（动漫、写实、古风都可以）</li>
</ul></section>
<section><h2>为什么推荐它？<a href="#为什么推荐它"><span>#</span></a></h2><section><h3>1️⃣ 新手也能上手<a href="#1️⃣-新手也能上手"><span>#</span></a></h3><p>完全不需要任何专业技能：</p><ul>
<li>不用学 Premiere、After Effects</li>
<li>不用会画画、不用会剪辑</li>
<li>甚至不用出镜，纯文字就能做视频
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/42e8d4fb5e7c4ba6bd59653fd8a6f94d1.png" alt="" /></li>
</ul></section><section><h3>2️⃣ 效率超高<a href="#2️⃣-效率超高"><span>#</span></a></h3><p>以前做一条视频：</p><ul>
<li>写脚本：2小时</li>
<li>找素材：1小时</li>
<li>剪辑：3小时</li>
<li>加字幕音效：1小时</li>
<li><strong>总计：7小时+</strong></li>
</ul><p>现在用 Toonflow：</p><ul>
<li>输入想法：5分钟</li>
<li>等待生成：30分钟</li>
<li><strong>总计：35分钟</strong></li>
</ul><p>效率提升了12倍！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/66d91c55a1d1441e9c0342c211770ee42.png" alt="" /></p></section><section><h3>3️⃣ 质量稳定<a href="#3️⃣-质量稳定"><span>#</span></a></h3><p>AI 生成的内容质量很可靠：</p><ul>
<li>画面风格统一</li>
<li>字幕自动生成</li>
<li>背景音乐搭配合理</li>
<li>节奏符合平台算法
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/4475ce51e5f74d549291eac33b26c38c4.png" alt="" /></li>
</ul></section><section><h3>4️⃣ 完全免费开源<a href="#4️⃣-完全免费开源"><span>#</span></a></h3><p>可以免费下载使用，还能自己改代码，开发者社区也很活跃。</p></section></section>
<section><h2>手把手教你用 Toonflow<a href="#手把手教你用-toonflow"><span>#</span></a></h2><section><h3>第一步：下载安装<a href="#第一步下载安装"><span>#</span></a></h3><ol>
<li>打开浏览器，访问官网：<a href="https://toonflow.net/#/" target="_blank">https://toonflow.net/#/</a></li>
<li>点击”下载”按钮，选择适合你电脑的版本（Windows 或 Mac）</li>
<li>下载完成后，双击安装包，跟着提示一步步安装</li>
</ol></section><section><h3>第二步：配置 AI（很简单）<a href="#第二步配置-ai很简单"><span>#</span></a></h3><p>第一次打开会提示配置 AI 服务，推荐选择”APIYI 一键配置”，跟着提示操作就行。如果有自己的 OpenAI API Key，也可以手动输入。</p></section><section><h3>第三步：创建项目<a href="#第三步创建项目"><span>#</span></a></h3><ol>
<li>打开 Toonflow，点击”新建项目”</li>
<li>输入项目名称，比如”我的第一个视频”</li>
<li>选择模板：推荐”短视频模板”（适合抖音、快手）</li>
<li>选择画布大小：竖版 9&lt;16&gt;（手机全屏）</li>
</ol></section><section><h3>第四步：写剧本（核心步骤）<a href="#第四步写剧本核心步骤"><span>#</span></a></h3><p>在左侧工具栏找到”剧本”按钮，点击添加到画布上：</p><ul>
<li>在输入框里写你的想法，比如：“做一个介绍人工智能的科普视频，1分钟左右，风格轻松有趣”</li>
<li>点击”生成”按钮，等待15秒左右</li>
<li>AI 会自动生成完整的剧本，包括台词、旁白、镜头提示</li>
</ul><p><strong>小技巧</strong>：写得越详细，生成的效果越好。比如可以指定人物、场景、风格。</p></section><section><h3>第五步：生成分镜<a href="#第五步生成分镜"><span>#</span></a></h3><p>选中刚才生成的剧本，点击上方的”生成分镜”按钮：</p><ul>
<li>等待20秒左右，会生成8-12张画面</li>
<li>每张画面都有详细的描述</li>
<li>可以点击画面更换风格（动漫风、写实风、古风等）
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/8be9859cfc61461ea7ad427fd118be997.png" alt="" /></li>
</ul></section><section><h3>第六步：合成视频<a href="#第六步合成视频"><span>#</span></a></h3><p>点击画布右上角的”合成”按钮：</p><ul>
<li>选择分辨率：1080x1920（手机全屏）</li>
<li>选择输出格式：MP4（最常用）</li>
<li>点击”开始合成”，等待30-60秒</li>
<li>合成完成后可以预览效果
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/a4665054141b466baeaffcec0db807409.png" alt="" /></li>
</ul></section><section><h3>第七步：导出发布<a href="#第七步导出发布"><span>#</span></a></h3><ol>
<li>预览没问题后，点击”导出”按钮</li>
<li>选择保存位置，比如桌面</li>
<li>导出完成后，就可以上传到抖音、快手、B站等平台了</li>
</ol></section></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ol>
<li><strong>自媒体博主</strong>：快速产出内容，提高更新频率</li>
<li><strong>职场人士</strong>：做产品介绍、培训视频</li>
<li><strong>学生党</strong>：做课程作业、活动宣传</li>
<li><strong>兴趣爱好者</strong>：记录生活、分享知识</li>
</ol></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>Toonflow 是一个真正能帮普通人实现”文字转视频”的神器。它降低了视频创作的门槛，让每个人都能轻松做视频。</p><p>如果你也想尝试做短视频，但又怕麻烦，强烈推荐试试 Toonflow！</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你平时喜欢看什么类型的短视频？如果让你做一个，你想做什么主题？欢迎在评论区分享！如果觉得这篇文章对你有帮助，别忘了点赞、在看、转发三连支持一下～</p><hr /><p><strong>项目地址</strong>：<a href="https://github.com/HBAI-Ltd/Toonflow-app" target="_blank">https://github.com/HBAI-Ltd/Toonflow-app</a></p><p><strong>官网</strong>：<a href="https://toonflow.net/#/" target="_blank">https://toonflow.net/#/</a></p><blockquote><p>注：创作内容请遵守相关法律法规和版权规定。</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/reubah-intro/</id>
      <title type="text">文件格式转换太麻烦？这个工具支持多格式批量转换！</title>
      <published>2026-05-15T00:00:00.000Z</published>
      <updated>2026-05-15T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/reubah-intro/"/>
      <summary type="text">多格式转换、批量处理、在线转换，让文件转换更简单</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！文件格式转换太麻烦的看过来！<a href="#朋友们文件格式转换太麻烦的看过来"><span>#</span></a></h2><p>文件格式不兼容；转换工具太多太乱；想批量转换却没有好工具…</p><p>今天给大家推荐一个神器——<strong>Reubah</strong>，一个支持多格式转换及批量处理的工具。自从用了它，我的文件转换再也不头疼了！</p></section>
<section><h2>什么是 Reubah？<a href="#什么是-reubah"><span>#</span></a></h2><p>Reubah 是一个开源的文件格式转换工具，它支持多种格式转换和批量处理操作，让文件转换变得简单。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/bbf633bf23c14dad9f82408b4338e5e020260529152240184.png" alt="" /></p></section>
<section><h2>为什么推荐 Reubah？<a href="#为什么推荐-reubah"><span>#</span></a></h2><section><h3>1️⃣ 多格式支持<a href="#1️⃣-多格式支持"><span>#</span></a></h3><p>支持多种文件格式：</p><ul>
<li>文档格式：DOC、DOCX、PDF、TXT等</li>
<li>图片格式：JPG、PNG、GIF、WebP等</li>
<li>音频格式：MP3、WAV、FLAC等</li>
<li>视频格式：MP4、AVI、MKV等</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/147a5ab5570043e1bd1c18c731a2acec20260529152319754.png" alt="" /></p></section><section><h3>2️⃣ 批量处理<a href="#2️⃣-批量处理"><span>#</span></a></h3><p>一次转换多个文件：</p><ul>
<li>支持批量选择文件</li>
<li>支持文件夹批量转换</li>
<li>可以设置输出格式</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/7e3ba7f661144519aecf5fd085c4b44d20260529152337882.png" alt="" /></p></section><section><h3>3️⃣ 在线转换<a href="#3️⃣-在线转换"><span>#</span></a></h3><p>无需安装软件：</p><ul>
<li>支持Web端在线转换</li>
<li>支持Docker部署</li>
<li>随时随地使用</li>
</ul></section><section><h3>4️⃣ 简洁高效<a href="#4️⃣-简洁高效"><span>#</span></a></h3><p>操作简单，转换快速：</p><ul>
<li>简洁的界面设计</li>
<li>支持拖拽上传</li>
<li>转换速度快</li>
</ul></section><section><h3>5️⃣ 完全开源<a href="#5️⃣-完全开源"><span>#</span></a></h3><p>Reubah 是开源项目，完全免费使用：</p><ul>
<li>代码透明可审计</li>
<li>支持自定义修改</li>
<li>使用简单方便</li>
</ul></section></section>
<section><h2>如何使用 Reubah？<a href="#如何使用-reubah"><span>#</span></a></h2><section><h3>步骤1：部署 Reubah<a href="#步骤1部署-reubah"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>reubah</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image</span><span>: </span><span>ghcr.io/dendianugerah/reubah:latest</span></div></div><div><div><div>4</div></div><div><span>    </span><span>container_name</span><span>: </span><span>reubah</span></div></div><div><div><div>5</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>6</div></div><div><span><span>      </span></span><span>- </span><span>"8081:8081"</span></div></div><div><div><div>7</div></div><div><span>    </span><span>security_opt</span><span>:</span></div></div><div><div><div>8</div></div><div><span><span>      </span></span><span>- </span><span>no-new-privileges:true</span></div></div><div><div><div>9</div></div><div><span>    </span><span>cap_drop</span><span>:</span></div></div><div><div><div>10</div></div><div><span><span>      </span></span><span>- </span><span>ALL</span></div></div><div><div><div>11</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤2：启动服务<a href="#步骤2启动服务"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker-compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤3：上传文件<a href="#步骤3上传文件"><span>#</span></a></h3><p>访问 <code>http://localhost:8081</code>，上传需要转换的文件。</p></section><section><h3>步骤4：选择格式<a href="#步骤4选择格式"><span>#</span></a></h3><p>选择目标格式，点击转换。</p></section></section>
<section><h2>常见问题<a href="#常见问题"><span>#</span></a></h2><p>Q: Reubah 需要什么配置？
A: Reubah 对硬件要求不高，建议至少 2GB 内存。</p><p>Q: 支持哪些格式转换？
A: 支持文档、图片、音频、视频等多种格式。</p><p>Q: 需要联网吗？
A: 自建部署的话可以离线使用。</p><p>Q: 可以批量转换吗？
A: 可以，支持批量转换多个文件。</p></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>办公人士</strong>：经常需要转换文件格式</li>
<li><strong>学生</strong>：处理作业文件</li>
<li><strong>开发者</strong>：转换代码文件</li>
<li><strong>任何人</strong>：需要文件格式转换</li>
</ul></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ul>
<li><strong>文件大小</strong>：注意文件大小限制</li>
<li><strong>转换时间</strong>：大文件转换需要时间</li>
<li><strong>输出目录</strong>：注意设置输出目录</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 Reubah 感兴趣，可以访问它的 GitHub 仓库：<a href="https://github.com/dendianugerah/reubah" target="_blank">https://github.com/dendianugerah/reubah</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时怎么转换文件格式？有没有遇到过什么问题？使用 Reubah 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/SqiQM0SEqn8GJlznXB96IQ?token=1876705190&amp;lang=zh_CN" target="_blank">从Hexo到Astro Firefly：我的博客迁移之旅</a></li>
<li><a href="https://mp.weixin.qq.com/s/R7o3RBDG2nmxfNtuUpAGWQ?token=1876705190&amp;lang=zh_CN" target="_blank">文件分发利器！这个工具让文件分享更安全</a></li>
<li><a href="http://mp.weixin.qq.com/s/G_ScLi37oGOlQv41mqTiYw?token=1128995367&amp;lang=zh_CN" target="_blank">Docker打包工具！这个Electron工具让镜像管理更高效！</a></li>
<li><a href="https://mp.weixin.qq.com/s/9wtyGpcXcjsXTt581ZCmEQ?token=1876705190&amp;lang=zh_CN" target="_blank">Redis管理神器！这个工具让你的数据操作更高效</a></li>
<li><a href="https://mp.weixin.qq.com/s/ANeunD7Z6oV4OPlbVqDKyw?token=2054933560&amp;lang=zh_CN" target="_blank">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</a></li>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=2054933560&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/xzF0cKZVAlU2Orzb_Qx9Bg?token=2054933560&amp;lang=zh_CN" target="_blank">替代Notion的最佳选择！这个开源工具太惊艳了</a></li>
<li><a href="https://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2054933560&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
</ul><blockquote><p>如果您觉得这篇文章有帮助，请为小王点点推荐，谢谢！🌹</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/wsl-dashboard-intro/</id>
      <title type="text">8MB 大小！这款 WSL 管理工具让我彻底告别命令行</title>
      <published>2026-05-15T00:00:00.000Z</published>
      <updated>2026-05-15T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/wsl-dashboard-intro/"/>
      <summary type="text">Rust + Slint 构建的 WSL 可视化管理神器，轻量高性能，颜值还在线！</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>作为一个常年在 Windows 上写代码的开发者，WSL (Windows Subsystem for Linux) 是我离不开的神器。但说实话，管理 WSL 一直是个头疼的问题 —— 要么在 PowerShell 里敲命令，要么用 Windows Terminal，总觉得不够直观。</p><p>直到我发现了 <strong>WSL Dashboard</strong>，一款用 Rust + Slint 构建的 WSL 可视化管理工具，8MB 大小，颜值在线，功能强大，彻底改变了我的 WSL 使用体验！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/e0b4a87c98824236944b93040c532ca720260514150017987.png" alt="" /></p></section>
<section><h2>为什么推荐它？<a href="#为什么推荐它"><span>#</span></a></h2><section><h3>1️⃣ 轻量到离谱<a href="#1️⃣-轻量到离谱"><span>#</span></a></h3><p>你敢信？整个安装包只有 <strong>8MB</strong>！</p><ul>
<li>启动速度飞快，秒开无压力</li>
<li>运行时内存占用仅 80MB 左右</li>
<li>基于 Rust 开发，性能炸裂</li>
<li>无冗余框架或依赖，老旧设备也能流畅运行</li>
</ul><p>相比那些动辄几百 MB 的管理工具，这简直是股清流！</p></section><section><h3>2️⃣ 颜值在线，体验丝滑<a href="#2️⃣-颜值在线体验丝滑"><span>#</span></a></h3><p>WSL Dashboard 用 Slint 构建界面，视觉效果非常现代化：</p><ul>
<li>简洁直观的图形界面，无需记忆命令行参数</li>
<li>操作流畅，响应迅速</li>
<li>支持多语言（中文、英文、日文等）</li>
<li>深色/浅色主题切换
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/5dabf94783944f4b9156c16b3b79ac9edemo.gif" alt="" /></li>
</ul></section><section><h3>3️⃣ 多发行版管理超方便<a href="#3️⃣-多发行版管理超方便"><span>#</span></a></h3><p>如果你同时安装了 Ubuntu、Fedora、Arch 等多个 Linux 发行版，WSL Dashboard 能让你轻松管理：</p><ul>
<li><strong>快速切换默认发行版</strong>：一键设置常用环境</li>
<li><strong>移动/导出/克隆发行版</strong>：灵活管理磁盘空间</li>
<li><strong>开机自启动</strong>：通过 Windows 任务计划程序实现系统启动时自动运行 WSL</li>
<li><strong>全局互斥锁</strong>：防止多发行版同时操作产生冲突
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/5d460acc939749c8b31b83262d33eb48home-settings.png" alt="" /></li>
</ul></section><section><h3>4️⃣ 实用功能一应俱全<a href="#4️⃣-实用功能一应俱全"><span>#</span></a></h3><ul>
<li><strong>一键打开终端</strong>：支持自定义终端应用（Windows Terminal、PowerShell 等）</li>
<li><strong>VS Code 集成</strong>：直接打开 WSL 中的项目</li>
<li><strong>端口转发管理</strong>：可视化配置端口映射，局域网内访问 WSL 服务</li>
<li><strong>USB 设备共享</strong>：将 USB 设备直通给 WSL 使用</li>
<li><strong>自动化脚本</strong>：支持编写 Shell 脚本实现复杂任务
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/a9f6ca41f59446759e9350156ea74124usb.png" alt="" /></li>
</ul></section><section><h3>5️⃣ 安全可靠<a href="#5️⃣-安全可靠"><span>#</span></a></h3><ul>
<li>使用最小权限原则运行</li>
<li>支持按需提权机制</li>
<li>操作前会提示确认，防止误操作</li>
</ul></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>用了 WSL Dashboard 一段时间后，最明显的感受是：</p><ol>
<li><strong>管理 WSL 变得轻松了</strong>：以前要记住一堆 <code>wsl</code> 命令，现在点点鼠标就搞定</li>
<li><strong>磁盘空间可控了</strong>：可以直观看到每个发行版占用的空间，随时导出或清理</li>
<li><strong>开发效率提升了</strong>：开机自动启动 WSL + 端口转发，不用再手动配置</li>
<li><strong>颜值即正义</strong>：界面好看，用起来心情都好多了</li>
</ol></section>
<section><h2>怎么安装？<a href="#怎么安装"><span>#</span></a></h2><ol>
<li>访问 <a href="https://github.com/owu/wsl-dashboard/releases" target="_blank">GitHub Releases</a> 下载最新版本</li>
<li>解压后双击运行即可（绿色软件，无需安装）</li>
<li>首次运行会自动检测系统中的 WSL 发行版
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/47ad421342494ddfb3da38bfdf1677fb20260514151136257.png" alt="" />
<strong>系统要求</strong>：</li>
</ol><ul>
<li>Windows 10/11</li>
<li>已启用 WSL 功能</li>
</ul></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>WSL Dashboard 绝对是 WSL 生态中的一款”瑞士军刀”，通过轻量化设计、自动化脚本支持和直观的图形界面，彻底改变了 WSL 的管理方式。无论是提升开发效率、简化系统管理，还是降低 Linux 使用门槛，它都是值得推荐的工具。</p><p>如果你也是 WSL 用户，强烈推荐试试这款工具，相信你会爱上它的！</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你平时怎么管理 WSL？用命令行还是其他工具？欢迎在评论区分享你的经验！如果觉得这篇文章对你有帮助，别忘了点赞、在看、转发三连支持一下～</p><hr /><p><strong>项目地址</strong>：<a href="https://github.com/owu/wsl-dashboard" target="_blank">https://github.com/owu/wsl-dashboard</a></p><blockquote><p>注：WSL Dashboard 目前还在快速迭代中，部分功能可能还不够完善，但整体体验已经非常不错了！</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/fresh-editor-intro/</id>
      <title type="text">又一个 Rust 神级编辑器！Fresh 让我放弃了 VS Code</title>
      <published>2026-05-13T00:00:00.000Z</published>
      <updated>2026-05-13T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/fresh-editor-intro/"/>
      <summary type="text">用 Rust 写的新一代代码编辑器，性能炸裂，功能强大，还能远程开发！</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>作为一个常年和代码打交道的程序员，我对编辑器的要求越来越高。VS Code 虽然好用，但总觉得有点臃肿；Neovim 很强大但配置太麻烦。直到我发现了 <strong>Fresh</strong>，一个用 Rust 写的新一代代码编辑器，彻底改变了我的开发体验。</p><p>今天就来给大家安利这个宝藏编辑器！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/88a53df210fe48279e55f21111a4a634showcase.C7kn0Bea.gif" alt="" /></p></section>
<section><h2>为什么我放弃了 VS Code？<a href="#为什么我放弃了-vs-code"><span>#</span></a></h2><p>说实话，VS Code 陪伴了我很多年，但最近越来越觉得力不从心：</p><ol>
<li><strong>启动慢</strong>：每次打开大项目都要等好几秒</li>
<li><strong>内存占用高</strong>：开几个窗口内存就飙升到 2-3GB</li>
<li><strong>插件臃肿</strong>：为了功能装了一堆插件，反而拖慢速度</li>
<li><strong>远程开发体验一般</strong>：SSH 连接经常卡顿</li>
</ol><p>直到我遇到 Fresh，这些问题都迎刃而解！</p></section>
<section><h2>Fresh 到底有多香？<a href="#fresh-到底有多香"><span>#</span></a></h2><section><h3>1️⃣ 性能炸裂，秒开秒关<a href="#1️⃣-性能炸裂秒开秒关"><span>#</span></a></h3><p>Fresh 用 Rust 编写，性能真的没话说：</p><ul>
<li><strong>启动速度</strong>：几乎瞬间打开，大项目也不卡顿</li>
<li><strong>内存占用</strong>：比 VS Code 少一半以上</li>
<li><strong>响应流畅</strong>：滚动、编辑、搜索都丝滑无比
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/4d2b561bcbe949c789d6710771e00b47multicursor.png" alt="" /></li>
</ul></section><section><h3>2️⃣ 功能强大，应有尽有<a href="#2️⃣-功能强大应有尽有"><span>#</span></a></h3><p>别以为轻量就功能少，Fresh 啥都有：</p><ul>
<li><strong>LSP 支持</strong>：智能补全、语法检查、定义跳转，一个不少</li>
<li><strong>代码折叠</strong>：支持 LSP 折叠范围，代码结构一目了然</li>
<li><strong>多光标编辑</strong>：批量修改神器</li>
<li><strong>Live Grep</strong>：支持 ripgrep、git-grep，搜索超快</li>
<li><strong>代码审查</strong>：内置 diff 查看器，代码对比很方便</li>
</ul></section><section><h3>3️⃣ 远程开发超方便<a href="#3️⃣-远程开发超方便"><span>#</span></a></h3><p>这个功能我太爱了！Fresh 支持直接编辑远程服务器上的文件：</p><ul>
<li>SSH 连接稳定，速度快</li>
<li>本地和远程无缝切换</li>
<li>文件系统抽象，操作和本地一样</li>
</ul></section><section><h3>4️⃣ 主题系统超灵活<a href="#4️⃣-主题系统超灵活"><span>#</span></a></h3><p>Fresh 的主题系统设计得很用心：</p><ul>
<li>支持主题继承，可以基于内置主题自定义</li>
<li>有 4 个内置主题：light、dark、high-contrast、nostalgia</li>
<li>还能直接用终端配色，无缝融入你的终端环境
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/ddec43b870eb4cfebd5d9379b43dfa08fresh-lsp-hover.png" alt="" /></li>
</ul></section><section><h3>5️⃣ 插件生态正在崛起<a href="#5️⃣-插件生态正在崛起"><span>#</span></a></h3><p>虽然年轻，但插件生态已经很丰富了：</p><ul>
<li>支持 QuickJS 插件运行时</li>
<li>已有很多实用插件：代码 tour、git 集成、终端等</li>
<li>插件 API 设计合理，开发门槛不高
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/b21bd38f0fd14939ad01e08aba0a80a8palette.png" alt="" /></li>
</ul></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>用了 Fresh 一周，我的感受是：</p><ol>
<li><strong>启动真的快</strong>：以前开 VS Code 要等 5 秒，现在几乎秒开</li>
<li><strong>内存占用感人</strong>：同样打开一个 Rust 项目，VS Code 用了 1.2GB，Fresh 只用了 400MB</li>
<li><strong>远程开发太香</strong>：连服务器写代码和本地没区别，再也不用 scp 来 scp 去了</li>
<li><strong>界面简洁清爽</strong>：没有多余的按钮和菜单，专注于写代码</li>
</ol></section>
<section><h2>怎么安装？<a href="#怎么安装"><span>#</span></a></h2><p>Fresh 支持所有主流平台：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># macOS</span></div></div><div><div><div>2</div></div><div><span>brew</span><span> </span><span>install</span><span> </span><span>fresh-editor</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># Linux (Flatpak)</span></div></div><div><div><div>5</div></div><div><span>flatpak</span><span> </span><span>install</span><span> </span><span>flathub</span><span> </span><span>io.github.sinelaw.fresh</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># Windows</span></div></div><div><div><div>8</div></div><div><span>scoop</span><span> </span><span>install</span><span> </span><span>fresh-editor</span></div></div><div><div><div>9</div></div><div><span># or</span></div></div><div><div><div>10</div></div><div><span>winget</span><span> </span><span>install</span><span> </span><span>fresh-editor</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>或者直接从 GitHub Releases 下载对应平台的二进制文件。</p></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>Fresh 是一款非常有潜力的代码编辑器。它用 Rust 带来了极致的性能体验，同时功能也足够强大，完全能满足日常开发需求。如果你对 VS Code 的臃肿感到厌倦，又不想折腾 Neovim 的配置，Fresh 绝对值得一试！</p><p>目前 Fresh 还在快速迭代中，每周都有新功能上线。相信用不了多久，它就能成为主流编辑器的有力竞争者。</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你平时用什么编辑器？最看重编辑器的什么功能？欢迎在评论区分享！如果觉得这篇文章对你有帮助，别忘了点赞、在看、转发三连支持一下～</p><hr /><p><strong>项目地址</strong>：<a href="https://github.com/sinelaw/fresh" target="_blank">https://github.com/sinelaw/fresh</a></p><blockquote><p>注：Fresh 目前还在快速发展中，部分功能可能还不够完善，但整体体验已经非常不错了！</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/karpathy-skills-intro/</id>
      <title type="text">Karpathy 出手了！这个插件让 Claude Code 瞬间变聪明</title>
      <published>2026-05-12T00:00:00.000Z</published>
      <updated>2026-05-12T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/karpathy-skills-intro/"/>
      <summary type="text">受 Andrej Karpathy 启发，四个原则让 AI 编码更靠谱，少走弯路！</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>最近在 Twitter 上看到 Andrej Karpathy 的一条推文，简直说出了所有用 AI 写代码的人的心声：</p><blockquote><p>“模型会代你做错误假设，然后不假思索地执行。它们不管理自身的困惑，不寻求澄清，不呈现矛盾…”</p></blockquote><p>相信很多人都有这样的经历：让 AI 写代码，它噼里啪啦写了一堆，看起来很完美，结果一运行全是坑。明明 100 行能搞定的事情，非要写成 1000 行的臃肿架构。</p><p>直到我发现了这个项目 —— <strong>andrej-karpathy-skills</strong>，一个专门解决这些问题的 Claude Code 插件。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/2c1d4116941d4010b5e38d6dd22dead720260512153356449.png" alt="" /></p></section>
<section><h2>为什么 AI 写代码容易踩坑？<a href="#为什么-ai-写代码容易踩坑"><span>#</span></a></h2><p>Karpathy 总结了几个核心问题：</p><ol>
<li><strong>想当然</strong>：AI 会默默做错误假设，然后直接执行</li>
<li><strong>过度设计</strong>：喜欢堆砌抽象概念，把简单问题复杂化</li>
<li><strong>手欠</strong>：经常改动或删除自己不理解的代码和注释</li>
<li><strong>不验证</strong>：做完就完了，不管结果对不对</li>
</ol><p>这些问题真的太戳心了！每次用 AI 写完代码，我都要花大量时间去 debug，有时候还不如自己写。</p></section>
<section><h2>四个原则，让 AI 变靠谱<a href="#四个原则让-ai-变靠谱"><span>#</span></a></h2><p>这个项目提出了四个核心原则，专门针对这些问题：</p><section><h3>1️⃣ 编码前先思考<a href="#1️⃣-编码前先思考"><span>#</span></a></h3><p>AI 最喜欢做的事情就是瞎猜。这个原则强制它：</p><ul>
<li>明确说明假设，如果不确定就问</li>
<li>遇到歧义时，给出多种解释，不要默默选择</li>
<li>困惑时停下来，要求澄清</li>
</ul><p>简单说就是：<strong>先想清楚再动手</strong>！</p></section><section><h3>2️⃣ 简洁优先<a href="#2️⃣-简洁优先"><span>#</span></a></h3><p>对抗 AI 的过度工程倾向：</p><ul>
<li>不要添加要求之外的功能</li>
<li>不要为一次性代码创建抽象</li>
<li>如果 200 行能写成 50 行，重写它</li>
</ul><p>检验标准：<strong>资深工程师会觉得这过于复杂吗？</strong> 如果是，简化！</p></section><section><h3>3️⃣ 精准修改<a href="#3️⃣-精准修改"><span>#</span></a></h3><p>这个太重要了！AI 经常手欠改一些无关的代码。这个原则要求：</p><ul>
<li>只碰必须碰的代码</li>
<li>不要”改进”相邻的代码、注释或格式</li>
<li>不要重构没坏的东西</li>
<li>匹配现有风格，即使你不喜欢</li>
</ul><p>检验标准：<strong>每一行修改都能直接追溯到用户的请求</strong>。</p></section><section><h3>4️⃣ 目标驱动执行<a href="#4️⃣-目标驱动执行"><span>#</span></a></h3><p>把模糊的指令变成可验证的目标：</p><ul>
<li>“添加验证” → “为无效输入编写测试，然后让它们通过”</li>
<li>“修复 bug” → “编写重现 bug 的测试，然后让它通过”</li>
</ul><p>这样 AI 就能自己循环执行，直到达成目标。</p></section></section>
<section><h2>怎么用？<a href="#怎么用"><span>#</span></a></h2><section><h3>方式一：Claude Code 插件（推荐）<a href="#方式一claude-code-插件推荐"><span>#</span></a></h3><p>在 Claude Code 中执行两条命令就行：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>/plugin marketplace add forrestchang/andrej-karpathy-skills</span></div></div><div><div><div>2</div></div><div><span>/plugin install andrej-karpathy-skills@karpathy-skills</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>安装后，这些指南会自动应用到你所有的项目中。</p></section><section><h3>方式二：Trae 编辑器规则<a href="#方式二trae-编辑器规则"><span>#</span></a></h3><p>如果你使用 Trae 编辑器，可以直接将 CLAUDE.md 的内容添加到你的规则中：</p><ol>
<li>在 Trae 中创建或编辑你的规则文件（通常在 <code>.trae/rules/</code> 目录下）</li>
<li>访问 <a href="https://raw.githubusercontent.com/forrestchang/andrej-karpathy-skills/main/CLAUDE.md" target="_blank">CLAUDE.md</a> 获取完整内容</li>
<li>将内容复制到你的规则文件中</li>
</ol><p>这样 Trae 的 AI 助手也会遵循这四个原则来帮你写代码。</p></section><section><h3>方式三：按项目配置<a href="#方式三按项目配置"><span>#</span></a></h3><p>在项目根目录创建 <code>CLAUDE.md</code> 文件：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>curl</span><span> </span><span>-o</span><span> </span><span>CLAUDE.md</span><span> </span><span>https://raw.githubusercontent.com/forrestchang/andrej-karpathy-skills/main/CLAUDE.md</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这种方式适合需要针对特定项目定制规则的场景。</p></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>用了几天之后，最明显的感受是：</p><ol>
<li><strong>AI 变”谨慎”了</strong>：遇到不确定的地方会主动问，不会瞎猜</li>
<li><strong>代码简洁了</strong>：不再有一堆没用的抽象，该多少行就多少行</li>
<li><strong>改动精准了</strong>：diff 里只有我要求的改动，没有乱七八糟的”顺手改进”</li>
<li><strong>验证意识强了</strong>：写完代码会自己跑测试，直到通过</li>
</ol></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>这个插件真的是用 AI 写代码的神器！它不是让 AI 写得更快，而是让 AI 写得更准、更稳、更符合人类工程师的思维方式。</p><p>四个原则看似简单，但直击 AI 编码的痛点。如果你经常用 Claude Code 写代码，强烈推荐试试这个插件，会让你的开发体验提升一个档次！</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你平时用 AI 写代码时遇到过哪些坑？欢迎在评论区分享！如果觉得这篇文章对你有帮助，别忘了点赞、在看、转发三连支持一下～</p><hr /><p><strong>项目地址</strong>：<a href="https://github.com/forrestchang/andrej-karpathy-skills" target="_blank">https://github.com/forrestchang/andrej-karpathy-skills</a></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/omniget-intro/</id>
      <title type="text">挖到宝了！这工具把下载、学习、阅读全搞定，我直接卸载了3个软件</title>
      <published>2026-05-11T00:00:00.000Z</published>
      <updated>2026-05-11T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/omniget-intro/"/>
      <summary type="text">一个工具=下载器+课程播放器+电子书阅读器+音乐播放器，太香了！</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>最近发现一个神仙工具，用了一周我直接把电脑里的视频播放器、电子书阅读器、音乐播放器都卸载了，就留这一个就够了！今天必须把这个宝藏工具安利给你们——<strong>OmniGet</strong>。</p><p>说实话，之前我电脑里软件多到爆炸：看视频用 PotPlayer，读书用 Kindle，听音乐用网易云，下载用 IDM，学课程还要开浏览器… 切换来切换去真的烦死了。直到我遇到 OmniGet，一个软件搞定所有，简直是效率神器！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/4d2946a16da8454dbdf2990b24be75e0screenshot.png" alt="" /></p></section>
<section><h2>为什么我强烈推荐？<a href="#为什么我强烈推荐"><span>#</span></a></h2><section><h3>1️⃣ 下载功能强到离谱<a href="#1️⃣-下载功能强到离谱"><span>#</span></a></h3><p>最开始吸引我的是它的下载能力，简直是无所不能：</p><ul>
<li><strong>视频平台全覆盖</strong>：YouTube、B站、抖音、小红书、TikTok、Instagram、Twitter… 你能想到的视频网站它都支持，复制链接就能下</li>
<li><strong>课程下载是真的香</strong>：Udemy、Hotmart 这些平台的课程，登录一次就能批量下载，还能在软件里直接看，笔记能绑定时间戳，复习的时候点笔记就跳转到对应位置</li>
<li><strong>种子和 P2P 都支持</strong>：磁力链接直接拖进去就行，两台电脑之间用4个词的密码就能传文件，太方便了
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/bbbdab28625040d9ab88777157007a8d20260511173823634.png" alt="" /></li>
</ul></section><section><h3>2️⃣ 内置播放器真的好用<a href="#2️⃣-内置播放器真的好用"><span>#</span></a></h3><p>下载完不用切换软件，直接在里面看：</p><ul>
<li><strong>课程播放器</strong>：进度记忆、倍速播放、时间戳笔记，PDF 附件还能并排显示，学习体验拉满
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/c0bf8dd09f7b4d7a83639c3de7e464c620260511173752293.png" alt="" /></li>
<li><strong>电子书阅读器</strong>：支持 PDF、EPUB、漫画，有专注模式和护眼主题，做笔记和高亮都很方便
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/2f40ea08730a45b3b8b0297a53b2fc7820260511173841594.png" alt="" /></li>
<li><strong>音乐播放器</strong>：像 iTunes 一样展示专辑封面，支持同步歌词，还能接入 Spotify，一个播放器搞定所有音乐
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/466ee59d280b467e94a6d441f5f47cdf20260511173855986.png" alt="" /></li>
</ul></section><section><h3>3️⃣ 细节做得特别贴心<a href="#3️⃣-细节做得特别贴心"><span>#</span></a></h3><p>这些小功能真的戳到我了：</p><ul>
<li><strong>全局快捷键</strong>：<code>Ctrl+Shift+D</code> 一键下载剪贴板里的链接，不用打开软件</li>
<li><strong>番茄钟</strong>：学累了自动暂停视频，劳逸结合</li>
<li><strong>14 个主题</strong>：Catppuccin、Dracula 这些热门主题都有，颜值党狂喜</li>
<li><strong>跨平台</strong>：Windows、macOS、Linux 都能用，而且是便携版，U盘一插就能带走</li>
</ul></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>说说我这几天的真实感受：</p><ol>
<li>
<p><strong>下载课程</strong>：把 Udemy 上买的一门 Python 课程下载下来，大概50节课，边看边做笔记，复习的时候点击笔记就跳转到当时的知识点，效率提升太多了</p>
</li>
<li>
<p><strong>看电子书</strong>：把之前下载的一堆 PDF 丢进去，自动识别封面和书名，专注模式下再也不会被其他软件打扰</p>
</li>
<li>
<p><strong>听音乐</strong>：把本地音乐文件夹导入，自动整理成专辑视图，歌词同步滚动，比网易云还好用（关键是没广告！）</p>
</li>
</ol></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>OmniGet 真的是我今年发现的最实用的工具，它不只是一个下载器，更像是一个<strong>一站式内容消费平台</strong>。从下载到学习到娱乐，一个软件全部搞定，大大减少了窗口切换的时间，让我能更专注地做事情。</p><p>最关键的是，它完全开源免费，没有任何广告，开发者也一直在更新维护。目前在 GitHub 上已经有 2000+ Star，口碑非常好。</p><p>如果你也像我一样，电脑里一堆软件，想要简化自己的数字生活，强烈推荐试试 OmniGet！</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你平时电脑里最常用的工具是什么？有没有什么让你相见恨晚的神器？欢迎在评论区分享！如果觉得这篇文章对你有帮助，别忘了点赞、在看、转发三连支持一下～</p><hr /><p><strong>项目地址</strong>：<a href="https://github.com/tonhowtf/omniget" target="_blank">https://github.com/tonhowtf/omniget</a></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/deepseek-tui-intro/</id>
      <title type="text">GitHub 5.7k Star！DeepSeek-TUI，DeepSeek版的Claude Code来了</title>
      <published>2026-05-08T00:00:00.000Z</published>
      <updated>2026-05-08T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/deepseek-tui-intro/"/>
      <summary type="text">DeepSeek版的Claude Code，100万token上下文，让AI编程更高效</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>嘿，小伙伴们！你在用 DeepSeek 网页版编程的时候，是不是总觉得哪里不对劲？让它改个文件还要复制粘贴，让它跑个命令还得手动执行，想让它管理 Git 更是难上加难。AI 的编程能力明明很强，但用起来效率却大打折扣，因为缺少那种”直接操控电脑”的体验。</p><p>直到最近发现了一个宝藏项目——<strong>DeepSeek-TUI</strong>！这是 DeepSeek 版的 Claude Code，一个跑在终端里的 AI 编程 Agent。能直接读写文件、执行 Shell 命令、管理 Git、甚至编排子 Agent 并行干活。说白了就是把 DeepSeek 的强大能力，直接搬进了你的 terminal！</p><p>今天我就来和大家唠唠这个神器，看看它是怎么让 AI 编程变得如此畅快的！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/95dec4a489d941f49b6b8fc58ad75ca720260509090813290.png" alt="" /></p></section>
<section><h2>项目介绍<a href="#项目介绍"><span>#</span></a></h2><section><h3>✨ 核心特性<a href="#-核心特性"><span>#</span></a></h3><ul>
<li><strong>🤖 终端原生</strong>: 跑在终端里的 AI 编程 Agent，键盘驱动，高效便捷</li>
<li><strong>📝 文件操作</strong>: 读写文件、应用补丁、正则搜索，全部搞定</li>
<li><strong>💻 Shell 执行</strong>: 运行命令、超时控制、后台任务管理</li>
<li><strong>🔍 网页搜索</strong>: 集成 DuckDuckGo 搜索，AI 帮你查资料</li>
<li><strong>📦 子 Agent</strong>: 编排多个子 Agent 并行工作，效率翻倍</li>
<li><strong>🔄 Git 集成</strong>: 代码审查、补丁应用、差异分析</li>
<li><strong>🌐 MCP 协议</strong>: 支持 Model Context Protocol，扩展无限</li>
<li><strong>🔢 100万上下文</strong>: DeepSeek V4 的 100万 token 上下文，一次性看懂整个项目</li>
</ul></section><section><h3>🎮 多种工作模式<a href="#-多种工作模式"><span>#</span></a></h3>

<table><thead><tr><th>模式</th><th>说明</th><th>适用场景</th></tr></thead><tbody><tr><td><strong>Normal</strong></td><td>聊天模式，写文件和执行命令前询问</td><td>日常交流</td></tr><tr><td><strong>Plan</strong></td><td>只读模式，先探索代码库再规划方案</td><td>需求分析</td></tr><tr><td><strong>Agent</strong></td><td>多步工具调用，执行前询问 Shell</td><td>日常开发</td></tr><tr><td><strong>YOLO</strong></td><td>全自动模式，所有操作直接执行</td><td>快速出活</td></tr><tr><td><strong>RLM</strong></td><td>外部化上下文，适合大文件处理</td><td>大项目</td></tr><tr><td><strong>Duo</strong></td><td><em>player-coach</em> 迭代验证模式</td><td>复杂任务</td></tr></tbody></table></section><section><h3>🛠️ 技术栈<a href="#️-技术栈"><span>#</span></a></h3>

<table><thead><tr><th>分类</th><th>技术</th></tr></thead><tbody><tr><td>语言</td><td>Rust</td></tr><tr><td>TUI框架</td><td>Ratatui</td></tr><tr><td>AI模型</td><td>DeepSeek V4</td></tr><tr><td>协议</td><td>MCP (Model Context Protocol)</td></tr><tr><td>平台</td><td>macOS / Linux / Windows</td></tr></tbody></table></section></section>
<section><h2>实战体验<a href="#实战体验"><span>#</span></a></h2><section><h3>安装配置<a href="#安装配置"><span>#</span></a></h3><p>安装方式超级简单，一行命令搞定：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 方式一：npm 安装（推荐）</span></div></div><div><div><div>2</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>-g</span><span> </span><span>deepseek-tui</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 方式二：Cargo 安装</span></div></div><div><div><div>5</div></div><div><span>cargo</span><span> </span><span>install</span><span> </span><span>deepseek-tui-cli</span><span> </span><span>--locked</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 国内用户建议配清华镜像</span></div></div><div><div><div>8</div></div><div><span>npm</span><span> </span><span>config</span><span> </span><span>set</span><span> </span><span>registry</span><span> </span><span>https://registry.npmmirror.com</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>获取 API Key<a href="#获取-api-key"><span>#</span></a></h3><ol>
<li>访问 <a href="https://platform.deepseek.com" target="_blank">https://platform.deepseek.com</a> 注册账号</li>
<li>在控制台创建一个 API Key（格式：<code>sk-...</code>）</li>
<li>首次运行时会提示输入 Key，或者手动设置：</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 方式一：环境变量</span></div></div><div><div><div>2</div></div><div><span>export</span><span> </span><span>DEEPSEEK_API_KEY</span><span>=</span><span>sk-your-key-here</span></div></div><div><div><div>3</div></div><div><span>echo</span><span> </span><span>'export DEEPSEEK_API_KEY=sk-...'</span><span> &gt;&gt; </span><span>~/.zshrc</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># 方式二：配置文件</span></div></div><div><div><div>6</div></div><div><span># ~/.deepseek/config.toml</span></div></div><div><div><div>7</div></div><div><span>[api]</span></div></div><div><div><div>8</div></div><div><span>key</span><span> </span><span>=</span><span> </span><span>"sk-your-key-here"</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>启动使用<a href="#启动使用"><span>#</span></a></h3><p>安装完成后，直接在终端输入：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>deepseek</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>界面会立即启动，键盘驱动，操作流畅！</p></section><section><h3>查看帮助<a href="#查看帮助"><span>#</span></a></h3><p>按 <code>F1</code> 或输入 <code>/help</code> 查看所有命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 常用命令</span></div></div><div><div><div>2</div></div><div><span>/help</span><span>          </span><span># 显示帮助</span></div></div><div><div><div>3</div></div><div><span>/modes</span><span>         </span><span># 查看所有模式</span></div></div><div><div><div>4</div></div><div><span>/exit</span><span>          </span><span># 退出程序</span></div></div><div><div><div>5</div></div><div><span>/doctor</span><span>         </span><span># 运行诊断</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>模式切换<a href="#模式切换"><span>#</span></a></h3><p>按 <code>Tab</code> 键循环切换模式：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Normal → Plan → Agent → YOLO → Normal</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 想先了解代码库？用 Plan 模式</span></div></div><div><div><div>2</div></div><div><span># 输入："这个代码库是做什么的？"</span></div></div><div><div><div>3</div></div><div><span># AI 会先分析项目结构，不做任何修改</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># 想让它干活？切换到 Agent 模式</span></div></div><div><div><div>6</div></div><div><span># 输入："帮我重构这个函数"</span></div></div><div><div><div>7</div></div><div><span># AI 会一步步执行，每次执行 Shell 前都会询问</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>项目分析<a href="#项目分析"><span>#</span></a></h3><p>进入一个项目目录，让 AI 帮你分析：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>~/my-project</span></div></div><div><div><div>2</div></div><div><span>deepseek</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 问：这个代码库是做什么的？</span></div></div><div><div><div>5</div></div><div><span># AI 会：</span></div></div><div><div><div>6</div></div><div><span># 1. 分析项目结构</span></div></div><div><div><div>7</div></div><div><span># 2. 读取关键配置文件</span></div></div><div><div><div>8</div></div><div><span># 3. 总结项目功能</span></div></div><div><div><div>9</div></div><div><span># 4. 给出目录结构说明</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>100万 token 上下文意味着 AI 可以一次性看完整个项目的所有代码，不需要你手动挑选要分析的文件！</p></section><section><h3>代码修改<a href="#代码修改"><span>#</span></a></h3><p>想让 AI 帮你修改代码？太简单了！</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Agent 模式下</span></div></div><div><div><div>2</div></div><div><span># 输入："把这个函数的错误处理完善一下"</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># AI 会：</span></div></div><div><div><div>5</div></div><div><span># 1. 读取源文件</span></div></div><div><div><div>6</div></div><div><span># 2. 分析代码逻辑</span></div></div><div><div><div>7</div></div><div><span># 3. 编写修改后的代码</span></div></div><div><div><div>8</div></div><div><span># 4. 询问是否应用</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Shell 命令执行<a href="#shell-命令执行"><span>#</span></a></h3><p>AI 可以帮你执行各种 Shell 命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 输入："运行一下测试用例"</span></div></div><div><div><div>2</div></div><div><span># AI 会执行：npm test</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 输入："帮我启动开发服务器"</span></div></div><div><div><div>5</div></div><div><span># AI 会执行：npm run dev</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 想看输出结果？实时显示！</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>子 Agent 并行工作<a href="#子-agent-并行工作"><span>#</span></a></h3><p>这是高级功能，可以让多个 AI Agent 同时工作：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 输入："帮我同时更新三个模块的依赖"</span></div></div><div><div><div>2</div></div><div><span># AI 会：</span></div></div><div><div><div>3</div></div><div><span># 1. 创建一个子 Agent 处理模块A</span></div></div><div><div><div>4</div></div><div><span># 2. 创建一个子 Agent 处理模块B</span></div></div><div><div><div>5</div></div><div><span># 3. 创建一个子 Agent 处理模块C</span></div></div><div><div><div>6</div></div><div><span># 4. 协调三个 Agent 并行工作</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>网页搜索<a href="#网页搜索"><span>#</span></a></h3><p>AI 可以帮你搜索网页获取信息：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 输入："帮我查一下 Rust 最新版有什么新特性"</span></div></div><div><div><div>2</div></div><div><span># AI 会使用 DuckDuckGo 搜索</span></div></div><div><div><div>3</div></div><div><span># 返回搜索结果并总结</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Git 操作<a href="#git-操作"><span>#</span></a></h3><p>集成 Git 功能，代码管理更方便：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 输入："查看最近的提交"</span></div></div><div><div><div>2</div></div><div><span># AI 执行 git log 并分析</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 输入："帮我审查这个 PR"</span></div></div><div><div><div>5</div></div><div><span># AI 分析代码变更并给出建议</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 输入："应用这个补丁"</span></div></div><div><div><div>8</div></div><div><span># AI 执行 git apply</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>费用追踪<a href="#费用追踪"><span>#</span></a></h3><p>每次对话都会显示 token 消耗和费用：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>对话费用：</span></div></div><div><div><div>2</div></div><div><span>├─ 输入 tokens: 1,234</span></div></div><div><div><div>3</div></div><div><span>├─ 输出 tokens: 567</span></div></div><div><div><div>4</div></div><div><span>├─ 费用: $0.0008</span></div></div><div><div><div>5</div></div><div><span>└─ 模型: deepseek-v4-flash</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>对比一下价格就知道有多实惠了：</p>

<table><thead><tr><th>模型</th><th>输入价格</th><th>输出价格</th></tr></thead><tbody><tr><td>DeepSeek V4 Flash</td><td>$0.14/百万token</td><td>$0.28/百万token</td></tr><tr><td>Claude Sonnet</td><td>$3/百万token</td><td>$15/百万token</td></tr><tr><td>差距</td><td><strong>21倍便宜</strong></td><td><strong>53倍便宜</strong></td></tr></tbody></table></section></section>
<section><h2>我的使用感受<a href="#我的使用感受"><span>#</span></a></h2><p>作为一个每天要在终端里干活的开发者，我必须说 DeepSeek-TUI 彻底改变了我的编程方式。以前用网页版 AI 辅助编程，效率真的很低——让 AI 看代码要复制粘贴，让 AI 改代码要手动复制回来，让 AI 执行命令更是想都别想。</p><p>现在有了 DeepSeek-TUI，我直接在终端里和 AI 对话，让它读写文件、执行命令、管理 Git。要分析整个项目？100万 token 上下文直接搞定，不用手动挑文件。要改代码？AI 一步步来，每次操作都清清楚楚，我可以随时介入或批准。</p><p>最让我惊喜的是子 Agent 功能！上次让三个子 Agent 同时处理三个模块的依赖更新，效率直接翻了三倍。而且价格还这么便宜，用 Claude 要花的钱，用 DeepSeek 够用好几个月了！</p></section>
<section><h2>项目资源<a href="#项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>: <a href="https://github.com/Hmbown/DeepSeek-TUI" target="_blank">https://github.com/Hmbown/DeepSeek-TUI</a></p><p><strong>官网地址</strong>: <a href="https://deepseek-tui.com" target="_blank">https://deepseek-tui.com</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p><p><strong>项目特色</strong>: DeepSeek 版的 Claude Code，终端原生 AI 编程 Agent，100万 token 上下文，多种工作模式支持，价格实惠。</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你是不是已经跃跃欲试了？赶紧安装 DeepSeek-TUI，体验一下终端里 AI 编程的畅快感吧！</p><p>如果你用了之后有什么有趣的体验，或者有什么问题，欢迎在评论区和我交流。我会定期分享更多好用的 AI 工具，记得关注我哦！</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/hexhub-intro/</id>
      <title type="text">HexHub：程序员和运维的“瑞士军刀” Navicat+Xshell+XFtp+Docker一站替代</title>
      <published>2026-05-08T00:00:00.000Z</published>
      <updated>2026-05-08T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/hexhub-intro/"/>
      <summary type="text">Database、Docker、SSH、SFTP一网打尽，让开发运维更高效</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>嘿，小伙伴们！作为开发者和运维人员，每天是不是要在各种工具之间来回切换？SSH连接服务器要用Xshell，数据库管理要用Navicat，Docker管理又要用Portainer，SFTP传文件还要打开FileZilla…窗口开得比代码还多，找个工具半天找不到，效率低得让人抓狂！</p><p>直到最近发现了一个宝藏工具——<strong>HexHub</strong>！这是一款专门为程序员和运维人员打造的一站式开发运维利器，把数据库、Docker、SSH、SFTP等功能全部集成在一个软件里。一个窗口搞定所有操作，简直就是为我们量身定制的神器！</p><p>今天我就来和大家唠唠这个神奇的工具，看看它是怎么让开发运维变得如此轻松的！</p></section>
<section><h2>项目介绍<a href="#项目介绍"><span>#</span></a></h2><section><h3>✨ 核心特性<a href="#-核心特性"><span>#</span></a></h3><ul>
<li><strong>🎯 一站式集成</strong>: Database、Docker、SSH、SFTP，All in One！</li>
<li><strong>🌐 跨平台支持</strong>: Windows、macOS、Linux，全平台可用</li>
<li><strong>🎨 双主题设计</strong>: 亮色/暗色主题，保护你的眼睛</li>
<li><strong>🚀 专业功能</strong>: 分屏广播输入、跨服务器文件传输、实时面板</li>
<li><strong>💰 免费可用</strong>: 社区版完全免费，核心功能一应俱全</li>
</ul></section><section><h3>📦 支持的数据库<a href="#-支持的数据库"><span>#</span></a></h3>

<table><thead><tr><th>数据库类型</th><th>支持版本</th></tr></thead><tbody><tr><td>MySQL</td><td>✅</td></tr><tr><td>PostgreSQL</td><td>✅</td></tr><tr><td>SQLite</td><td>✅</td></tr><tr><td>SQL Server</td><td>✅</td></tr><tr><td>Oracle</td><td>✅</td></tr><tr><td>Redis</td><td>✅</td></tr><tr><td>ClickHouse</td><td>✅</td></tr><tr><td>MariaDB</td><td>✅</td></tr><tr><td>达梦</td><td>✅</td></tr><tr><td>人大金仓</td><td>✅</td></tr><tr><td>OpenGauss</td><td>✅</td></tr><tr><td>OceanBase</td><td>✅</td></tr><tr><td>PolarDB</td><td>✅</td></tr></tbody></table></section><section><h3>🛠️ 主要功能模块<a href="#️-主要功能模块"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>┌─────────────────────────────────────────┐</span></div></div><div><div><div>2</div></div><div><span>│              HexHub                     │</span></div></div><div><div><div>3</div></div><div><span>├──────────────┬──────────────────────────┤</span></div></div><div><div><div>4</div></div><div><span>│   Database   │  SQL查询、表结构编辑      │</span></div></div><div><div><div>5</div></div><div><span>│              │  数据同步、数据字典导出   │</span></div></div><div><div><div>6</div></div><div><span>├──────────────┼──────────────────────────┤</span></div></div><div><div><div>7</div></div><div><span>│    SSH      │  终端连接、跳板机         │</span></div></div><div><div><div>8</div></div><div><span>│              │  X11转发、分屏广播输入   │</span></div></div><div><div><div>9</div></div><div><span>├──────────────┼──────────────────────────┤</span></div></div><div><div><div>10</div></div><div><span>│    SFTP     │  文件上传下载、权限管理   │</span></div></div><div><div><div>11</div></div><div><span>│              │  跨服务器文件传输        │</span></div></div><div><div><div>12</div></div><div><span>├──────────────┼──────────────────────────┤</span></div></div><div><div><div>13</div></div><div><span>│   Docker    │  容器管理、镜像管理       │</span></div></div><div><div><div>14</div></div><div><span>│              │  容器终端、日志查看      │</span></div></div><div><div><div>15</div></div><div><span>└──────────────┴──────────────────────────┘</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section>
<section><h2>实战体验<a href="#实战体验"><span>#</span></a></h2><section><h3>下载安装<a href="#下载安装"><span>#</span></a></h3><p>首先，去官网下载安装包：</p><p><strong>官网地址</strong>: <a href="https://www.hexhub.cn/" target="_blank">https://www.hexhub.cn/</a></p><p>支持三大平台：</p><ul>
<li><strong>Windows</strong>: <code>.exe</code> 安装包</li>
<li><strong>macOS</strong>: <code>.dmg</code> 磁盘镜像</li>
<li><strong>Linux</strong>: <code>.deb</code> / <code>.rpm</code></li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/1d4746ed21524813a3f68478c05dcf6020260508134510489.png" alt="" /></p></section><section><h3>SSH 连接服务器<a href="#ssh-连接服务器"><span>#</span></a></h3><p>打开 HexHub，点击左侧「SSH」图标：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 新建连接配置</span></div></div><div><div><div>2</div></div><div><span>├─ 名称: 生产服务器</span></div></div><div><div><div>3</div></div><div><span>├─ 主机: 192.168.1.100</span></div></div><div><div><div>4</div></div><div><span>├─ 端口: 22</span></div></div><div><div><div>5</div></div><div><span>├─ 用户名: root</span></div></div><div><div><div>6</div></div><div><span>└─ 认证方式: 密码/秘钥/交互式</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>分屏广播输入<a href="#分屏广播输入"><span>#</span></a></h3><p>管理多台服务器时，这个功能简直是神器！</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 分屏广播输入操作</span></div></div><div><div><div>2</div></div><div><span>1.</span><span> </span><span>打开多个服务器连接</span></div></div><div><div><div>3</div></div><div><span>2.</span><span> </span><span>点击「广播输入」按钮</span></div></div><div><div><div>4</div></div><div><span>3.</span><span> </span><span>在任意窗口输入命令</span></div></div><div><div><div>5</div></div><div><span>4.</span><span> </span><span>所有窗口同步执行！</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/0a5923e17f0c4149a9db4a84f972088b20260508134650044.png" alt="" /></p></section><section><h3>SFTP 文件传输<a href="#sftp-文件传输"><span>#</span></a></h3><p>SSH 连接的同时，自动打开 SFTP 面板：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 文件操作</span></div></div><div><div><div>2</div></div><div><span>├─</span><span> </span><span>拖拽上传/下载</span></div></div><div><div><div>3</div></div><div><span>├─</span><span> </span><span>右键菜单操作</span></div></div><div><div><div>4</div></div><div><span>├─</span><span> </span><span>权限管理</span><span>(</span><span>chmod</span><span>)</span></div></div><div><div><div>5</div></div><div><span>└─</span><span> </span><span>SUDO提权编辑</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>支持跨服务器文件传输，复制粘贴即可：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 跨服务器文件传输</span></div></div><div><div><div>2</div></div><div><span>1.</span><span> </span><span>在服务器A选中文件</span><span> </span><span>→</span><span> </span><span>Ctrl+C</span></div></div><div><div><div>3</div></div><div><span>2.</span><span> </span><span>在服务器B目标目录</span><span> </span><span>→</span><span> </span><span>Ctrl+V</span></div></div><div><div><div>4</div></div><div><span>3.</span><span> </span><span>自动完成传输！</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/eccc81ebcc2045e4bc10fb1e5945c10820260508135027359.png" alt="" /></p></section><section><h3>数据库管理<a href="#数据库管理"><span>#</span></a></h3><p>支持 15+ 种数据库，一个界面搞定所有：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 数据库操作</span></div></div><div><div><div>2</div></div><div><span>├─</span><span> </span><span>SQL查询编辑器（语法高亮）</span></div></div><div><div><div>3</div></div><div><span>├─</span><span> </span><span>表结构可视化编辑</span></div></div><div><div><div>4</div></div><div><span>├─</span><span> </span><span>数据内联编辑</span></div></div><div><div><div>5</div></div><div><span>├─</span><span> </span><span>数据字典导出</span></div></div><div><div><div>6</div></div><div><span>└─</span><span> </span><span>XLSX导入导出</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>连接配置也很简单：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># MySQL连接配置</span></div></div><div><div><div>2</div></div><div><span>├─ 类型: MySQL</span></div></div><div><div><div>3</div></div><div><span>├─ 主机: localhost</span></div></div><div><div><div>4</div></div><div><span>├─ 端口: 3306</span></div></div><div><div><div>5</div></div><div><span>├─ 数据库: test</span></div></div><div><div><div>6</div></div><div><span>└─ 用户名/密码</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/625d34cceb2646d8a264353315ec23ed20260508134832979.png" alt="" /></p></section><section><h3>Docker 管理<a href="#docker-管理"><span>#</span></a></h3><p>可视化管理 Docker 容器和镜像：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Docker功能</span></div></div><div><div><div>2</div></div><div><span>├─</span><span> </span><span>容器列表（状态一目了然）</span></div></div><div><div><div>3</div></div><div><span>├─</span><span> </span><span>容器终端（直接进入容器）</span></div></div><div><div><div>4</div></div><div><span>├─</span><span> </span><span>容器日志（实时查看）</span></div></div><div><div><div>5</div></div><div><span>├─</span><span> </span><span>镜像管理（拉取/删除）</span></div></div><div><div><div>6</div></div><div><span>└─</span><span> </span><span>镜像导入导出</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>专业版还支持 Docker-Compose 编辑：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># Docker-Compose 示例</span></div></div><div><div><div>2</div></div><div><span>version</span><span>: </span><span>'3.8'</span></div></div><div><div><div>3</div></div><div><span>services</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>web</span><span>:</span></div></div><div><div><div>5</div></div><div><span>    </span><span>image</span><span>: </span><span>nginx:latest</span></div></div><div><div><div>6</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>"80:80"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/bad54d5eb56047e299bdd82a764fe2bc20260508134908853.png" alt="" /></p></section><section><h3>实时面板<a href="#实时面板"><span>#</span></a></h3><p>一键查看服务器状态：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 实时面板内容</span></div></div><div><div><div>2</div></div><div><span>├─</span><span> </span><span>网速监控（上传/下载）</span></div></div><div><div><div>3</div></div><div><span>├─</span><span> </span><span>CPU使用率</span></div></div><div><div><div>4</div></div><div><span>├─</span><span> </span><span>内存使用率</span></div></div><div><div><div>5</div></div><div><span>├─</span><span> </span><span>进程列表</span></div></div><div><div><div>6</div></div><div><span>├─</span><span> </span><span>Docker容器列表</span></div></div><div><div><div>7</div></div><div><span>└─</span><span> </span><span>磁盘挂载列表</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/f7c857c9256e472f8e53b36461cc9d2520260508134945635.png" alt="" /></p></section></section>
<section><h2>我的使用感受<a href="#我的使用感受"><span>#</span></a></h2><p>作为一个每天要管理十几台服务器的运维工程师，我必须说 HexHub 彻底改变了我的工作方式。以前打开一堆工具窗口，找个连接要半天，现在一个 HexHub 搞定所有！</p><p>最让我惊喜的是分屏广播输入功能，以前更新配置要一台台服务器登录执行，现在一键同步，效率提升了十倍不止。还有跨服务器文件传输，再也不用先下载到本地再上传了，直接复制粘贴就搞定！</p></section>
<section><h2>项目资源<a href="#项目资源"><span>#</span></a></h2><p><strong>官网地址</strong>: <a href="https://www.hexhub.cn/" target="_blank">https://www.hexhub.cn/</a></p><p><strong>下载地址</strong>: <a href="https://www.hexhub.cn/#download" target="_blank">https://www.hexhub.cn/#download</a></p><p>觉得工具不错的话，记得分享给你的小伙伴！</p><p><strong>项目特色</strong>: 一站式开发运维工具，集成数据库、Docker、SSH、SFTP，支持跨平台，免费版功能齐全，专业版功能强大。</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你是不是已经受够了在各种工具之间来回切换？赶紧试试 HexHub，体验一下一站式开发运维的快感！</p><p>如果你用了之后有什么有趣的体验，或者有什么功能建议，欢迎在评论区和我交流。我会定期分享更多好用的开发工具，记得关注我哦！</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/llmfit-intro/</id>
      <title type="text">GitHub热门项目！llmfit，一键找到最适合你电脑的大模型</title>
      <published>2026-05-06T00:00:00.000Z</published>
      <updated>2026-05-06T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/llmfit-intro/"/>
      <summary type="text">自动检测硬件配置，智能推荐最适合的LLM模型，让你的AI体验更流畅</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>嘿，小伙伴们！最近是不是经常遇到这样的困扰：想在本地跑大模型，但不知道自己的电脑能跑哪个？下载了模型才发现显存不够，或者速度慢得让人抓狂？作为一个AI爱好者，我太懂这种感受了！曾经为了找一个适合我笔记本的模型，我试遍了各种方法，浪费了大量时间下载那些根本跑不动的模型。</p><p>直到最近发现了一个宝藏项目——<strong>llmfit</strong>！这是一个专门为本地大模型爱好者打造的工具，只要一条命令，它就能自动检测你的硬件配置，评估上百个模型在你电脑上的运行情况，然后告诉你哪些模型能完美运行，哪些可以勉强运行，哪些根本跑不动。</p><p>这两天这个项目在AI圈子里特别火，今天我就来和大家唠唠这个神奇的工具，让你再也不用为选模型发愁！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/cd03ce2f1a434e29ac184e5223834ac020260506112437986.png" alt="" /></p></section>
<section><h2>项目介绍<a href="#项目介绍"><span>#</span></a></h2><section><h3>✨ 核心特性<a href="#-核心特性"><span>#</span></a></h3><ul>
<li><strong>🔍 智能硬件检测</strong>: 自动识别你的 CPU、GPU、RAM 配置，支持 CUDA、Metal、ROCm 等加速后端</li>
<li><strong>📊 多维度评分</strong>: 从质量、速度、适配性、上下文四个维度为每个模型打分</li>
<li><strong>🚀 一键推荐</strong>: 告诉你哪些模型能完美运行，哪些可以尝试，哪些直接放弃</li>
<li><strong>💬 交互式界面</strong>: 漂亮的 TUI 界面，操作直观，新手也能轻松上手</li>
<li><strong>🔧 灵活模式</strong>: 支持 TUI（交互式）和 CLI（命令行）两种模式</li>
<li><strong>⚡ 支持多GPU</strong>: 完美支持多GPU配置，充分利用你的硬件资源</li>
<li><strong>🧠 MoE支持</strong>: 支持 Mixture-of-Experts 架构的模型评估</li>
</ul></section><section><h3>📊 评分维度<a href="#-评分维度"><span>#</span></a></h3>

<table><thead><tr><th>维度</th><th>说明</th><th>权重</th></tr></thead><tbody><tr><td><strong>质量 (Quality)</strong></td><td>模型本身的能力和性能</td><td>35%</td></tr><tr><td><strong>速度 (Speed)</strong></td><td>推理速度估计</td><td>25%</td></tr><tr><td><strong>适配性 (Fit)</strong></td><td>模型与硬件的匹配程度</td><td>25%</td></tr><tr><td><strong>上下文 (Context)</strong></td><td>上下文窗口大小</td><td>15%</td></tr></tbody></table></section></section>
<section><h2>实战体验<a href="#实战体验"><span>#</span></a></h2><section><h3>安装方式<a href="#安装方式"><span>#</span></a></h3><p><strong>方式一：一键安装（推荐）</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># macOS/Linux 一键安装</span></div></div><div><div><div>2</div></div><div><span>curl</span><span> </span><span>-fsSL</span><span> </span><span>https://llmfit.axjns.dev/install.sh</span><span> | </span><span>sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式二：Homebrew 安装（macOS）</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>brew</span><span> </span><span>tap</span><span> </span><span>AlexsJones/llmfit</span><span> &amp;&amp; </span><span>brew</span><span> </span><span>install</span><span> </span><span>llmfit</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式三：Cargo 安装</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cargo</span><span> </span><span>install</span><span> </span><span>llmfit</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>启动工具<a href="#启动工具"><span>#</span></a></h3><p>安装完成后，直接在终端输入：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>llmfit</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>工具会自动检测你的硬件配置，然后显示交互式界面：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/0572b5f44f9747e583607b038279cc1d20260506141142650.png" alt="" /></p></section><section><h3>查看推荐模型<a href="#查看推荐模型"><span>#</span></a></h3><p>界面会显示所有支持的模型，并按照适配程度排序：</p><ul>
<li><strong>Perfect</strong>: 完美适配，推荐使用</li>
<li><strong>Good</strong>: 良好适配，可以尝试</li>
<li><strong>Marginal</strong>: 勉强运行，可能卡顿</li>
<li><strong>Too tight</strong>: 显存不足，不建议尝试</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/4751c43305fd4585b33ad952cbf20f0920260506141207005.png" alt="" /></p></section><section><h3>CLI 模式<a href="#cli-模式"><span>#</span></a></h3><p>如果你喜欢命令行方式，可以使用 <code>--cli</code> 参数：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 查看所有可用模型</span></div></div><div><div><div>2</div></div><div><span>llmfit</span><span> </span><span>--cli</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 只显示能完美运行的模型</span></div></div><div><div><div>5</div></div><div><span>llmfit</span><span> </span><span>--cli</span><span> </span><span>--perfect</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 指定显存限制</span></div></div><div><div><div>8</div></div><div><span>llmfit</span><span> </span><span>--cli</span><span> </span><span>--memory</span><span> </span><span>24G</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 输出 JSON 格式</span></div></div><div><div><div>11</div></div><div><span>llmfit</span><span> </span><span>--cli</span><span> </span><span>--json</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>筛选模型<a href="#筛选模型"><span>#</span></a></h3><p>使用各种筛选参数找到最适合你的模型：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 按使用场景筛选</span></div></div><div><div><div>2</div></div><div><span>llmfit</span><span> </span><span>--use-case</span><span> </span><span>coding</span><span>    </span><span># 编码</span></div></div><div><div><div>3</div></div><div><span>llmfit</span><span> </span><span>--use-case</span><span> </span><span>reasoning</span><span> </span><span># 推理</span></div></div><div><div><div>4</div></div><div><span>llmfit</span><span> </span><span>--use-case</span><span> </span><span>chat</span><span>      </span><span># 聊天</span></div></div><div><div><div>5</div></div><div><span>llmfit</span><span> </span><span>--use-case</span><span> </span><span>multimodal</span><span> </span><span># 多模态</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 按运行时筛选</span></div></div><div><div><div>8</div></div><div><span>llmfit</span><span> </span><span>--runtime</span><span> </span><span>llamacpp</span></div></div><div><div><div>9</div></div><div><span>llmfit</span><span> </span><span>--runtime</span><span> </span><span>mlx</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span># 搜索模型</span></div></div><div><div><div>12</div></div><div><span>llmfit</span><span> </span><span>--search</span><span> </span><span>"Qwen"</span></div></div><div><div><div>13</div></div><div><span>llmfit</span><span> </span><span>--search</span><span> </span><span>"7B"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/25b0279f2b8345dd863a9e831ec006c320260506141238651.png" alt="" /></p></section><section><h3>API 服务模式<a href="#api-服务模式"><span>#</span></a></h3><p>llmfit 还提供了 REST API，可以集成到你的应用中：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 启动 API 服务</span></div></div><div><div><div>2</div></div><div><span>llmfit</span><span> </span><span>serve</span><span> </span><span>--host</span><span> </span><span>0.0.0.0</span><span> </span><span>--port</span><span> </span><span>8787</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 获取系统信息</span></div></div><div><div><div>2</div></div><div><span>curl</span><span> </span><span>http://localhost:8787/api/v1/system</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 获取推荐模型</span></div></div><div><div><div>5</div></div><div><span>curl</span><span> </span><span>http://localhost:8787/api/v1/models/top?limit=</span><span>5</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 按场景筛选</span></div></div><div><div><div>8</div></div><div><span>curl</span><span> </span><span>"http://localhost:8787/api/v1/models?use_case=coding&amp;min_fit=good"</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>我的使用感受<a href="#我的使用感受"><span>#</span></a></h2><p>作为一个经常折腾本地大模型的爱好者，我必须说这个工具彻底改变了我的体验。以前每次想换个模型试试，都要先查半天资料，下载下来才发现跑不动或者速度太慢。现在有了 llmfit，一键就能知道哪些模型适合我的配置，节省了大量时间和带宽。</p><p>最让我惊喜的是它对 MoE 模型的支持，以前我根本不敢碰那些大模型，现在有了准确的显存估算，我知道哪些 MoE 模型能在我的显卡上运行了。而且界面做得特别漂亮，交互也很流畅，用起来特别舒服！</p></section>
<section><h2>项目资源<a href="#项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>: <a href="https://github.com/AlexsJones/llmfit" target="_blank">https://github.com/AlexsJones/llmfit</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p><p><strong>项目特色</strong>: 智能大模型硬件匹配工具，自动检测配置，多维度评分推荐，支持 TUI/CLI/API 三种模式，支持 MoE 架构和多 GPU 配置。</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你是不是已经跃跃欲试了？赶紧安装 llmfit，看看你的电脑能跑哪些大模型吧！</p><p>如果你用了之后有什么有趣的发现，或者有什么问题，欢迎在评论区和我交流。我会定期分享更多好用的 AI 工具和技术教程，记得关注我哦！</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/motrix-next-intro/</id>
      <title type="text">GitHub宝藏项目！Motrix Next，让下载变成一种享受</title>
      <published>2026-05-06T00:00:00.000Z</published>
      <updated>2026-05-06T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/motrix-next-intro/"/>
      <summary type="text">基于Tauri 2重写的下载神器，15MB安装包替代90MB老版本，更轻更快更强</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>嘿，小伙伴们！不知道你们有没有遇到过这些糟心事：浏览器下载大文件，速度慢得像蜗牛不说，还动不动就断开；公司电脑配置低，用个下载工具占内存比浏览器还多；想下载个学习资料，文件名还乱码成一堆乱字符…作为一个经常下载各种资源的老网民，我太懂这种感受了！每次遇到下载问题，都恨不得把那个软件给卸载了。</p><p>直到最近发现了一个宝藏项目——<strong>Motrix Next</strong>！这是一款基于 Tauri 2 全新重写的下载工具，安装包只有 15MB，却能做 90MB 老版本做不到的事情。更轻、更快、更安全，用起来还特别顺手，简直就是下载工具中的”小钢炮”！</p><p>今天我就来和大家唠唠这个神器，看看它是怎么解决我们这些下载痛点的！</p></section>
<section><h2>项目介绍<a href="#项目介绍"><span>#</span></a></h2><section><h3>✨ 核心特性<a href="#-核心特性"><span>#</span></a></h3><ul>
<li><strong>🚀 轻量高效</strong>: 安装包仅 15MB，内存占用极低，Rust 后端保障性能</li>
<li><strong>🔧 全协议支持</strong>: HTTP/FTP/BT/Magnet/Thunder，一网打尽所有下载需求</li>
<li><strong>🎨 全新 UI</strong>: Material Design 3 风格，支持深色模式，界面美观大方</li>
<li><strong>🌐 26种语言</strong>: 完整国际化支持，切换语言无压力</li>
<li><strong>🔄 自动更新</strong>: 稳定版/测试版双通道，想尝鲜还是求稳定随你选</li>
<li><strong>💾 断点续传</strong>: 告别下载中断的烦恼，从头再来不存在的</li>
</ul></section><section><h3>🆚 对比老版本<a href="#-对比老版本"><span>#</span></a></h3>

<table><thead><tr><th>特性</th><th>Motrix (老版)</th><th>Motrix Next</th></tr></thead><tbody><tr><td>框架</td><td>Electron</td><td><strong>Tauri 2 (Rust)</strong></td></tr><tr><td>前端</td><td>Vue 2 + VueX</td><td><strong>Vue 3 + Pinia</strong></td></tr><tr><td>安装包大小</td><td>~90 MB</td><td><strong>~15 MB</strong></td></tr><tr><td>内存占用</td><td>较高</td><td><strong>极低</strong></td></tr><tr><td>启动速度</td><td>较慢</td><td><strong>秒开</strong></td></tr><tr><td>安全性</td><td>一般</td><td><strong>Rust内存安全</strong></td></tr></tbody></table></section><section><h3>🛠️ 技术栈<a href="#️-技术栈"><span>#</span></a></h3>

<table><thead><tr><th>分类</th><th>技术</th></tr></thead><tbody><tr><td>框架</td><td>Tauri 2</td></tr><tr><td>前端</td><td>Vue 3 + TypeScript</td></tr><tr><td>状态管理</td><td>Pinia</td></tr><tr><td>UI组件</td><td>Naive UI</td></tr><tr><td>下载引擎</td><td>aria2</td></tr><tr><td>语言</td><td>Rust + TypeScript</td></tr></tbody></table></section></section>
<section><h2>实战体验<a href="#实战体验"><span>#</span></a></h2><section><h3>下载安装<a href="#下载安装"><span>#</span></a></h3><p>首先，咱们去 GitHub 下载安装包：</p><p><strong>下载地址</strong>: <a href="https://github.com/AnInsomniacy/motrix-next/releases" target="_blank">https://github.com/AnInsomniacy/motrix-next/releases</a></p><p>支持三大平台：</p><ul>
<li><strong>Windows</strong>: x64 / ARM64 (.exe)</li>
<li><strong>macOS</strong>: Apple Silicon / Intel (.dmg)</li>
<li><strong>Linux</strong>: x64 / ARM64 (.AppImage / .deb)</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Windows 用户双击 .exe 安装包，一路下一步即可</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span># macOS 用户拖拽到 Applications 文件夹</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># Linux 用户</span></div></div><div><div><div>6</div></div><div><span>sudo</span><span> </span><span>dpkg</span><span> </span><span>-i</span><span> </span><span>MotrixNext_</span><span>*</span><span>.deb</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/61f6045e82944044af57aa82ca1f44f820260507085731979.png" alt="" /></p></section><section><h3>界面初体验<a href="#界面初体验"><span>#</span></a></h3><p>打开软件，第一感觉就是清爽！Material Design 3 的设计风格看起来特别舒服：</p><ul>
<li>左侧是任务列表，清晰展示所有下载任务</li>
<li>顶部是工具栏，常用功能一目了然</li>
<li>右下角是速度面板，实时网速一览无余</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/e20a50c73fc64541884f9ddf301a891320260507085819082.png" alt="" /></p></section><section><h3>新建下载任务<a href="#新建下载任务"><span>#</span></a></h3><p>有三种方式添加下载任务：</p><p><strong>方式一：直接粘贴链接</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 复制下载链接</span></div></div><div><div><div>2</div></div><div><span># 在 Motrix Next 中按下 Ctrl + V</span></div></div><div><div><div>3</div></div><div><span># 自动识别并添加任务</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式二：手动输入</strong></p><p>点击工具栏的「新建」按钮，输入下载链接和保存位置：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>任务配置：</span></div></div><div><div><div>2</div></div><div><span>├─ URL: https://example.com/file.zip</span></div></div><div><div><div>3</div></div><div><span>├─ 保存目录: D:\Downloads</span></div></div><div><div><div>4</div></div><div><span>└─ 文件名: file.zip</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式三：BT种子和磁力链接</strong></p><p>直接拖拽 .torrent 文件到窗口，或者粘贴磁力链接：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>magnet:?xt=urn:btih:xxxxx...</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/62e6c18cdbb541e19629d058f172be1120260507090122819.png" alt="" /></p></section><section><h3>BT下载增强功能<a href="#bt下载增强功能"><span>#</span></a></h3><p>Motrix Next 的 BT 功能特别强大！</p><p><strong>GeoIP 显示</strong>: 显示每个 peer 的国家国旗，一眼看出热门资源分布：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Peers:</span></div></div><div><div><div>2</div></div><div><span>🇨🇳 China (12 peers)</span></div></div><div><div><div>3</div></div><div><span>🇺🇸 USA (5 peers)</span></div></div><div><div><div>4</div></div><div><span>🇯🇵 Japan (3 peers)</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>tracker 列表管理</strong>: 自动获取最佳 tracker，提高下载速度：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 自动更新 tracker 列表</span></div></div><div><div><div>2</div></div><div><span># 无需手动配置，开箱即用</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/2d80c07014944c4ba001309497d8441b20260507090419125.png" alt="" /></p></section><section><h3>速度限制与调度<a href="#速度限制与调度"><span>#</span></a></h3><p>不想让下载占满带宽？没问题！</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 全局速度限制</span></div></div><div><div><div>2</div></div><div><span># 最大上传速度: 1 MB/s</span></div></div><div><div><div>3</div></div><div><span># 最大下载速度: 不限</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># 下载调度</span></div></div><div><div><div>6</div></div><div><span># 定时开始/停止下载任务</span></div></div><div><div><div>7</div></div><div><span># 自动化管理你的下载任务</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>轻量级模式<a href="#轻量级模式"><span>#</span></a></h3><p>这就是黑科技了！开启轻量级模式后，最小化到托盘会自动销毁 WebView，减少约 150MB 内存占用：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 开启轻量级模式</span></div></div><div><div><div>2</div></div><div><span># 设置 → 轻量级模式 → 启用</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 效果：</span></div></div><div><div><div>5</div></div><div><span># 内存占用减少 ~150MB</span></div></div><div><div><div>6</div></div><div><span># 托盘操作完全正常</span></div></div><div><div><div>7</div></div><div><span># 下载任务继续运行</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/05/a33b2e75b3d643cc832bd54c2753e8a320260507090300619.png" alt="" /></p></section><section><h3>保持唤醒功能<a href="#保持唤醒功能"><span>#</span></a></h3><p>下载大文件怕电脑睡着？开启「保持唤醒」功能：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 开启保持唤醒</span></div></div><div><div><div>2</div></div><div><span># 下载期间防止系统休眠</span></div></div><div><div><div>3</div></div><div><span># 支持 macOS / Windows / Linux</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>浏览器集成<a href="#浏览器集成"><span>#</span></a></h3><p>配合浏览器扩展使用更方便！</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 安装 Motrix Next 浏览器扩展</span></div></div><div><div><div>2</div></div><div><span># 支持 Chrome / Firefox / Edge</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 一键下载：</span></div></div><div><div><div>5</div></div><div><span># 页面点击下载按钮 → 自动唤醒 Motrix Next → 开始下载</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>我的使用感受<a href="#我的使用感受"><span>#</span></a></h2><p>作为一个下载工具的重度用户，我必须说 Motrix Next 彻底征服了我。以前用 Electron 版的下载工具，内存占用高得吓人，开个浏览器再加下载工具，电脑就开始卡顿。现在用了 Motrix Next，16GB 内存的笔记本终于不再”喘粗气”了！</p><p>最让我惊喜的是 BT 下载的 GeoIP 功能，以前不知道哪些peer是国内的，现在一眼就能看出来，下载热门资源的时候心里更有底了。还有那个轻量级模式，之前根本不敢边下载边做其他事，现在开着一堆任务，电脑照样流畅跑游戏！</p></section>
<section><h2>项目资源<a href="#项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>: <a href="https://github.com/AnInsomniacy/motrix-next" target="_blank">https://github.com/AnInsomniacy/motrix-next</a>
<strong>官网地址</strong>: <a href="https://motrix-next.pages.dev/" target="_blank">https://motrix-next.pages.dev/</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p><p><strong>项目特色</strong>: 基于 Tauri 2 全新重写的下载工具，支持全协议下载，15MB 安装包 + Rust 后端保障，内存占用极低，支持 26 种语言和深色模式。</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你是不是已经受够了那些卡顿、占地儿、还经常断流的下载工具？赶紧试试 Motrix Next，体验一下什么叫”轻盈下载”！</p><p>如果你用了之后有什么有趣的体验，或者下载过程中遇到什么问题，欢迎在评论区和我交流。我会定期分享更多好用的效率工具，记得关注我哦！</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/trek-travel-planner/</id>
      <title type="text">GitHub宝藏项目！TREK，五一出游必备的智能旅行规划神器</title>
      <published>2026-04-30T00:00:00.000Z</published>
      <updated>2026-04-30T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/trek-travel-planner/"/>
      <summary type="text">自托管旅行规划工具，实时协作、交互式地图、预算管理，五一出游必备</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>嘿，小伙伴们！五一假期马上就要到了，是不是已经按捺不住想要出去玩的心情了？作为一个爱旅行的”驴友”，每次出行前最头疼的就是做攻略——景点太多不知道怎么安排、路线规划太复杂、预算总是超支…相信很多朋友都有同感吧？</p><p>直到最近发现了一个宝藏项目——<strong>TREK</strong>！这是一个开源的自托管旅行规划工具，简直就是为我们这些爱旅行的人量身打造的。有了它，旅行规划变得超级简单：实时协作让团队旅行更高效，交互式地图让路线规划一目了然，预算追踪帮你控制开支，打包清单再也不会丢三落四。</p></section>
<section><h2>项目介绍<a href="#项目介绍"><span>#</span></a></h2><section><h3>✨ 核心特性<a href="#-核心特性"><span>#</span></a></h3><ul>
<li><strong>🧭 智能行程规划</strong>: 拖拽式规划器，轻松安排每天的行程，支持跨天调整和重新排序</li>
<li><strong>🗺️ 交互式地图</strong>: 支持 Leaflet 或 Mapbox GL，带3D建筑、地形、照片标记和路线可视化</li>
<li><strong>🔍 地点搜索</strong>: 支持 Google Places 和 OpenStreetMap，找景点、餐厅、住宿超方便</li>
<li><strong>📝 每日笔记</strong>: 带时间戳和图标的笔记功能，记录旅行点滴</li>
<li><strong>🚗 路线优化</strong>: 自动排序地点，支持导出到 Google Maps</li>
<li><strong>🌤️ 天气预报</strong>: 16天天气预报，提前做好出行准备</li>
<li><strong>💰 预算追踪</strong>: 分类支出管理，支持多人分摊和多币种</li>
<li><strong>🧳 打包清单</strong>: 分类模板、成员分配、进度追踪，再也不会漏东西</li>
</ul></section><section><h3>👥 团队协作功能<a href="#-团队协作功能"><span>#</span></a></h3><ul>
<li><strong>🔄 实时同步</strong>: WebSocket 实时同步，修改即时显示</li>
<li><strong>👨‍👩‍👧‍👦 多用户协作</strong>: 支持多人共享行程，角色权限管理</li>
<li><strong>📧 邀请链接</strong>: 一次性或可重复使用的邀请链接，带有效期</li>
<li><strong>🔐 SSO 登录</strong>: 支持 Google、Apple、Authentik、Keycloak 等多种登录方式</li>
<li><strong>💬 团队聊天</strong>: 群组聊天、共享笔记、投票、每日签到</li>
</ul></section><section><h3>📱 移动体验<a href="#-移动体验"><span>#</span></a></h3><ul>
<li><strong>📲 PWA 支持</strong>: iOS 和 Android 都能安装，无需应用商店</li>
<li><strong>📴 离线支持</strong>: 离线缓存地图和数据，旅途中随时查看</li>
<li><strong>🎨 原生体验</strong>: 全屏独立运行，主题状态栏，启动画面</li>
</ul></section></section>
<section><h2>实战体验<a href="#实战体验"><span>#</span></a></h2><section><h3>快速开始<a href="#快速开始"><span>#</span></a></h3><p>TREK 支持多种部署方式，最简单的就是用 Docker：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 生成加密密钥</span></div></div><div><div><div>2</div></div><div><span>ENCRYPTION_KEY</span><span><span>=</span><span>$(</span></span><span>openssl</span><span> </span><span>rand</span><span> </span><span>-hex</span><span> </span><span>32</span><span>)</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 启动容器</span></div></div><div><div><div>5</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>-p</span><span> </span><span>3000:3000</span><span> </span><span>\</span></div></div><div><div><div>6</div></div><div><span>  </span><span>-e</span><span> </span><span>ENCRYPTION_KEY=</span><span>$ENCRYPTION_KEY</span><span> </span><span>\</span></div></div><div><div><div>7</div></div><div><span>  </span><span>-v</span><span> </span><span>./data:/app/data</span><span> </span><span>-v</span><span> </span><span>./uploads:/app/uploads</span><span> </span><span>mauriceboe/trek</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>Docker Compose 部署</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>app</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image</span><span>: </span><span>mauriceboe/trek:latest</span></div></div><div><div><div>4</div></div><div><span>    </span><span>container_name</span><span>: </span><span>trek</span></div></div><div><div><div>5</div></div><div><span>    </span><span>read_only</span><span>: </span><span>true</span></div></div><div><div><div>6</div></div><div><span>    </span><span>security_opt</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>no-new-privileges:true</span></div></div><div><div><div>8</div></div><div><span>    </span><span>cap_drop</span><span>:</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>- </span><span>ALL</span></div></div><div><div><div>10</div></div><div><span>    </span><span>cap_add</span><span>:</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>- </span><span>CHOWN</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>- </span><span>SETUID</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span>- </span><span>SETGID</span></div></div><div><div><div>14</div></div><div><span>    </span><span>tmpfs</span><span>:</span></div></div><div><div><div>15</div></div><div><span><span>      </span></span><span>- </span><span>/tmp:noexec,nosuid,size=64m</span></div></div><div><div><div>16</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>17</div></div><div><span><span>      </span></span><span>- </span><span>"3000:3000"</span></div></div><div><div><div>18</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>19</div></div><div><span><span>      </span></span><span>- </span><span>NODE_ENV=production</span></div></div><div><div><div>20</div></div><div><span><span>      </span></span><span>- </span><span>PORT=3000</span></div></div><div><div><div>21</div></div><div><span><span>      </span></span><span>- </span><span>ENCRYPTION_KEY=${ENCRYPTION_KEY:-}</span><span>   </span><span># generate with: openssl rand -hex 32</span></div></div><div><div><div>22</div></div><div><span><span>      </span></span><span>- </span><span>TZ=${TZ:-UTC}</span></div></div><div><div><div>23</div></div><div><span><span>      </span></span><span>- </span><span>LOG_LEVEL=${LOG_LEVEL:-info}</span></div></div><div><div><div>24</div></div><div><span><span>      </span></span><span>- </span><span>ALLOWED_ORIGINS=${ALLOWED_ORIGINS:-}</span></div></div><div><div><div>25</div></div><div><span><span>      </span></span><span>- </span><span>APP_URL=${APP_URL:-}</span><span>                 </span><span># required for OIDC + email links</span></div></div><div><div><div>26</div></div><div><span>      </span><span># - FORCE_HTTPS=true                   # behind a TLS-terminating proxy</span></div></div><div><div><div>27</div></div><div><span>      </span><span># - TRUST_PROXY=1</span></div></div><div><div><div>28</div></div><div><span>      </span><span># - OIDC_ISSUER=https://auth.example.com</span></div></div><div><div><div>29</div></div><div><span>      </span><span># - OIDC_CLIENT_ID=trek</span></div></div><div><div><div>30</div></div><div><span>      </span><span># - OIDC_CLIENT_SECRET=supersecret</span></div></div><div><div><div>31</div></div><div><span>      </span><span># - OIDC_DISPLAY_NAME=SSO</span></div></div><div><div><div>32</div></div><div><span>      </span><span># - OIDC_ADMIN_CLAIM=groups</span></div></div><div><div><div>33</div></div><div><span>      </span><span># - OIDC_ADMIN_VALUE=app-trek-admins</span></div></div><div><div><div>34</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>35</div></div><div><span><span>      </span></span><span>- </span><span>./data:/app/data</span></div></div><div><div><div>36</div></div><div><span><span>      </span></span><span>- </span><span>./uploads:/app/uploads</span></div></div><div><div><div>37</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>38</div></div><div><span>    </span><span>healthcheck</span><span>:</span></div></div><div><div><div>39</div></div><div><span>      </span><span>test</span><span>: [</span><span>"CMD"</span><span>, </span><span>"wget"</span><span>, </span><span>"-qO-"</span><span>, </span><span>"http://localhost:3000/api/health"</span><span>]</span></div></div><div><div><div>40</div></div><div><span>      </span><span>interval</span><span>: </span><span>30s</span></div></div><div><div><div>41</div></div><div><span>      </span><span>timeout</span><span>: </span><span>10s</span></div></div><div><div><div>42</div></div><div><span>      </span><span>retries</span><span>: </span><span>3</span></div></div><div><div><div>43</div></div><div><span>      </span><span>start_period</span><span>: </span><span>15s</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>打开浏览器访问 <a href="http://localhost:3000" target="_blank">http://localhost:3000</a> 即可使用！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/88631dcd4acc4fdcbd584efbdd0b8ebc20260430140926290.png" alt="" /></p><blockquote><p>提示：首次登录时，需要从docker log 中获取默认账号密码  <code>docker logs trak</code>。</p></blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[DB] Running migration 125/125[DB] Migrations complete - schema version 125</span></div></div><div><div><div>2</div></div><div><span>TREK</span><span> </span><span>-</span><span> </span><span>First</span><span> </span><span>Run:</span><span> </span><span>Admin</span><span> </span><span>Account</span><span> </span><span>Created</span></div></div><div><div><div>3</div></div><div><span>Email:</span><span>  </span><span>admin@trek.local</span></div></div><div><div><div>4</div></div><div><span>Password:</span><span>  </span><span>XXXXXidJ4HS1</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>创建旅行计划<a href="#创建旅行计划"><span>#</span></a></h3><p>登录后，点击”新建行程”开始规划你的五一之旅：</p><ol>
<li><strong>设置基本信息</strong>: 输入行程名称、目的地、日期范围</li>
<li><strong>添加成员</strong>: 邀请家人或朋友一起协作规划</li>
<li><strong>规划每日行程</strong>: 拖拽地点到每一天的计划中</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/5cef17905a6a4ae88371231df8f5c89c20260430141258499.png" alt="" /></p></section><section><h3>搜索地点<a href="#搜索地点"><span>#</span></a></h3><p>使用地点搜索功能查找景点、餐厅、酒店：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 搜索示例</span></div></div><div><div><div>2</div></div><div><span>搜索 "北京故宫" → 查看评分、照片、营业时间 → 添加到行程</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>支持 Google Places 和 OpenStreetMap 两种数据源，后者完全免费无需 API 密钥。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/36e0dcb5b0874eaba5898faa8245da7920260430141502390.png" alt="" /></p></section><section><h3>查看地图<a href="#查看地图"><span>#</span></a></h3><p>交互式地图让你的行程一目了然：</p><ul>
<li>查看所有计划地点的位置分布</li>
<li>可视化路线规划</li>
<li>3D 建筑和地形视图</li>
<li>照片标记展示</li>
</ul></section><section><h3>管理预订<a href="#管理预订"><span>#</span></a></h3><p>记录航班、住宿、餐厅等预订信息：</p>

<table><thead><tr><th>类型</th><th>信息</th></tr></thead><tbody><tr><td>航班</td><td>航空公司、航班号、确认号</td></tr><tr><td>住宿</td><td>酒店名称、地址、入住时间</td></tr><tr><td>餐厅</td><td>名称、时间、人数</td></tr></tbody></table><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/bbcfa5c75a834637a4f767d5b75cb67620260430141546710.png" alt="" /></p></section><section><h3>预算追踪<a href="#预算追踪"><span>#</span></a></h3><p>设置旅行预算，实时追踪支出：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 预算设置流程</span></div></div><div><div><div>2</div></div><div><span>设置总预算 → 分类添加支出 → 查看饼图统计 → 多人分摊计算</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>支持多币种和按人/按天拆分，帮你管好旅行经费。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/3387430be19243c4850c945232f8511a20260430141617922.png" alt="" /></p></section><section><h3>打包清单<a href="#打包清单"><span>#</span></a></h3><p>创建打包清单，确保出行前万事俱备：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 打包清单示例</span></div></div><div><div><div>2</div></div><div><span>衣物: 上衣×3, 裤子×2, 外套×1</span></div></div><div><div><div>3</div></div><div><span>洗漱用品: 牙刷, 牙膏, 毛巾</span></div></div><div><div><div>4</div></div><div><span>电子产品: 手机, 充电器, 相机</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>支持模板、成员分配和进度追踪。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/69dc3444a0f643e39b9188903bf506a220260430141649851.png" alt="" /></p></section><section><h3>团队协作<a href="#团队协作"><span>#</span></a></h3><p>和朋友一起规划行程：</p><ol>
<li>发送邀请链接</li>
<li>实时看到对方的修改</li>
<li>群聊讨论行程细节</li>
<li>投票决定去哪玩</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/998ea41f5e6d4913b7b9cd2cb7ff286620260430141708639.png" alt="" /></p></section></section>
<section><h2>项目资源<a href="#项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>: <a href="https://github.com/mauriceboe/TREK" target="_blank">https://github.com/mauriceboe/TREK</a>
<strong>体验地址</strong>: <a href="https://demo-nomad.pakulat.org/" target="_blank">https://demo-nomad.pakulat.org/</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p><p><strong>项目特色</strong>: 自托管的旅行规划工具，支持实时协作、交互式地图、预算管理、打包清单、PWA 离线使用，适合家庭旅行和团队出游。</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>五一假期就要来了，你是不是已经跃跃欲试了？赶紧用 TREK 规划你的完美假期吧！</p><p>如果你用了之后有什么有趣的体验，或者有什么旅行规划的好建议，欢迎在评论区和我交流。我会定期分享更多好用的工具和旅行攻略，记得关注我哦！祝大家五一假期玩得开心！🎉</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/cloud-mail-deploy/</id>
      <title type="text">GitHub热门项目！Cloud Mail，用Cloudflare免费搭建个人邮件服务</title>
      <published>2026-04-29T00:00:00.000Z</published>
      <updated>2026-04-29T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/cloud-mail-deploy/"/>
      <summary type="text">手把手教你用Cloudflare Workers部署Cloud Mail，零成本搭建个人邮件服务</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>嘿，小伙伴们！最近是不是经常遇到这样的困扰：想拥有一个专属的个人邮箱服务，但是传统的邮箱方案要么太贵，要么配置太复杂？作为一个爱折腾的开发者，我太懂这种感受了！曾经为了搭建一个简单的邮件服务，我研究了各种方案，最后要么因为成本太高放弃，要么因为配置繁琐半途而废。</p><p>直到最近发现了一个宝藏项目——<strong>Cloud Mail</strong>！这是一个专门为 Cloudflare Workers 设计的轻量级邮件服务，让我们可以用几乎零成本搭建自己的邮件系统。不用买服务器，不用配置复杂的环境，只要一个域名和 Cloudflare 账号，就能拥有属于自己的邮件服务。</p><p>这两天这个项目在开发者圈子里特别火，今天我就来手把手教大家怎么用 Cloudflare 部署这个项目，体验一下免费搭建邮件服务的快乐！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/4712a2d1145e4e1a9dd9f87cadf2aca720260429091940109.png" alt="" /></p></section>
<section><h2>项目介绍<a href="#项目介绍"><span>#</span></a></h2><section><h3>✨ 核心特性<a href="#-核心特性"><span>#</span></a></h3><ul>
<li><strong>🚀 零成本部署</strong>: 基于 Cloudflare Workers，免费额度完全够用，个人使用几乎零成本</li>
<li><strong>🎯 多域名支持</strong>: 支持多个域名创建不同的邮箱地址，一套系统满足多种需求</li>
<li><strong>💰 无限邮箱</strong>: 理论上可以创建无限个邮箱账号，告别邮箱数量限制</li>
<li><strong>🔧 简单配置</strong>: 通过环境变量和 Web 界面即可完成配置，无需复杂命令</li>
<li><strong>📦 开源免费</strong>: 完全开源，代码透明，社区活跃，更新频繁</li>
</ul></section><section><h3>🎯 应用场景<a href="#-应用场景"><span>#</span></a></h3><ul>
<li><strong>个人邮箱</strong>: 搭建专属的个人邮箱服务，告别商业邮箱的广告和限制</li>
<li><strong>团队协作</strong>: 为小团队创建统一的邮箱系统，提升专业形象</li>
<li><strong>项目邮箱</strong>: 为开源项目或个人项目创建专门的联系邮箱</li>
<li><strong>隐私保护</strong>: 避免使用第三方邮箱泄露个人信息</li>
</ul></section></section>
<section><h2>部署实战<a href="#部署实战"><span>#</span></a></h2><section><h3>环境准备<a href="#环境准备"><span>#</span></a></h3><p>首先，我们需要准备一个 Cloudflare 账号和一个已经接入 Cloudflare 的域名。如果你还没有域名，可以在 Cloudflare Registrar 购买一个，非常便宜。</p><p>登录 Cloudflare 后台，确认你的域名已经正确接入：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/843b848a7fbc462593367e68c04231d020260429092016663.png" alt="" /></p></section><section><h3>项目下载<a href="#项目下载"><span>#</span></a></h3><p>首先，咱们去 GitHub 把项目克隆到自己的账号：
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/003de8ecb381491b9cb78e52bef1b77d20260429092204269.png" alt="" /></p></section><section><h3>创建 Worker 项目<a href="#创建-worker-项目"><span>#</span></a></h3><p>现在我们来创建 Cloudflare Worker 项目：</p><ol>
<li>登录 Cloudflare 控制台，进入 <strong>Workers &amp; Pages</strong>
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/8f5019c35ab142b78966c6bc623516b120260429092249038.png" alt="" /></li>
<li>点击 <strong>创建应用</strong> → <strong>Pages</strong> → <strong>连接到 Git</strong>
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/610a777273ae4c97a0917e30529a049620260429092302043.png" alt="" /></li>
<li>选择刚才 fork 的仓库,并设置目录为 <code>mail-worker</code>
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/a5d0561b0d6c472c938a550895dae8dc20260429092322197.png" alt="" /></li>
</ol></section><section><h3>设置环境变量<a href="#设置环境变量"><span>#</span></a></h3><p>部署成功后，进入项目设置页面，添加以下环境变量：</p>

<table><thead><tr><th>变量名</th><th>必填</th><th>用途</th><th>示例</th></tr></thead><tbody><tr><td><code>domain</code></td><td>✅</td><td>邮箱域名，多个域名用数组</td><td><code>["example.com"]</code></td></tr><tr><td><code>admin</code></td><td>✅</td><td>管理员邮箱地址</td><td><code>admin@example.com</code></td></tr><tr><td><code>jwt_secret</code></td><td>✅</td><td>JWT 密钥，随机字符串</td><td><code>your-secret-key-123</code></td></tr><tr><td><code>project_link</code></td><td>❌</td><td>是否显示项目链接</td><td><code>true</code> 或 <code>false</code></td></tr></tbody></table><p>添加环境变量的界面：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/2fac6a2a2f8b40f89c47128da09b181e20260429092428164.png" alt="" /></p></section><section><h3>绑定数据库<a href="#绑定数据库"><span>#</span></a></h3><p>接下来需要创建并绑定数据库：</p><section><h4>创建 KV 命名空间<a href="#创建-kv-命名空间"><span>#</span></a></h4><ol>
<li>进入 <strong>Workers &amp; Pages</strong> → <strong>KV</strong> → <strong>创建命名空间</strong></li>
<li>命名为 <code>cloud-mail-kv</code>
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/629d3cd118ea4f6daf5b66011f9accbe20260429092453281.png" alt="" /></li>
</ol></section><section><h4>创建 D1 数据库<a href="#创建-d1-数据库"><span>#</span></a></h4><ol>
<li>进入 <strong>Workers &amp; Pages</strong> → <strong>D1</strong> → <strong>创建数据库</strong></li>
<li>命名为 <code>cloud-mail-db</code>
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/1d3239843a4f45399d3f3e43ee68d76f20260429092650196.png" alt="" /></li>
</ol></section><section><h4>绑定到 Worker<a href="#绑定到-worker"><span>#</span></a></h4><ol>
<li>进入项目设置 → <strong>环境变量</strong> → <strong>绑定</strong></li>
<li>添加 KV 绑定：
<ul>
<li>变量名：<code>kv</code>（必须是这个名字）</li>
<li>选择刚才创建的 KV 命名空间</li>
</ul>
</li>
<li>添加 D1 绑定：
<ul>
<li>变量名：<code>db</code>（必须是这个名字）</li>
<li>选择刚才创建的 D1 数据库</li>
</ul>
</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/72406612bc054babb312b48dfec7edc020260429092705825.png" alt="" /></p></section></section><section><h3>设置自定义域名<a href="#设置自定义域名"><span>#</span></a></h3><p>为了让邮箱服务可以通过自定义域名访问，我们需要添加自定义域名：</p><ol>
<li>进入项目设置 → <strong>自定义域</strong> → <strong>添加自定义域</strong></li>
<li>输入你的域名，比如 <code>mail.example.com</code></li>
<li>按照提示添加 DNS 记录</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/9e7ed8e4dcf9415082d66b2f6e9c1ad120260429092808562.png" alt="" /></p></section><section><h3>设置转发<a href="#设置转发"><span>#</span></a></h3><ol>
<li>进入域管理
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/4d279022c3c84ab0a67d594f0d2c40fb20260429092937086.png" alt="" /></li>
<li>设置电子邮件路由
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/d64661b81c30473293e1ff2be407696520260429093155809.png" alt="" />
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/b0f743bb3e254253843d348ada8b5ff520260429093247092.png" alt="" /></li>
</ol></section><section><h3>初始化数据库<a href="#初始化数据库"><span>#</span></a></h3><p>现在我们需要初始化数据库，在浏览器中访问：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://你的自定义域名/api/init/你的jwt_secret</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>替换成你自己的域名和 jwt_secret，访问后会看到成功提示：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/f9cd0ca7977743e99d2f5c9bb3b4b22820260429093305746.png" alt="" /></p></section><section><h3>注册管理员账号<a href="#注册管理员账号"><span>#</span></a></h3><p>打开浏览器访问你的自定义域名，会看到注册页面：</p><ol>
<li>输入管理员邮箱（必须和环境变量中的 admin 一致）</li>
<li>设置密码</li>
<li>点击注册</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/33fe7ac2188b4c3aa5a19ae13f6ebcc320260429093330718.png" alt="" /></p></section><section><h3>登录系统<a href="#登录系统"><span>#</span></a></h3><p>注册成功后，使用管理员账号登录：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/a331a672063a46439ee17fe167419d8e20260429093352772.png" alt="" /></p></section><section><h3>添加邮箱用户<a href="#添加邮箱用户"><span>#</span></a></h3><p>登录后，可以在管理界面添加邮箱用户：</p><ol>
<li>点击左侧菜单的 <strong>用户管理</strong></li>
<li>点击 <strong>添加用户</strong></li>
<li>输入邮箱地址和密码（密码可不填，会自动生成）</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/10316a0dc0eb4db5b05b1410ee11674020260429093440745.png" alt="" /></p></section><section><h3>测试发送邮件<a href="#测试发送邮件"><span>#</span></a></h3><p>添加用户后，我们可以测试发送邮件功能：</p><ol>
<li>登录用户邮箱</li>
<li>点击 <strong>写邮件</strong></li>
<li>输入收件人、主题和内容</li>
<li>点击发送</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/d5f99934e0574e60badfa64a9edb4c1a20260429093459720.png" alt="" /></p></section></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>今天主要带大家了解并实现了 Cloud Mail 的完整部署流程，该邮件服务以 “Cloudflare Workers + Hono” 为核心优势，结合个人邮箱需求，通过 Cloudflare 平台与 D1/KV 数据库，形成了一套从域名准备到邮件收发的全链路解决方案。通过这套实践方案，个人开发者能够高效突破传统邮箱服务的成本瓶颈——借助环境配置、数据库绑定、自定义域设置等操作（包括创建 Worker、配置环境变量、绑定 KV/D1、初始化数据库、注册账号），无需购买服务器或配置复杂环境，就能快速搭建专属邮件服务（如本次演示的 “个人邮箱系统”）。无论是多域名支持、无限邮箱创建，还是邮件收发、用户管理，都能通过简单的 Web 界面完成，极大降低了个人邮件服务的搭建门槛。在实际应用中，该服务不仅零成本运行，还具备良好的扩展性，适配性远优于传统的自建邮件服务器方案；特别是通过 Cloudflare 的全球 CDN 加速，有效解决了邮件传输延迟的难题。同时，方案具备良好的扩展性——小伙伴们可以基于此扩展更多应用场景，如团队协作邮箱、项目联系邮箱、隐私保护邮箱等，进一步发挥 Cloud Mail 在个人服务、团队协作、开源项目等领域的应用价值。感兴趣的小伙伴可以按照文中提供的步骤进行实践，根据实际需求类型调整域名配置和用户权限。今天的分享就到这里结束了，我们下一篇文章见。</p></section>
<section><h2>项目资源<a href="#项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>: <a href="https://github.com/maillab/cloud-mail" target="_blank">https://github.com/maillab/cloud-mail</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p><p><strong>项目特色</strong>: 基于 Cloudflare Workers 的轻量级邮件服务，支持多域名、无限邮箱账号，零成本搭建个人邮件系统。</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你是不是已经跃跃欲试了？赶紧去 GitHub fork 这个项目，试试用 Cloudflare 免费搭建自己的邮件服务吧！</p><p>如果你在部署过程中遇到什么问题，或者有什么有趣的体验，欢迎在评论区和我交流。我会定期分享更多好用的开发工具和技术教程，记得关注我哦！</p><p>（注：文章部分信息来源于 cloud-mail 官网）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/localsqueeze-tutorial/</id>
      <title type="text">GitHub宝藏项目！LocalSqueeze，让图片压缩既安全又高效</title>
      <published>2026-04-29T00:00:00.000Z</published>
      <updated>2026-04-29T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/localsqueeze-tutorial/"/>
      <summary type="text">一款完全在本地运行的图片压缩工具，安全快速，质量超高</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>嘿，小伙伴们！最近是不是经常遇到这样的困扰：想压缩图片但又担心隐私泄露？用在线工具吧，怕图片上传到服务器被窃取；用付费软件吧，又觉得不值当。作为一个经常需要处理图片的开发者，我太懂这种感受了！曾经为了压缩一张图片，我试遍了各种在线工具，每次上传都提心吊胆的，总担心图片里的敏感信息被泄露。</p><p>直到最近发现了一个宝藏项目——<strong>LocalSqueeze</strong>！这是一款完全在本地运行的图片压缩工具，所有操作都在你的电脑上完成，零数据泄露风险。压缩效果还超级棒，实测比 TinyPNG 压缩得更小，质量还没差异。</p><p>这两天这个项目在开发者圈子里特别火，今天我就来和大家唠唠这个神奇的工具，看看它是怎么让图片压缩变得既安全又高效的。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/8cc2b498d4d347d591894ac1f1b4502a20260429110544806.png" alt="" /></p></section>
<section><h2>项目介绍<a href="#项目介绍"><span>#</span></a></h2><section><h3>✨ 核心特性<a href="#-核心特性"><span>#</span></a></h3><ul>
<li><strong>🔐 安全至上</strong>: 所有操作均在本地完成，零数据泄露风险，隐私安全有保障</li>
<li><strong>🔍 高质量压缩</strong>: 智能压缩策略，在保持图片质量的同时最大程度减小文件大小</li>
<li><strong>🚀 批量处理</strong>: 同时处理多张图片，大大提高工作效率</li>
<li><strong>🎨 体验优先</strong>: 直观的界面设计，流畅的操作体验，新手也能轻松上手</li>
<li><strong>🔧 灵活配置</strong>: 丰富的压缩参数，满足专业用户的个性化需求</li>
<li><strong>🌍 跨平台</strong>: 支持 Windows、macOS 主流平台，无论用什么系统都能用</li>
<li><strong>👁️ 效果对比</strong>: 直观对比压缩前后的效果，确保图片质量符合预期</li>
<li><strong>🌓 深色模式</strong>: 支持深色/浅色主题切换，保护你的眼睛</li>
</ul></section><section><h3>🆚 与同类产品对比<a href="#-与同类产品对比"><span>#</span></a></h3>

<table><thead><tr><th>特性</th><th>LocalSqueeze</th><th>TinyPNG</th><th>Picdiet</th></tr></thead><tbody><tr><td>隐私安全</td><td>100% 本地处理</td><td>需上传服务器</td><td>需上传服务器</td></tr><tr><td>压缩效果</td><td>更优（104KB vs 175KB）</td><td>一般</td><td>一般</td></tr><tr><td>网络依赖</td><td>无需网络</td><td>需要网络</td><td>需要网络</td></tr><tr><td>费用</td><td>完全免费</td><td>有限免费</td><td>有限免费</td></tr><tr><td>配置选项</td><td>丰富</td><td>简单</td><td>简单</td></tr><tr><td>支持格式</td><td>多种</td><td>仅支持 JPG/PNG</td><td>仅支持 JPG</td></tr></tbody></table></section></section>
<section><h2>实战体验<a href="#实战体验"><span>#</span></a></h2><section><h3>环境准备<a href="#环境准备"><span>#</span></a></h3><p>用这个工具真的超级简单，不需要任何特殊环境，只要你的电脑能运行普通软件就行。支持 Windows 10+ 和 macOS 10.14+，几乎覆盖了所有主流系统。</p></section><section><h3>下载安装<a href="#下载安装"><span>#</span></a></h3><p>首先，咱们去 GitHub 看看这个宝藏仓库：<a href="https://github.com/freeany/LocalSqueeze" target="_blank">https://github.com/freeany/LocalSqueeze</a></p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/99051bd0318b46f8a0442f6c1f11fc1320260429105707585.png" alt="" /></p><p>在 Release 页面下载对应系统的安装包：</p><ul>
<li><strong>Windows 用户</strong>: 下载 <code>.exe</code> 安装文件</li>
<li><strong>macOS 用户</strong>: 下载 <code>.dmg</code> 磁盘镜像
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/6ff99f2a9a3f4c57bfd8034421e7085420260429105738539.png" alt="" /></li>
</ul><p>下载完成后，双击安装包进行安装，一路点击下一步即可。</p></section><section><h3>启动应用<a href="#启动应用"><span>#</span></a></h3><p>安装完成后，在应用列表找到 LocalSqueeze 并启动：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/c467db6859c948eb8e6da8f6b616c20e20260429110122249.png" alt="" /></p><p>界面非常简洁，主要分为几个区域：</p><ul>
<li><strong>顶部工具栏</strong>: 包含压缩级别选择、输出格式选择等</li>
<li><strong>中间预览区</strong>: 显示正在处理的图片</li>
<li><strong>底部状态栏</strong>: 显示压缩进度和结果</li>
</ul></section><section><h3>选择压缩级别<a href="#选择压缩级别"><span>#</span></a></h3><p>LocalSqueeze 提供了多种压缩级别供选择：</p>

<table><thead><tr><th>级别</th><th>压缩率</th><th>质量</th><th>适用场景</th></tr></thead><tbody><tr><td>最低</td><td>约 30%</td><td>最高</td><td>对质量要求极高的场景</td></tr><tr><td>低</td><td>约 50%</td><td>高</td><td>一般图片处理</td></tr><tr><td>中</td><td>约 65%</td><td>中高</td><td>网页图片</td></tr><tr><td>高</td><td>约 80%</td><td>中等</td><td>社交媒体图片</td></tr><tr><td>最高</td><td>约 90%</td><td>较低</td><td>对质量要求不高的场景</td></tr></tbody></table><p>根据你的需求选择合适的压缩级别，默认是 “中” 级别，适合大多数场景。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/b12eb16caa4d457a8d1ffc389aabd09820260429110146261.png" alt="" /></p></section><section><h3>添加图片<a href="#添加图片"><span>#</span></a></h3><p>有两种方式可以添加图片：</p><p><strong>方式一：拖拽添加</strong>
直接将图片或包含图片的文件夹拖拽到应用窗口中：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 拖拽操作</span></div></div><div><div><div>2</div></div><div><span># 从文件夹中选中图片 → 拖拽到 LocalSqueeze 窗口</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式二：点击添加</strong>
点击窗口中的 “添加图片” 按钮，选择要压缩的图片：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 点击操作流程</span></div></div><div><div><div>2</div></div><div><span># 点击「添加图片」→ 选择图片文件 → 确认添加</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/165c942cac1943e981a11198a2d9cf3120260429110228653.png" alt="" /></p></section><section><h3>开始压缩<a href="#开始压缩"><span>#</span></a></h3><p>添加完图片后，点击 “开始压缩” 按钮：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 压缩命令（软件内部执行）</span></div></div><div><div><div>2</div></div><div><span># 点击「开始压缩」→ 等待处理 → 完成</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>压缩过程中会显示进度条和实时状态：</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/753850ab657f4329bb6e84775c6dab8520260429110408980.png" alt="" /></p></section><section><h3>导出压缩后的图片<a href="#导出压缩后的图片"><span>#</span></a></h3><p>点击 “导出全部” 按钮，选择保存位置即可：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 导出操作</span></div></div><div><div><div>2</div></div><div><span># 点击「导出全部」→ 选择保存目录 → 确认导出</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>导出后的图片会自动保存在你选择的目录中，文件名保持不变。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/af78e79de04940c2acc324332e45378c20260429110304690.png" alt="" /></p></section></section>
<section><h2>我的使用感受<a href="#我的使用感受"><span>#</span></a></h2><p>作为一个经常需要处理大量图片的开发者，我必须说这个工具彻底改变了我的工作流程。以前压缩图片，我总是小心翼翼地选择在线工具，每次都要检查图片里有没有敏感信息。现在有了 LocalSqueeze，我再也不用担心了，所有操作都在本地完成，安全感爆棚！</p><p>前几天我用它压缩了一批产品图片，520KB 的图片压缩后只有 104KB，节省了 80% 的空间，而且质量几乎看不出差别。最让我惊喜的是批量处理功能，一次性拖入几十张图片，几分钟就全部搞定了，效率提升了不止十倍！</p></section>
<section><h2>项目资源<a href="#项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>: <a href="https://github.com/freeany/LocalSqueeze" target="_blank">https://github.com/freeany/LocalSqueeze</a></p><p>觉得项目不错的话，记得给作者点个 star 支持一下！</p><p><strong>项目特色</strong>: 完全本地运行的图片压缩工具，安全高效，支持批量处理和效果对比，跨平台支持，完全免费开源。</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你是不是已经跃跃欲试了？赶紧去 GitHub 下载这个神器，试试用它压缩你的图片吧！</p><p>如果你用了之后有什么有趣的体验，或者有什么问题，欢迎在评论区和我交流。我会定期分享更多好用的开发工具，记得关注我哦！</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/sink-deployment-guide/</id>
      <title type="text">无需服务器！使用Cloudflare免费部署Sink短链接工具</title>
      <published>2026-04-27T00:00:00.000Z</published>
      <updated>2026-04-27T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/sink-deployment-guide/"/>
      <summary type="text">一款开源、高效、安全的短链接工具，100%运行在Cloudflare上，支持自定义别名、AI Slug和链接分析</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>嘿,小伙伴们!在日常工作和生活中,你是不是经常遇到需要分享长链接的场景?比如分享一个复杂的URL,不仅看起来冗长难记,而且在某些平台上还可能被自动截断,影响用户体验。这时候,一个好用的短链接工具就显得尤为重要了。</p><p>今天我要给大家介绍一款开源、高效、安全的短链接工具——Sink。它的最大特点是完全运行在Cloudflare上,无需传统服务器,可以免费部署和使用。而且它还支持自定义别名、AI Slug生成、链接分析等强大功能,简直是短链接工具中的佼佼者!</p><p>这两天这个项目在开发者圈子里特别火,今天我就来和大家唠唠如何在Cloudflare上免费部署和使用Sink,让你的链接分享变得更加简洁高效。</p></section>
<section><h2>项目介绍<a href="#项目介绍"><span>#</span></a></h2><section><h3>✨ 核心特性<a href="#-核心特性"><span>#</span></a></h3><ul>
<li><strong>🚀 URL缩短</strong>: 将冗长的网址压缩到最短长度，方便分享和记忆</li>
<li><strong>📊 链接分析</strong>: 监控链接点击数据，收集有洞察力的统计信息</li>
<li><strong>☁️ 无服务器部署</strong>: 完全运行在Cloudflare上，无需传统服务器</li>
<li><strong>🎨 自定义别名</strong>: 支持创建个性化的短链接别名</li>
<li><strong>🤖 AI Slug</strong>: 利用AI自动生成有意义的短链接Slug</li>
<li><strong>⏰ 链接过期</strong>: 为短链接设置过期日期，增强安全性</li>
<li><strong>🔒 安全可靠</strong>: 开源免费，无广告，数据安全可控</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/3856ca128b2d4594b92aa07e3f63851420260427161934162.png" alt="" /></p></section><section><h3>🛠️ 技术栈<a href="#️-技术栈"><span>#</span></a></h3>

<table><thead><tr><th>类别</th><th>技术</th><th>说明</th></tr></thead><tbody><tr><td>前端</td><td>React</td><td>现代化的前端框架，提供流畅的用户界面</td></tr><tr><td>后端</td><td>Cloudflare Workers</td><td>无服务器计算平台，提供高效的后端服务</td></tr><tr><td>存储</td><td>Cloudflare KV</td><td>键值存储服务，用于存储短链接数据</td></tr><tr><td>分析</td><td>Cloudflare Analytics Engine</td><td>提供链接点击分析功能</td></tr><tr><td>部署</td><td>Cloudflare Pages</td><td>静态网站托管服务，用于部署前端应用</td></tr></tbody></table></section><section><h3>🎯 应用场景<a href="#-应用场景"><span>#</span></a></h3><ul>
<li><strong>社交媒体分享</strong>: 缩短长链接，提升分享体验</li>
<li><strong>营销活动</strong>: 追踪链接点击数据，分析用户行为</li>
<li><strong>企业内部</strong>: 统一管理内部链接，方便员工访问</li>
<li><strong>个人使用</strong>: 整理和管理个人常用链接</li>
</ul></section></section>
<section><h2>部署教程<a href="#部署教程"><span>#</span></a></h2><section><h3>环境准备<a href="#环境准备"><span>#</span></a></h3><p>部署Sink只需要一个Cloudflare账号，不需要任何服务器或其他基础设施。如果还没有Cloudflare账号，可以免费注册一个。</p></section><section><h3>步骤1: Fork Sink项目<a href="#步骤1-fork-sink项目"><span>#</span></a></h3><ol>
<li>访问<a href="https://github.com/miantiao-me/Sink" target="_blank">Sink项目的GitHub页面</a></li>
<li>点击页面右上角的”Fork”按钮
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/8ed98e8df7884af1907c9683e8c642d020260427141044262.png" alt="" /></li>
<li>在弹出的对话框中，选择你要将项目fork到的GitHub账户
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/e9b0157a25694f4b864c874849d02f7c20260427141341928.png" alt="" /></li>
<li>等待fork完成，你会被重定向到你自己账户下的Sink项目页面
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/c41eaa6cacbf4a1f89f6fb6faa96fe8620260427141151173.png" alt="" /></li>
</ol></section><section><h3>步骤2: 登录Cloudflare账号<a href="#步骤2-登录cloudflare账号"><span>#</span></a></h3><p>访问<a href="https://www.cloudflare.com/" target="_blank">Cloudflare官网</a>并登录你的账号。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/b1703fd8bb4440eea0169830a0cba59820260427141421725.png" alt="" /></p></section><section><h3>步骤3: 创建KV命名空间<a href="#步骤3-创建kv命名空间"><span>#</span></a></h3><ol>
<li>在Cloudflare控制台中，点击左侧菜单的”存储和数据库”，点击“workers KV”
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/bf1a1e64566c4ff780fa1154ba47aa9c20260427142957177.png" alt="" /></li>
<li>点击右上角的“Create Instance”，创建一个新的KV命名空间
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/ee870a1c15c549f494011f891ca35a9b20260427143109431.png" alt="" /></li>
<li>点击”创建命名空间”按钮</li>
<li>输入命名空间名称为”sink”，然后点击”创建”</li>
</ol></section><section><h3>步骤4: 创建Pages项目<a href="#步骤4-创建pages项目"><span>#</span></a></h3><ol>
<li>回到”Workers &amp; Pages”页面</li>
<li>点击”想要部署 Pages？开始使用”
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/794fc941df724e4abfd7c2417068109120260427150046299.png" alt="" /></li>
<li>点击”导入现有 Git 存储库-开始使用”按钮
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/66de510a807b4438ae9639fac901077520260427150132626.png" alt="" /></li>
<li>选择”连接到Git”</li>
<li>选择你的Git提供商（GitHub、GitLab或Bitbucket）</li>
<li>授权Cloudflare访问你的Git账户</li>
<li>在仓库列表中找到并选择你自己账户下的”Sink”仓库（不是miantiao-me/Sink）
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/34d75a383d6f471ab3c9ae14b3ee919f20260427150221283.png" alt="" /></li>
<li>配置环境变量
<ul>
<li>NUXT_SITE_TOKEN： 必须至少8个字符。此令牌授予访问仪表盘的权限。</li>
<li>NUXT_CF_ACCOUNT_ID：找到你的账户ID。（域名—&gt;概览—&gt;点击你的域名）
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/4adb0552105f4704ad233fc7bcfbe45220260427144006560.png" alt="" />
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/f8bed3b2cee742c98050081f67925b7920260427143910161.png" alt="" /></li>
<li>NUXT_CF_API_TOKEN： 创建一个至少获得权限的 Cloudflare API 令牌。（点击创建令牌 → 创建自定义令牌 → 自己取个名称，权限这里要选择 账户/账户分析/读取 。）
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/7dfff75770ce4068b147753594f8c2d720260427144204037.png" alt="" />
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/8fe612d26fc84d89a49bba73cb84733220260427144422012.png" alt="" /></li>
</ul>
</li>
<li>点击”保存并部署”
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/cf25050e644b4edca559da0a4c8c8e5820260427150435296.png" alt="" /></li>
</ol></section><section><h3>步骤5: 部署项目<a href="#步骤5-部署项目"><span>#</span></a></h3><ol>
<li>点击”保存并部署”按钮</li>
<li>等待部署完成，这可能需要几分钟时间，部署可能会失败，报下面这个错误</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>15:14:23.224  Success: Assets published!</span></div></div><div><div><div>2</div></div><div><span>15:14:24.029  Error: Failed to publish your Function. Got error: Uncaught Error: No such module "node:buffer".</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>imported from "bundledWorker-0.2566199779193783.mjs"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>设置下node兼容性标志，然后重新部署，就不会报错了
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/f3c05c53ecd44dd891b47ae29b9bf04d20260427155739867.png" alt="" /></li>
<li>首次部署成功后,你会看到部署成功的消息和临时域名,这个时候还需要设置下KV，你需要进入项目的 “Settings” 页面，导航至 “Functions” -&gt; “Bindings“，在设置中绑定选择kv命名空间，找到我们刚才创建好的kv命名空间，变量名称选择KV（必须是大写的KV）
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/b8dd533add3045d589bb0eb7f91b8bca20260427155933330.png" alt="" /></li>
<li>重新部署项目,这一次，部署将包含你新配置的绑定和标志。</li>
</ol></section><section><h3>步骤6: 配置自定义域名<a href="#步骤6-配置自定义域名"><span>#</span></a></h3><ol>
<li>在Pages项目页面，点击”自定义域”</li>
<li>点击”添加自定义域”</li>
<li>输入你想要使用的域名，然后点击”继续”</li>
<li>按照提示在你的域名注册商处添加DNS记录</li>
<li>等待DNS记录生效，通常需要几分钟到几小时</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/4756c815ca8445718b7c98569487238420260427160259246.png" alt="" /></p></section></section>
<section><h2>使用指南<a href="#使用指南"><span>#</span></a></h2><section><h3>生成短链接<a href="#生成短链接"><span>#</span></a></h3><ol>
<li><strong>访问Sink管理界面</strong>：打开你部署的Sink网站</li>
<li><strong>输入长链接</strong>：在输入框中粘贴你想要缩短的长链接</li>
<li><strong>自定义别名（可选）</strong>：在”Custom Slug”字段中输入你想要的自定义别名</li>
<li><strong>设置过期时间（可选）</strong>：选择链接的过期日期</li>
<li><strong>点击生成</strong>：点击”Generate”按钮生成短链接</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/61f51924376f42b2b79241d3296ab48820260427161738665.png" alt="" /></p></section><section><h3>管理短链接<a href="#管理短链接"><span>#</span></a></h3><ol>
<li><strong>访问管理页面</strong>：在Sink管理界面中，点击”Links”选项</li>
<li><strong>编辑短链接</strong>：可以修改短链接的目标URL、过期时间等信息</li>
<li><strong>删除短链接</strong>：可以删除不再需要的短链接</li>
<li><strong>搜索短链接</strong>：可以通过关键词搜索已创建的短链接</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/7f76b2dc871141d1af75f597b0e4889520260427161539114.png" alt="" /></p></section></section>
<section><h2>我的使用感受<a href="#我的使用感受"><span>#</span></a></h2><p>作为一个经常需要分享链接的内容创作者,我必须说Sink彻底改变了我的链接分享方式。以前我使用其他短链接服务时,要么功能有限,要么需要付费,要么担心数据安全。现在有了Sink,不仅所有功能都免费,而且完全掌控在自己手中,让我使用得更加安心。</p><p>还有它的链接分析功能,让我可以清晰地看到每个链接的点击情况,这对于我分析内容效果非常有帮助。而且所有这些功能都运行在Cloudflare上,无需自己维护服务器,节省了大量的时间和精力。</p><p>前几天我用它为我的公众号文章生成了几个短链接,不仅看起来简洁美观,而且点击数据一目了然。哈哈,现在我已经彻底离不开它了!</p></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>今天和大家分享了Sink这个宝藏项目,它是一款开源、高效、安全的短链接工具,完全运行在Cloudflare上,无需传统服务器。通过简单的部署步骤,我们可以拥有一个功能强大的短链接服务,支持自定义别名、AI Slug生成、链接分析等功能。</p><p>与其他短链接服务相比,Sink最大的优势在于它的免费性和可控性。我们可以完全掌控自己的数据,而且不需要支付任何费用。无论是个人使用还是企业应用,Sink都能为我们提供稳定、高效的短链接服务。</p><p>最重要的是,作为一个开源项目,它欢迎社区贡献,这意味着它会不断进化和改进,未来会变得更加优秀。如果你正在寻找一款可靠的短链接工具,那么Sink绝对值得一试!</p></section>
<section><h2>项目资源<a href="#项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>: <a href="https://github.com/miantiao-me/Sink" target="_blank">https://github.com/miantiao-me/Sink</a>
<strong>demo</strong>: <a href="https://sink.cool/" target="_blank">https://sink.cool/</a></p><p>觉得项目不错的话,记得给作者点个star支持一下!</p><p><strong>项目特色</strong>: 开源免费的短链接工具,支持URL缩短、自定义别名、AI Slug生成、链接分析等功能,完全运行在Cloudflare上,无需传统服务器。</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你是不是已经跃跃欲试了?赶紧按照文中的步骤部署一个属于自己的Sink短链接服务吧!</p><p>如果你在部署或使用过程中遇到任何问题,或者有什么有趣的使用体验,欢迎在评论区和我交流。我会定期分享更多好用的工具和教程,记得关注我哦!</p><p>今天的分享就到这里结束了,我们下一篇文章见。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/ztools-introduction/</id>
      <title type="text">GitHub宝藏项目！ZTools，开源免费的效率工具神器</title>
      <published>2026-04-24T00:00:00.000Z</published>
      <updated>2026-04-24T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/ztools-introduction/"/>
      <summary type="text">一款开源免费的跨平台应用启动器和插件平台，是uTools的完美替代品</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>嘿,小伙伴们!作为一个每天都要和电脑打交道的打工人,你是不是经常为找应用、管理剪贴板、处理文件这些琐碎的事情感到头疼?尤其是当你需要在多个窗口之间来回切换,或者频繁重复一些操作时,是不是特别希望有个工具能帮你搞定这些?</p><p>说到效率工具,大家可能首先想到的是uTools,这款工具确实好用,但它的一些限制和收费策略也让不少用户望而却步。不过别担心,今天我要给大家介绍一个宝藏项目——ZTools,它不仅功能强大,而且完全开源免费,简直是效率工具界的一股清流!</p><p>这两天这个项目在开发者圈子里特别火,今天我就来和大家唠唠这个神奇的工具,看看它是怎么让我们的工作效率飙升的,以及为什么它比uTools更值得推荐。</p></section>
<section><h2>项目介绍<a href="#项目介绍"><span>#</span></a></h2><section><h3>✨ 核心特性<a href="#-核心特性"><span>#</span></a></h3><ul>
<li><strong>🚀 快速启动</strong>: 支持拼音搜索、正则匹配、历史记录追踪、常用应用固定，通过快捷键（macOS为Option+Z，Windows为Alt+Z）快速唤起，无需手动查找应用</li>
<li><strong>🧩 插件系统</strong>: 支持UI插件和无界面插件，搭配完整API支持，既能实现可视化交互功能，也能完成后台数据处理、自动化任务</li>
<li><strong>📋 剪贴板管理</strong>: 历史记录追踪、搜索功能、图片支持，跨平台原生实现，让你再也不用担心复制内容丢失</li>
<li><strong>🎨 主题定制</strong>: 支持系统/浅色/深色主题，可自定义界面风格，满足不同用户的审美需求</li>
<li><strong>🔒 安全可靠</strong>: 开源免费，无广告，无隐私收集，让你使用得安心</li>
<li><strong>🌐 跨平台支持</strong>: 同时支持Windows和macOS，保持一致的使用体验,最新版还支持了linux</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/a66dd29bae884c5eb25e056bfb5f4c79demo.gif" alt="" /></p></section><section><h3>🛠️ 技术栈<a href="#️-技术栈"><span>#</span></a></h3>

<table><thead><tr><th>类别</th><th>技术</th><th>说明</th></tr></thead><tbody><tr><td>前端</td><td>React</td><td>现代化的前端框架，提供流畅的用户界面</td></tr><tr><td>后端</td><td>Node.js</td><td>高效的服务器端运行环境</td></tr><tr><td>构建工具</td><td>Vite</td><td>快速的前端构建工具</td></tr><tr><td>跨平台</td><td>Electron</td><td>实现跨平台桌面应用</td></tr></tbody></table></section><section><h3>🎯 应用场景<a href="#-应用场景"><span>#</span></a></h3><ul>
<li><strong>日常办公</strong>: 快速启动应用、管理剪贴板、批量处理文件</li>
<li><strong>开发工作</strong>: 代码片段管理、API测试、快速搜索文档</li>
<li><strong>设计工作</strong>: 颜色取色、图片处理、屏幕截图</li>
<li><strong>生活助手</strong>: 天气查询、单位转换、翻译工具</li>
</ul></section></section>
<section><h2>实战体验<a href="#实战体验"><span>#</span></a></h2><section><h3>环境准备<a href="#环境准备"><span>#</span></a></h3><p>用ZTools真的超级简单,不需要任何特殊环境,只要你的电脑是Windows或macOS系统就行。</p></section><section><h3>项目下载<a href="#项目下载"><span>#</span></a></h3><p>首先,咱们去GitHub看看这个宝藏仓库:</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 克隆仓库</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/ZToolsCenter/ZTools.git</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 或者直接下载发布版本</span></div></div><div><div><div>5</div></div><div><span># 访问 https://github.com/ZToolsCenter/ZTools/releases</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/f4ff2aceeb3e498294ddeec22f6dc1bd20260424151535620.png" alt="" /></p></section><section><h3>安装与配置<a href="#安装与配置"><span>#</span></a></h3><ol>
<li><strong>下载安装包</strong>: 访问GitHub releases页面，下载对应系统的安装包</li>
<li><strong>安装应用</strong>: 双击安装包，按照提示完成安装</li>
<li><strong>启动应用</strong>: 安装完成后，使用快捷键Alt+Z（Windows）或Option+Z（macOS）唤起ZTools</li>
<li><strong>基本设置</strong>: 首次启动时，会引导你进行基本设置，包括主题选择、快捷键设置等</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/83aec0e7fbe342bd9f68d14e9716d9f320260424151828054.png" alt="" /></p></section><section><h3>使用体验<a href="#使用体验"><span>#</span></a></h3><section><h4>快速启动应用<a href="#快速启动应用"><span>#</span></a></h4><p>按下快捷键Alt+Z，输入应用名称的拼音或部分文字，ZTools会智能匹配并显示结果，按回车即可启动应用。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/b734d3e77a3a4e4f9b68481de57537ae20260424152026809.png" alt="" /></p></section><section><h4>插件使用<a href="#插件使用"><span>#</span></a></h4><p>ZTools内置了丰富的插件，包括文件重命名、垃圾清理、图片处理等。你还可以在插件市场中下载更多插件。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/e32c07bab2834f2bb8f1a7d12e88628320260424152216475.png" alt="" /></p></section><section><h4>主题定制<a href="#主题定制"><span>#</span></a></h4><p>ZTools支持多种主题，你可以根据自己的喜好选择系统、浅色或深色主题。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/14325958cb1c48318c0940690c72bb2620260424152252237.png" alt="" /></p></section></section></section>
<section><h2>ZTools vs uTools 对比<a href="#ztools-vs-utools-对比"><span>#</span></a></h2>

<table><thead><tr><th>特性</th><th>ZTools</th><th>uTools</th></tr></thead><tbody><tr><td>开源状态</td><td>完全开源</td><td>闭源</td></tr><tr><td>价格</td><td>免费</td><td>部分功能收费</td></tr><tr><td>广告</td><td>无</td><td>无</td></tr><tr><td>插件系统</td><td>支持，API完整</td><td>支持，API完整</td></tr><tr><td>跨平台</td><td>Windows/macOS</td><td>Windows/macOS</td></tr><tr><td>剪贴板管理</td><td>原生实现，功能丰富</td><td>功能丰富</td></tr><tr><td>主题定制</td><td>支持多主题</td><td>支持多主题</td></tr><tr><td>隐私保护</td><td>开源透明</td><td>闭源，存在隐私顾虑</td></tr></tbody></table></section>
<section><h2>我的使用感受<a href="#我的使用感受"><span>#</span></a></h2><p>作为一个效率工具爱好者,我必须说ZTools彻底改变了我的工作方式。以前我使用uTools时,虽然功能不错,但总感觉有些限制,尤其是一些高级功能需要付费才能使用。现在有了ZTools,不仅所有功能都免费,而且开源透明,让我使用得更加安心。</p><p>最让我惊喜的是它的剪贴板管理功能,以前我经常因为复制了新内容而丢失之前的内容,现在有了ZTools,所有复制过的内容都能轻松找到。还有它的快速启动功能,让我再也不用在桌面和开始菜单中找应用了,按下Alt+Z,输入几个字母就能启动想要的应用,简直不要太方便!</p><p>前几天我用它的批量重命名功能处理了几百个文件,几分钟就搞定了,要是以前手动重命名,估计得花上大半天时间。哈哈,现在我已经彻底离不开它了!</p></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>今天和大家分享了ZTools这个宝藏项目,它是一款开源免费的跨平台应用启动器和插件平台,完美解决了我们日常工作中的效率问题。通过简单的快捷键操作,我们可以快速启动应用、管理剪贴板、处理文件等,极大地提升了工作效率。</p><p>与uTools相比,ZTools最大的优势在于它完全开源免费,没有任何功能限制,同时保持了与uTools相当的功能体验。无论是日常办公、开发工作还是设计工作,ZTools都能为你提供强大的支持。</p><p>最重要的是,作为一个开源项目,它欢迎社区贡献,这意味着它会不断进化和改进,未来会变得更加优秀。如果你正在寻找一款高效、免费、可靠的效率工具,那么ZTools绝对值得一试!</p></section>
<section><h2>项目资源<a href="#项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>: <a href="https://github.com/ZToolsCenter/ZTools" target="_blank">https://github.com/ZToolsCenter/ZTools</a></p><p>觉得项目不错的话,记得给作者点个star支持一下!</p><p><strong>项目特色</strong>: 开源免费的跨平台应用启动器和插件平台,支持快速启动、剪贴板管理、插件扩展等功能,是uTools的完美替代品。</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你是不是已经跃跃欲试了?赶紧去GitHub下载ZTools,体验一下这个神奇的效率工具吧!</p><p>如果你用了之后有什么有趣的体验,或者有什么问题,欢迎在评论区和我交流。我会定期分享更多好用的开发工具和效率技巧,记得关注我哦!</p><p>今天的分享就到这里结束了,我们下一篇文章见。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/umami-vercel-supabase-deployment/</id>
      <title type="text">Umami 自托管部署完整指南：Vercel + Supabase 免费方案</title>
      <published>2026-04-22T20:31:13.000Z</published>
      <updated>2026-04-22T20:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/tools/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/umami-vercel-supabase-deployment/"/>
      <summary type="text">**Umami** 是一个开源、轻量、隐私友好的网站分析工具，相比 Google Analytics，它更注重用户隐私，数据完全由自己掌控，而且界面简洁美观，功能实用。</summary>
      <content type="html"><![CDATA[<section><h2>什么是 Umami？<a href="#什么是-umami"><span>#</span></a></h2><p><strong>Umami</strong> 是一个开源、轻量、隐私友好的网站分析工具，相比 Google Analytics，它更注重用户隐私，数据完全由自己掌控，而且界面简洁美观，功能实用。</p></section>
<section><h2>为什么选择 Vercel + Supabase？<a href="#为什么选择-vercel--supabase"><span>#</span></a></h2><ul>
<li><strong>Vercel</strong>：提供免费的静态网站托管服务，部署简单，全球 CDN，访问速度快</li>
<li><strong>Supabase</strong>：提供免费的 PostgreSQL 数据库服务，适合小型应用，操作简单</li>
<li><strong>完全免费</strong>：两者的免费额度足够个人和小型网站使用</li>
<li><strong>无需服务器</strong>：不需要购买和维护服务器，节省成本和精力</li>
</ul></section>
<section><h2>准备工作<a href="#准备工作"><span>#</span></a></h2><section><h3>1. 注册账号<a href="#1-注册账号"><span>#</span></a></h3><ul>
<li><strong>GitHub 账号</strong>：用于代码托管和 Vercel 登录</li>
<li><strong>Vercel 账号</strong>：用于部署 Umami</li>
<li><strong>Supabase 账号</strong>：用于提供 PostgreSQL 数据库</li>
</ul></section><section><h3>2. 技术要求<a href="#2-技术要求"><span>#</span></a></h3><ul>
<li>基本的 Git 操作知识</li>
<li>基本的数据库操作知识</li>
<li>能够访问 GitHub、Vercel 和 Supabase 网站</li>
</ul></section></section>
<section><h2>步骤一：创建 Supabase 项目<a href="#步骤一创建-supabase-项目"><span>#</span></a></h2><section><h3>1. 登录 Supabase<a href="#1-登录-supabase"><span>#</span></a></h3><p>访问 <a href="https://supabase.com/dashboard" target="_blank">Supabase 控制台</a>，使用 GitHub 账号登录。</p></section><section><h3>2. 创建新项目<a href="#2-创建新项目"><span>#</span></a></h3><ol>
<li>点击「New Project」按钮</li>
<li>填写项目信息：
<ul>
<li><strong>Project Name</strong>：填写项目名称，比如 <code>umami-db</code></li>
<li><strong>Database Password</strong>：设置一个安全的数据库密码（记住这个密码，后面会用到）</li>
<li><strong>Region</strong>：选择离你最近的区域</li>
</ul>
</li>
<li>点击「Create Project」按钮，等待项目创建完成（约需 2-3 分钟）
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/02b3f5271023432daaad769275d9970420260423100128562.png" alt="" /></li>
</ol></section><section><h3>3. 获取数据库连接信息<a href="#3-获取数据库连接信息"><span>#</span></a></h3><p>项目创建完成后：</p><ol>
<li>点击顶部菜单的「Connect」
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/b9d15d582fe3460d95524edbad95d0fd20260423110312620.png" alt="" /></li>
<li>在「Connection String」部分，找到「URI」格式的连接字符串
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/b425b7beed554f42ae2ecc68c5acdfa620260423110238977.png" alt="" /></li>
<li>复制这个连接字符串，备用</li>
</ol><p><strong>注意</strong>：连接字符串格式类似：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>postgresql://postgres:你的密码@aws-0-us-east-1.pooler.supabase.com:6543/postgres</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>4. 执行数据库初始化脚本<a href="#4-执行数据库初始化脚本"><span>#</span></a></h3><ol>
<li>点击左侧菜单的「SQL Editor」</li>
<li>点击「New query」按钮</li>
<li>复制粘贴以下 SQL 脚本：
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/fc80e7fbf61043f481bb5c8c937dce8620260423100807437.png" alt="" /></li>
</ol><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>-- Create tables</span></div></div><div><div><div>2</div></div><div><span>CREATE</span><span> </span><span>TABLE</span><span> </span><span>IF</span><span> </span><span>NOT</span><span> </span><span>EXISTS</span><span> accounts (</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>id </span><span>serial</span><span> </span><span>PRIMARY KEY</span><span>,</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>username </span><span>VARCHAR</span><span>(</span><span>255</span><span>) </span><span>UNIQUE</span><span> </span><span>NOT NULL</span><span>,</span></div></div><div><div><div>5</div></div><div><span>  </span><span>password</span><span> </span><span>VARCHAR</span><span>(</span><span>255</span><span>) </span><span>NOT NULL</span><span>,</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>created_at </span><span>TIMESTAMP</span><span> </span><span>DEFAULT</span><span> CURRENT_TIMESTAMP</span></div></div><div><div><div>7</div></div><div><span>);</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>CREATE</span><span> </span><span>TABLE</span><span> </span><span>IF</span><span> </span><span>NOT</span><span> </span><span>EXISTS</span><span> websites (</span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>id </span><span>serial</span><span> </span><span>PRIMARY KEY</span><span>,</span></div></div><div><div><div>11</div></div><div><span>  </span><span>name</span><span> </span><span>VARCHAR</span><span>(</span><span>255</span><span>) </span><span>NOT NULL</span><span>,</span></div></div><div><div><div>12</div></div><div><span><span>  </span></span><span>domain </span><span>VARCHAR</span><span>(</span><span>255</span><span>) </span><span>NOT NULL</span><span>,</span></div></div><div><div><div>13</div></div><div><span><span>  </span></span><span>share_id </span><span>VARCHAR</span><span>(</span><span>64</span><span>) </span><span>UNIQUE</span><span>,</span></div></div><div><div><div>14</div></div><div><span><span>  </span></span><span>created_at </span><span>TIMESTAMP</span><span> </span><span>DEFAULT</span><span> CURRENT_TIMESTAMP</span></div></div><div><div><div>15</div></div><div><span>);</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>CREATE</span><span> </span><span>TABLE</span><span> </span><span>IF</span><span> </span><span>NOT</span><span> </span><span>EXISTS</span><span> website_events (</span></div></div><div><div><div>18</div></div><div><span><span>  </span></span><span>id </span><span>serial</span><span> </span><span>PRIMARY KEY</span><span>,</span></div></div><div><div><div>19</div></div><div><span><span>  </span></span><span>website_id </span><span>INTEGER</span><span> </span><span>NOT NULL</span><span>,</span></div></div><div><div><div>20</div></div><div><span><span>  </span></span><span>session_id </span><span>VARCHAR</span><span>(</span><span>64</span><span>) </span><span>NOT NULL</span><span>,</span></div></div><div><div><div>21</div></div><div><span><span>  </span></span><span>event_type </span><span>VARCHAR</span><span>(</span><span>64</span><span>) </span><span>NOT NULL</span><span>,</span></div></div><div><div><div>22</div></div><div><span>  </span><span>url</span><span> </span><span>VARCHAR</span><span>(</span><span>2048</span><span>) </span><span>NOT NULL</span><span>,</span></div></div><div><div><div>23</div></div><div><span><span>  </span></span><span>referrer </span><span>VARCHAR</span><span>(</span><span>2048</span><span>),</span></div></div><div><div><div>24</div></div><div><span><span>  </span></span><span>device </span><span>VARCHAR</span><span>(</span><span>64</span><span>),</span></div></div><div><div><div>25</div></div><div><span><span>  </span></span><span>browser </span><span>VARCHAR</span><span>(</span><span>64</span><span>),</span></div></div><div><div><div>26</div></div><div><span><span>  </span></span><span>os </span><span>VARCHAR</span><span>(</span><span>64</span><span>),</span></div></div><div><div><div>27</div></div><div><span><span>  </span></span><span>country </span><span>VARCHAR</span><span>(</span><span>2</span><span>),</span></div></div><div><div><div>28</div></div><div><span><span>  </span></span><span>city </span><span>VARCHAR</span><span>(</span><span>255</span><span>),</span></div></div><div><div><div>29</div></div><div><span><span>  </span></span><span>screen </span><span>VARCHAR</span><span>(</span><span>64</span><span>),</span></div></div><div><div><div>30</div></div><div><span>  </span><span>language</span><span> </span><span>VARCHAR</span><span>(</span><span>64</span><span>),</span></div></div><div><div><div>31</div></div><div><span><span>  </span></span><span>created_at </span><span>TIMESTAMP</span><span> </span><span>DEFAULT</span><span> CURRENT_TIMESTAMP</span></div></div><div><div><div>32</div></div><div><span>);</span></div></div><div><div><div>33</div></div><div>
</div></div><div><div><div>34</div></div><div><span>-- Create indexes</span></div></div><div><div><div>35</div></div><div><span>CREATE</span><span> </span><span>INDEX</span><span> </span><span>IF</span><span> </span><span>NOT</span><span> </span><span>EXISTS</span><span> website_events_website_id_idx </span><span>ON</span><span> website_events(website_id);</span></div></div><div><div><div>36</div></div><div><span>CREATE</span><span> </span><span>INDEX</span><span> </span><span>IF</span><span> </span><span>NOT</span><span> </span><span>EXISTS</span><span> website_events_session_id_idx </span><span>ON</span><span> website_events(session_id);</span></div></div><div><div><div>37</div></div><div><span>CREATE</span><span> </span><span>INDEX</span><span> </span><span>IF</span><span> </span><span>NOT</span><span> </span><span>EXISTS</span><span> website_events_created_at_idx </span><span>ON</span><span> website_events(created_at);</span></div></div><div><div><div>38</div></div><div>
</div></div><div><div><div>39</div></div><div><span>-- Insert default account</span></div></div><div><div><div>40</div></div><div><span>INSERT INTO</span><span> accounts (username, </span><span>password</span><span>) </span><span>VALUES</span><span> (</span><span>'admin'</span><span>, </span><span>'$2b$10$t3q4bN3BjV8sS6XZ7Y8Z9u.7a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0t'</span><span>);</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><ol>
<li>点击「Run」按钮执行脚本</li>
</ol><p><strong>说明</strong>：默认账号的用户名是 <code>admin</code>，密码是 <code>umami</code>，登录后可以修改。</p><hr /></section></section>
<section><h2>方案二：使用 Vercel Database（Neon）部署<a href="#方案二使用-vercel-databaseneon部署"><span>#</span></a></h2><p>如果你觉得 Supabase 配置步骤太麻烦，也可以选择使用 Vercel 自带的 Neon 数据库服务，操作更加简单一体化。</p><section><h3>1. 登录 Vercel<a href="#1-登录-vercel"><span>#</span></a></h3><p>访问 <a href="https://vercel.com/dashboard" target="_blank">Vercel 控制台</a>，使用 GitHub 账号登录。</p></section><section><h3>2. 创建数据库<a href="#2-创建数据库"><span>#</span></a></h3><ol>
<li>在 Vercel 控制台中，点击左侧菜单的「Storage」</li>
<li>点击「Create Database」按钮</li>
<li>选择「Neon」作为数据库类型
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/2cc334d0acff445c92d9517231e1153420260423113254353.png" alt="" /></li>
<li>填写数据库信息：
<ul>
<li><strong>Database Name</strong>：填写数据库名称，比如 <code>umami-db</code></li>
<li><strong>Region</strong>：选择离你最近的区域</li>
</ul>
</li>
<li>点击「Create」按钮，等待数据库创建完成
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/7c16d298d5534daea6b604e5460bcaf320260423113342109.png" alt="" /></li>
</ol></section><section><h3>3. 获取数据库连接信息<a href="#3-获取数据库连接信息-1"><span>#</span></a></h3><p>数据库创建完成后：</p><ol>
<li>在 Storage 页面中，点击你刚刚创建的数据库</li>
<li>在「Connection Project」选项卡中，选择部署好的项目（前提是你已经部署了项目，建议先执行步骤二的内容）
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/9ed3a83987824258bc75ebef29a4e04420260423113448855.png" alt="" /></li>
<li>重新执行步骤二的第6点内容</li>
</ol></section></section>
<section><h2>步骤二：部署 Umami 到 Vercel<a href="#步骤二部署-umami-到-vercel"><span>#</span></a></h2><section><h3>1.  Fork Umami 仓库<a href="#1--fork-umami-仓库"><span>#</span></a></h3><ol>
<li>访问 <a href="https://github.com/umami-software/umami" target="_blank">Umami GitHub 仓库</a></li>
<li>点击右上角的「Fork」按钮，将仓库 fork 到自己的 GitHub 账号下
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/0bdc6920bbda4873a7e3a8d3413101d820260423110141629.png" alt="" /></li>
</ol></section><section><h3>2. 登录 Vercel<a href="#2-登录-vercel"><span>#</span></a></h3><p>访问 <a href="https://vercel.com/dashboard" target="_blank">Vercel 控制台</a>，使用 GitHub 账号登录。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/bbdb93a7e22a491199009a14c06ad61820260423110212262.png" alt="" /></p></section><section><h3>3. 导入项目<a href="#3-导入项目"><span>#</span></a></h3><ol>
<li>点击「Add New」→「Project」
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/d7303bc131d24282b074ee774af6ba8520260423092704153.png" alt="" /></li>
<li>在「Import Git Repository」部分，找到并选择你刚才 fork 的 Umami 仓库
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/949ca0ae0c954844af2a184764d9b32420260423092739701.png" alt="" /></li>
<li>点击「Import」按钮</li>
</ol></section><section><h3>4. 配置项目<a href="#4-配置项目"><span>#</span></a></h3><p>在配置页面：</p><ol>
<li><strong>Project Name</strong>：保持默认或修改为你喜欢的名称</li>
<li><strong>Framework Preset</strong>：选择「Next.js」</li>
<li><strong>Root Directory</strong>：保持默认</li>
<li><strong>Build and Output Settings</strong>：保持默认</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/028092d1138f47e598e5b6344e55bfa820260423092435632.png" alt="" /></p></section><section><h3>5. 设置环境变量<a href="#5-设置环境变量"><span>#</span></a></h3><p>在「Environment Variables」部分，点击「Add」按钮，添加以下环境变量：</p>

<table><thead><tr><th>变量名</th><th>值</th><th>说明</th></tr></thead><tbody><tr><td><code>DATABASE_URL</code></td><td>你的 Supabase 连接字符串</td><td>数据库连接地址</td></tr><tr><td><code>HASH_SALT</code></td><td>随机字符串</td><td>用于密码哈希，建议使用随机生成的字符串</td></tr></tbody></table><p><strong>注意</strong>：</p><ul>
<li><code>DATABASE_URL</code> 就是你在 Supabase 中复制的连接字符串</li>
<li><code>HASH_SALT</code> 可以使用在线工具生成一个随机字符串
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/77ff398d99b84e5987fd4602a904fd4520260423092827198.png" alt="" /></li>
</ul></section><section><h3>6. 部署项目<a href="#6-部署项目"><span>#</span></a></h3><p>点击「Deploy」按钮，等待部署完成。部署过程可能需要 2-3 分钟。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/dbc12fc015134577a0c3212560ed9ab120260423092851597.png" alt="" /></p></section><section><h3>7. 访问项目<a href="#7-访问项目"><span>#</span></a></h3><p>部署完成后，Vercel 会生成一个域名，点击「Visit」按钮即可访问 Umami 应用。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/9773e625c71a400a8673830af680f01c20260423110415551.png" alt="" /></p></section></section>
<section><h2>步骤三：配置 Umami<a href="#步骤三配置-umami"><span>#</span></a></h2><section><h3>1. 登录 Umami<a href="#1-登录-umami"><span>#</span></a></h3><ol>
<li>访问部署后的 Umami 网站</li>
<li>使用默认账号登录：
<ul>
<li>用户名：<code>admin</code></li>
<li>密码：<code>umami</code>
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/88831dca311549779e97c94608a6c43720260423113823228.png" alt="" /></li>
</ul>
</li>
</ol></section><section><h3>2. 修改默认密码(重要)<a href="#2-修改默认密码重要"><span>#</span></a></h3><ol>
<li>登录后，点击右上角的用户头像</li>
<li>选择「Profile」</li>
<li>在「Password」部分，输入新密码</li>
<li>点击「Save」按钮
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/17141b2a0f1542bea60488bb0e476f4420260423113913029.png" alt="" /></li>
</ol></section><section><h3>3. 添加网站<a href="#3-添加网站"><span>#</span></a></h3><ol>
<li>点击左侧菜单的「Websites」</li>
<li>点击「Add Website」按钮</li>
<li>填写网站信息：
<ul>
<li><strong>Name</strong>：网站名称</li>
<li><strong>Domain</strong>：网站域名</li>
</ul>
</li>
<li>点击「Save」按钮
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/e19d7115e0f04c0ebc5c4ec424265beb20260423114020934.png" alt="" /></li>
</ol></section><section><h3>4. 获取跟踪代码<a href="#4-获取跟踪代码"><span>#</span></a></h3><ol>
<li>在网站列表中，找到你刚刚添加的网站</li>
<li>点击右侧的「&lt;/&gt;」图标</li>
<li>复制跟踪代码</li>
<li>将跟踪代码添加到你网站的 <code>&lt;head&gt;</code> 标签中</li>
</ol></section></section>
<section><h2>步骤四：验证部署<a href="#步骤四验证部署"><span>#</span></a></h2><section><h3>1. 检查数据统计<a href="#1-检查数据统计"><span>#</span></a></h3><ol>
<li>访问你添加的网站</li>
<li>浏览几个页面</li>
<li>回到 Umami 控制台，查看「Real-time」数据</li>
<li>确认能看到访问数据</li>
</ol></section><section><h3>2. 检查历史数据<a href="#2-检查历史数据"><span>#</span></a></h3><ol>
<li>等待一段时间（约 5-10 分钟）</li>
<li>回到 Umami 控制台</li>
<li>查看「Dashboard」页面</li>
<li>确认能看到历史访问数据</li>
</ol></section></section>
<section><h2>常见问题及解决方案<a href="#常见问题及解决方案"><span>#</span></a></h2><section><h3>1. 数据库连接失败<a href="#1-数据库连接失败"><span>#</span></a></h3><p><strong>症状</strong>：部署后无法访问，或显示数据库连接错误</p><p><strong>解决方案</strong>：</p><ul>
<li>检查 <code>DATABASE_URL</code> 环境变量是否正确</li>
<li>确认 Supabase 项目是否正常运行</li>
<li>检查数据库密码是否正确</li>
</ul></section><section><h3>2. 跟踪代码不工作<a href="#2-跟踪代码不工作"><span>#</span></a></h3><p><strong>症状</strong>：网站访问后，Umami 中没有数据</p><p><strong>解决方案</strong>：</p><ul>
<li>确认跟踪代码是否正确添加到网站中</li>
<li>检查浏览器控制台是否有错误</li>
<li>确认网站域名是否与 Umami 中添加的域名一致</li>
</ul></section><section><h3>3. 部署失败<a href="#3-部署失败"><span>#</span></a></h3><p><strong>症状</strong>：Vercel 部署过程中出现错误</p><p><strong>解决方案</strong>：</p><ul>
<li>检查环境变量是否正确设置</li>
<li>确认 Umami 版本是否与 Vercel 兼容</li>
<li>查看部署日志，根据错误信息进行修复</li>
</ul></section></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>通过以上步骤，你已经成功在 Vercel 上部署了 Umami，并使用 Supabase 作为数据库。现在你可以：</p><ul>
<li>实时监控网站访问数据</li>
<li>查看详细的用户行为分析</li>
<li>导出数据进行进一步分析</li>
<li>完全掌控你的网站分析数据</li>
</ul><p>Umami 是一个非常优秀的开源网站分析工具，结合 Vercel 和 Supabase 的免费服务，你可以零成本搭建一个功能完整的网站分析系统。</p></section>
<section><h2>项目资源<a href="#项目资源"><span>#</span></a></h2><ul>
<li><strong>Umami GitHub 仓库</strong>：<a href="https://github.com/umami-software/umami" target="_blank">https://github.com/umami-software/umami</a></li>
<li><strong>Vercel 官网</strong>：<a href="https://vercel.com" target="_blank">https://vercel.com</a></li>
<li><strong>Supabase 官网</strong>：<a href="https://supabase.com" target="_blank">https://supabase.com</a></li>
</ul><p>希望这篇指南对你有所帮助！如果你在部署过程中遇到任何问题，欢迎在评论区留言。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/83b6163/</id>
      <title type="text">从“小白”到“大神”，Docker安装使用全攻略</title>
      <published>2026-04-11T18:31:13.000Z</published>
      <updated>2026-04-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/83b6163/"/>
      <summary type="text">Docker，简单来说，是一种开源的应用容器引擎 ，可以将应用程序及其依赖环境打包成一个可移植的容器，然后在任何支持 Docker 的环境中运行。它就像是一个超级 “集装箱”，把应用程序以及它运行所需要的各种 “零件”，如代码、运行时环境、系统工具、库文件等等，全部打包在一起 。这样不管这个 “集装箱” 被运到哪里，只要有能运行它的基础环境，应用程序都能以相同的方式运行，不会因为环境的变化而出现问题。</summary>
      <content type="html"><![CDATA[<section><h1>从“小白”到“大神”，Docker安装使用全攻略<a href="#从小白到大神docker安装使用全攻略"><span>#</span></a></h1><section><h2>Docker 是什么<a href="#docker-是什么"><span>#</span></a></h2><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/07/009dab7756074e66af44eed1c912f36ed0be9584-4b4d-4460-892a-b1022ac72a9f_1753441077954019004_origin~tplv-a9rns2rl98-image-qvalue.jpeg" alt="d0be9584-4b4d-4460-892a-b1022ac72a9f_1753441077954019004_origin~tplv-a9rns2rl98-image-qvalue" /><figcaption>d0be9584-4b4d-4460-892a-b1022ac72a9f_1753441077954019004_origin~tplv-a9rns2rl98-image-qvalue</figcaption></figure><p></p><p>Docker，简单来说，是一种开源的应用容器引擎 ，可以将应用程序及其依赖环境打包成一个可移植的容器，然后在任何支持 Docker 的环境中运行。它就像是一个超级 “集装箱”，把应用程序以及它运行所需要的各种 “零件”，如代码、运行时环境、系统工具、库文件等等，全部打包在一起 。这样不管这个 “集装箱” 被运到哪里，只要有能运行它的基础环境，应用程序都能以相同的方式运行，不会因为环境的变化而出现问题。</p><p>和传统的虚拟机相比，Docker 容器不需要像虚拟机那样为每个应用运行一个完整的操作系统，而是直接共享宿主机的操作系统内核 ，这使得它更加轻量级，启动速度更快，占用的资源也更少。在相同的硬件资源下，可以部署更多的容器实例，从而提高了服务器资源的利用率。</p><p>Docker 主要有三大核心概念，即镜像（Image）、容器（Container）和仓库（Repository）：</p><ul>
<li>
<p><strong>镜像</strong>：可以把它理解成一个只读的模板，包含了运行一个特定应用程序所需的所有文件系统内容，包括代码、运行时环境、库、依赖项等，就像是一个应用程序的 “快照”，定义了容器的初始状态。例如，一个基于 Python 的 Web 应用程序，其镜像会包含 Python 解释器、应用代码、所需的第三方库以及相关的配置文件等。</p>
</li>
<li>
<p><strong>容器</strong>：容器是镜像的运行实例，是从镜像创建出来的可运行的实体，可以看作是一个轻量级的、独立运行的操作系统环境，与宿主机以及其他容器相互隔离 。容器在运行时可以被启动、停止、暂停等操作，每个容器都有自己独立的文件系统、网络空间和进程空间等。比如，基于上述 Python Web 应用的镜像创建的容器，就是该应用实际运行的环境，它可以接收网络请求并处理业务逻辑。</p>
</li>
<li>
<p><strong>仓库</strong>：Docker 仓库是用来存储镜像的地方，分为公共仓库和私有仓库 。公共仓库如 Docker Hub，提供了大量的官方和社区维护的镜像，供用户免费下载和使用；私有仓库则通常由企业或组织自己搭建和管理，用于存储内部使用的镜像，以保证镜像的安全性和私密性。</p>
</li>
</ul></section><section><h2>为什么要用 Docker<a href="#为什么要用-docker"><span>#</span></a></h2><p>Docker 之所以在近年来如此火爆，成为众多开发者和企业的首选，是因为它能解决许多传统应用部署方式中存在的痛点，为软件开发和运维带来了极大的便利和效率提升 。下面我们来详细探讨一下为什么要使用 Docker。</p><ul>
<li>
<p><strong>环境一致性保障</strong>：在传统的开发与部署流程中，开发、测试和生产环境往往存在差异，这就导致了常说的 “在我机器上可以运行” 但在其他环境中出现故障的问题。不同的操作系统版本、软件库的安装与配置不同，都可能使得应用程序在不同环境中的表现不一致，增加了调试和部署的难度 。而 Docker 通过将应用程序及其依赖环境打包成一个镜像，确保了无论在开发、测试还是生产环境中，运行环境都是完全一致的。只要有支持 Docker 的运行时，应用就能以相同的方式运行，大大减少了因环境问题导致的部署失败和调试时间，提高了软件的可移植性和可靠性 。</p>
</li>
<li>
<p><strong>快速部署与扩展</strong>：Docker 容器的启动速度极快，通常只需要几秒钟，相比传统虚拟机的几分钟启动时间，极大地提高了应用的部署速度。当业务需求发生变化，需要扩展或缩减应用的规模时，使用 Docker 可以轻松实现。通过简单的命令，就可以快速创建或删除容器实例，实现应用的弹性伸缩。例如，在电商促销活动期间，可以快速启动更多的容器来应对突增的流量；活动结束后，又能及时减少容器数量，节省资源成本 。</p>
</li>
<li>
<p><strong>资源利用率高</strong>：传统的虚拟化技术需要为每个应用运行一个完整的操作系统，这会占用大量的系统资源，包括内存、CPU 等 。而 Docker 容器共享宿主机的操作系统内核，不需要额外的操作系统层，因此资源占用小，在相同的硬件资源下，可以部署更多的容器实例，从而提高了服务器资源的利用率，降低了硬件成本 。</p>
</li>
<li>
<p><strong>易于管理和维护</strong>：Docker 提供了统一的镜像管理和容器管理方式，通过简单的命令，就可以对镜像和容器进行创建、删除、启动、停止、查看状态等操作，使得应用的管理和维护变得更加简单和高效 。同时，Docker 还支持版本控制，开发者可以为不同版本的镜像打上标签，方便管理和追踪。当新版本的应用出现问题时，可以快速回滚到之前的稳定版本 。</p>
</li>
</ul><p>为了更直观地感受 Docker 的优势，我们来看一个具体的案例。假设有一个开发团队正在开发一个基于微服务架构的电商平台，该平台包含用户服务、商品服务、订单服务等多个微服务 。在传统的部署方式下，每个微服务都需要单独配置运行环境，安装相应的依赖项，这是一个繁琐且容易出错的过程。而且，不同微服务之间可能会因为依赖项的冲突或环境配置的差异而出现问题 。使用 Docker 后，每个微服务都可以被打包成一个独立的容器，这些容器之间相互隔离，互不影响。开发团队可以在本地开发环境中轻松地创建和管理这些容器，确保每个微服务都能正常运行 。在部署到生产环境时，只需要将这些容器镜像推送到生产服务器上，然后使用简单的命令就可以启动所有的微服务容器，大大缩短了部署时间，提高了部署的可靠性 。当某个微服务需要升级或修复时，只需要更新对应的容器镜像，然后重新启动容器即可，不会影响到其他微服务的正常运行 。</p></section><section><h2>Docker 安装教程<a href="#docker-安装教程"><span>#</span></a></h2><p>了解了 Docker 的强大功能后，接下来我们就进入实战环节，看看如何在不同的操作系统上安装 Docker。</p><section><h3>Windows 系统安装<a href="#windows-系统安装"><span>#</span></a></h3><p>在 Windows 系统下，我们可以通过安装 Docker Desktop 来使用 Docker。Docker Desktop 是一个用于在 Windows 上轻松构建、管理和运行容器化应用程序的工具，它集成了 Docker 引擎、CLI 客户端和 Kubernetes 等组件 。</p><p>具体安装步骤如下：</p><ol>
<li>
<p><strong>检查系统要求</strong>：确保你的 Windows 系统满足以下条件：Windows 10 64 位（专业版、企业版或教育版）或 Windows 11；64 位处理器，支持虚拟化（Intel VT-x 或 AMD-V）；至少 4GB 内存 。你可以通过运行<code>systeminfo</code>命令来查看系统信息，确认是否支持虚拟化。在输出结果中，找到 “Hyper-V Requirements” 部分，如果 “虚拟化已启用” 显示为 “是”，则说明系统支持虚拟化；若为 “否”，则需要进入 BIOS 或 UEFI 设置中启用虚拟化功能 。不同品牌的计算机进入 BIOS 的方式可能不同，一般在开机时按下 F2、F10、Delete 等键，具体按键可参考计算机的用户手册 。在 BIOS 设置中，找到 “Virtualization Technology” 或 “VT-x”（Intel）/“AMD-V”（AMD）选项，将其设置为 “Enabled” 启用，然后保存并退出 BIOS 。</p>
</li>
<li>
<p><strong>安装 WSL 2</strong>：WSL（Windows Subsystem for Linux）是 Windows 的一个功能，允许你在 Windows 上运行 Linux 二进制可执行文件 。Docker Desktop 依赖 WSL 2 作为后端引擎，因此需要先安装 WSL 2 。以管理员身份运行 PowerShell，执行<code>wsl --install</code>命令，该命令会自动安装最新版本的 WSL 及其核心组件，并设置 WSL 2 为默认版本 。安装完成后，重启计算机 。如果执行<code>wsl --install</code>命令时提示错误，可能是因为系统版本不支持或其他原因。你可以尝试手动安装 WSL 2，具体步骤如下：首先，下载适用于 Linux 的内核更新包，下载地址：<a href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">http</a><a href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">s://w</a><a href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">slsto</a><a href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">resto</a><a href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">rage.</a><a href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">blob.</a><a href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">core.</a><a href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">windo</a><a href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">ws.ne</a><a href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">t/wsl</a><a href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">blob/</a><a href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">wsl_u</a><a href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">pdate</a><a href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">_x64.</a><a href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">msi</a> 。下载完成后，运行安装包进行安装 。然后，以管理员身份运行 PowerShell，执行<code>wsl --set-default-version 2</code>命令，设置 WSL 2 为默认版本 。</p>
</li>
<li>
<p><strong>下载 Docker Desktop</strong>：访问 Docker 官网下载页面（<a href="https://www.docker.com/products/docker-desktop/" target="_blank">ht</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">tps:/</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">/www.</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">docke</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">r.com</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">/prod</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">ucts/</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">docke</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">r-des</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">ktop/</a>），点击 “Download for Windows” 按钮，下载最新版本的 Docker Desktop 安装程序 。</p>
</li>
<li>
<p><strong>安装 Docker Desktop</strong>：找到下载的安装文件（通常在 “下载” 文件夹中），双击安装文件，启动安装向导 。在安装过程中，按照提示进行操作，建议保留默认设置 。在 “Configuration” 页面，确保选择 “Use the WSL 2 based engine” 选项，以使用 WSL 2 作为容器后端 。安装完成后，可能需要重启计算机 。</p>
</li>
<li>
<p><strong>验证安装</strong>：打开命令提示符（CMD）或 PowerShell，输入<code>docker --version</code>命令，验证 Docker 是否安装成功 。如果安装成功，该命令将输出当前安装的 Docker 版本信息，例如 “Docker version 24.0.6, build ed223bc” 。你还可以运行<code>docker run hello-world</code>命令来测试 Docker 是否正常工作 。该命令会从 Docker Hub 下载一个测试镜像，并在容器中运行它 。如果一切顺利，你将看到 “Hello from Docker!” 的输出信息，表明 Docker 已成功安装并可以正常使用 。</p>
</li>
</ol><p>在安装过程中，可能会遇到一些问题，比如虚拟化未开启、缺少 WSL 2 工具等。针对这些问题，可以参考以下解决方案：</p><ul>
<li>
<p><strong>虚拟化未开启</strong>：如果在安装 Docker Desktop 时提示虚拟化未开启，按照上述 “检查系统要求” 步骤中提到的方法，进入 BIOS 或 UEFI 设置中启用虚拟化功能 。</p>
</li>
<li>
<p><strong>缺少 WSL 2 工具</strong>：如果提示缺少 WSL 2 工具，按照上述 “安装 WSL 2” 步骤中提到的方法，安装 WSL 2 。</p>
</li>
<li>
<p><strong>安装过程中出现其他错误</strong>：如果在安装过程中出现其他错误，可以查看 Docker Desktop 的安装日志，日志文件位于 “C:\Users\ 你的用户名 \AppData\Local\Docker\log” 目录下 。根据日志文件中的错误信息，在 Docker 官方文档或社区论坛中查找解决方案 。</p>
</li>
</ul></section><section><h3>Linux 系统安装（以 Ubuntu 为例）<a href="#linux-系统安装以-ubuntu-为例"><span>#</span></a></h3><p>在 Ubuntu 系统中，安装 Docker 也非常简单，只需要几个命令即可完成 。以下是具体的安装步骤：</p><ol>
<li><strong>更新软件包列表</strong>：在安装 Docker 之前，首先需要更新系统的软件包列表，以获取最新的软件包信息 。打开终端，运行以下命令：</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo apt-get update</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li><strong>安装依赖</strong>：Docker 依赖一些必要的软件包，我们需要先安装它们 。运行以下命令：</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>其中，<code>apt-transport-https</code>允许<code>apt</code>包管理器通过 HTTPS 协议与软件源进行通信；<code>ca-certificates</code>包含了根证书，用于验证 SSL/TLS 连接的安全性；<code>curl</code>是一个命令行工具，用于通过 URL 下载文件；<code>gnupg</code>是一个用于加密和签名的工具；<code>lsb-release</code>用于显示系统的发行版信息 。</p><p>3. <strong>添加 GPG 密钥</strong>：为了确保从 Docker 官方仓库下载的软件包的完整性和安全性，我们需要添加 Docker 官方的 GPG 密钥 。运行以下命令：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li><strong>添加软件源</strong>：将 Docker 官方的软件源添加到系统的软件源列表中，以便系统能够从该源下载 Docker 软件包 。运行以下命令：</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>echo "deb \[arch=\$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \$(lsb\_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list &gt; /dev/null</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li><strong>再次更新软件包列表</strong>：添加软件源后，需要再次更新软件包列表，使系统能够识别新添加的软件源 。运行以下命令：</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo apt-get update</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li><strong>安装 Docker 引擎</strong>：现在可以安装 Docker 引擎了，运行以下命令：</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>其中，<code>docker-ce</code>是 Docker 社区版的核心引擎；<code>docker-ce-cli</code>是 Docker 的命令行工具；<code>containerd.io</code>是一个开源的容器运行时；<code>docker-compose-plugin</code>是用于定义和运行多容器 Docker 应用程序的插件 。</p><p>7. <strong>验证安装</strong>：安装完成后，可以通过查看 Docker 的版本信息和运行测试镜像来验证安装是否成功 。运行以下命令查看版本信息：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker --version</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>运行以下命令运行测试镜像：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo docker run hello-world</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果安装成功，运行<code>docker --version</code>命令会输出 Docker 的版本号，运行<code>sudo docker run hello-world</code>命令会下载一个测试镜像并在容器中运行它，输出 “Hello from Docker!” 等信息 。</p></section><section><h3>MacOS 系统安装<a href="#macos-系统安装"><span>#</span></a></h3><p>在 MacOS 系统上，我们同样可以通过安装 Docker Desktop 来使用 Docker 。以下是具体的安装步骤：</p><ol>
<li>
<p><strong>下载 Docker Desktop</strong>：打开浏览器，访问 Docker 官网下载页面（<a href="https://www.docker.com/products/docker-desktop/" target="_blank">http</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">s://w</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">ww.do</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">cker.</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">com/p</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">roduc</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">ts/do</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">cker-</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">deskt</a><a href="https://www.docker.com/products/docker-desktop/" target="_blank">op/</a>），点击 “Download for Mac” 按钮，下载最新版本的 Docker Desktop 安装程序 。</p>
</li>
<li>
<p><strong>安装 Docker Desktop</strong>：下载完成后，双击下载的<code>.dmg</code>文件，将 Docker 图标拖放到 “应用程序” 文件夹中，完成安装 。</p>
</li>
<li>
<p><strong>启动 Docker Desktop</strong>：打开 “应用程序” 文件夹，找到 Docker 并双击打开 。首次启动时，可能会要求输入你的 MacOS 账号密码以授权 。</p>
</li>
<li>
<p><strong>基本配置</strong>：启动 Docker Desktop 后，可以根据自己的需求进行一些基本配置 。点击菜单栏中的 Docker 图标，选择 “Preferences”，在弹出的窗口中可以进行以下配置：</p>
</li>
</ol><ul>
<li>
<p><strong>Resources</strong>：在这里可以分配给 Docker 的 CPU、内存和磁盘空间等资源 。根据实际需求合理调整这些参数，以确保 Docker 能够在你的系统上稳定运行 。例如，如果你的项目对内存要求较高，可以适当增加分配给 Docker 的内存大小 。</p>
</li>
<li>
<p><strong>Network</strong>：设置 Docker 的网络模式 。默认情况下，Docker 会创建一个桥接网络，容器可以通过该网络与主机和其他容器进行通信 。如果你的项目有特殊的网络需求，也可以在这里进行自定义设置 。</p>
</li>
<li>
<p><strong>Docker Engine</strong>：手动配置 Docker 引擎的 JSON 设置 。一般情况下，保持默认设置即可 。但如果你对 Docker 的运行机制有深入了解，并且有特定的配置需求，也可以在这里进行修改 。</p>
</li>
</ul><ol>
<li><strong>验证安装</strong>：打开终端（Terminal），输入<code>docker --version</code>命令，验证 Docker 是否安装成功 。如果安装成功，该命令将输出当前安装的 Docker 版本信息 。你还可以运行<code>docker run hello-world</code>命令来测试 Docker 是否正常工作 。如果一切顺利，你将看到 “Hello from Docker!” 的输出信息，表明 Docker 已成功安装并可以正常使用 。</li>
</ol></section></section><section><h2>Docker 基本使用<a href="#docker-基本使用"><span>#</span></a></h2><p>在掌握了 Docker 的安装方法后，接下来让我们深入了解 Docker 的基本使用方法，包括镜像操作、容器操作和数据管理等方面，这些操作是使用 Docker 进行应用部署和管理的基础 。</p><section><h3>镜像操作<a href="#镜像操作"><span>#</span></a></h3><ul>
<li><strong>下载镜像</strong>：Docker Hub 是一个公共的镜像仓库，我们可以使用<code>docker pull</code>命令从 Docker Hub 下载镜像 。例如，要下载最新版本的 Nginx 镜像，可以执行以下命令：</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker pull nginx</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在上述命令中，如果不指定具体的版本标签，<code>docker pull</code>命令会默认下载镜像的<code>latest</code>标签版本，即最新版本 。如果需要下载特定版本的镜像，可以在镜像名称后加上版本标签，例如下载 Nginx 的 1.23.1 版本镜像，命令如下：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker pull nginx:1.23.1</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li><strong>构建自定义镜像</strong>：当官方提供的镜像无法满足我们的需求时，就需要基于<code>Dockerfile</code>来构建自定义镜像 。<code>Dockerfile</code>是一个文本文件，其中包含了一系列用于构建镜像的指令和操作步骤 。例如，我们要构建一个基于 Python 3.11 的 Web 应用镜像，假设<code>Dockerfile</code>的内容如下：</li>
</ul><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>\# 使用官方Python 3.11镜像作为基础镜像</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>FROM python:3.11-slim</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>\# 设置工作目录为/app</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>WORKDIR /app</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>\# 将当前目录下的所有文件复制到容器的/app目录中</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>COPY. /app</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>\# 安装项目依赖，假设项目依赖文件为requirements.txt</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>RUN pip install -r requirements.txt</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>\# 暴露容器的8000端口，用于Web应用的访问</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>EXPOSE 8000</span></div></div><div><div><div>20</div></div><div>
</div></div><div><div><div>21</div></div><div><span>\# 设置容器启动时执行的命令，假设启动Web应用的命令为python main.py</span></div></div><div><div><div>22</div></div><div>
</div></div><div><div><div>23</div></div><div><span>CMD \["python", "main.py"]</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>在包含上述<code>Dockerfile</code>的目录下，执行以下命令来构建镜像：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker build -t my-python-web-app.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在这个命令中，<code>-t</code>参数用于指定镜像的标签，格式为<code>[仓库名/][镜像名]:[标签]</code> ，这里<code>my-python-web-app</code>就是我们给镜像指定的名称和标签 。最后的<code>.</code>表示构建上下文为当前目录，即<code>Dockerfile</code>所在的目录，Docker 会在这个目录及其子目录中查找构建镜像所需的文件 。</p><ul>
<li><strong>查看本地镜像列表</strong>：使用<code>docker images</code>命令可以查看本地已经下载或构建的镜像列表，命令执行结果会显示镜像的仓库名、标签、镜像 ID、创建时间和大小等信息 ，例如：</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker images</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>执行上述命令后，可能得到类似如下的输出：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>nginx               latest              d1a364dc548d        3 weeks ago         133MB</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>my-python-web-app   latest              9c87f97e2f34        1 hour ago          256MB</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>从输出结果中，我们可以清晰地看到本地已有的镜像信息，方便我们对镜像进行管理和使用 。</p><ul>
<li><strong>删除镜像</strong>：当某个镜像不再需要时，可以使用<code>docker rmi</code>命令将其删除 。例如，要删除<code>my-python-web-app:latest</code>这个镜像，可以执行以下命令：</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker rmi my-python-web-app:latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果要删除多个镜像，可以在命令后依次列出镜像的名称和标签，或者使用镜像 ID 进行删除 。需要注意的是，如果某个镜像正在被容器使用，直接删除该镜像会失败，需要先停止并删除依赖该镜像的容器，然后才能删除镜像 。</p></section><section><h3>容器操作<a href="#容器操作"><span>#</span></a></h3><ul>
<li><strong>创建并运行容器</strong>：使用<code>docker run</code>命令可以创建并运行一个容器 。该命令的基本语法为<code>docker run [OPTIONS] IMAGE [COMMAND] [ARG]</code> ，其中<code>OPTIONS</code>是可选参数，<code>IMAGE</code>是指定的镜像名称，<code>COMMAND</code>是容器启动时要执行的命令，<code>ARG</code>是传递给命令的参数 。例如，基于 Nginx 镜像创建并运行一个容器，将容器的 80 端口映射到主机的 8080 端口，命令如下：</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker run -d -p 8080:80 --name my-nginx nginx</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在这个命令中：</p><ul>
<li>
<p><code>-d</code>参数表示以守护（后台）模式运行容器，容器会在后台运行，不会占用当前终端 。</p>
</li>
<li>
<p><code>-p 8080:80</code>表示将主机的 8080 端口映射到容器的 80 端口，这样通过访问主机的 8080 端口，就可以访问到容器内 Nginx 服务的 80 端口 。</p>
</li>
<li>
<p><code>--name my-nginx</code>为容器指定一个名称<code>my-nginx</code>，方便后续对容器进行管理和操作 。</p>
</li>
<li>
<p><code>nginx</code>是要使用的镜像名称 。</p>
</li>
<li>
<p><strong>查看正在运行的容器</strong>：使用<code>docker ps</code>命令可以查看当前正在运行的容器列表，命令执行结果会显示容器的 ID、使用的镜像、启动命令、创建时间、状态、端口映射和容器名称等信息 ，例如：</p>
</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker ps</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>执行上述命令后，可能得到类似如下的输出：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>7f37a8c9c8c8   nginx     "/docker-entrypoint.…"   5 minutes ago    Up 5 minutes    0.0.0.0:8080-&gt;80/tcp, :::8080-&gt;80/tcp   my-nginx</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>从输出结果中，我们可以清楚地了解正在运行的容器的各项信息 。如果要查看所有容器（包括已停止的容器），可以使用<code>docker ps -a</code>命令 。</p><ul>
<li><strong>停止容器</strong>：当需要停止正在运行的容器时，可以使用<code>docker stop</code>命令，后面跟上容器的 ID 或名称 。例如，停止名为<code>my-nginx</code>的容器，命令如下：</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker stop my-nginx</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>执行该命令后，容器会被优雅地停止，即容器内的应用程序会收到停止信号，有机会进行一些清理工作后再停止运行 。</p><ul>
<li><strong>启动已停止的容器</strong>：对于已经停止的容器，可以使用<code>docker start</code>命令来重新启动它，同样后面跟上容器的 ID 或名称 。例如，启动名为<code>my-nginx</code>的容器，命令如下：</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker start my-nginx</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li><strong>进入正在运行的容器内部</strong>：有时候我们需要进入正在运行的容器内部，执行一些命令或进行调试等操作，可以使用<code>docker exec</code>命令 。例如，进入名为<code>my-nginx</code>的容器，并启动一个交互式的<code>bash</code> shell，命令如下：</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker exec -it my-nginx bash</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在这个命令中，<code>-i</code>参数表示保持标准输入流打开，允许我们向容器内输入命令；<code>-t</code>参数表示为容器分配一个伪终端，使我们能够在终端中与容器进行交互 。执行上述命令后，我们就可以在容器内部执行各种命令，就像在容器所在的主机上操作一样 。</p></section><section><h3>数据管理<a href="#数据管理"><span>#</span></a></h3><ul>
<li>
<p><strong>数据卷的概念和作用</strong>：在 Docker 中，容器的存储是临时的，当容器被删除时，容器内的数据也会随之丢失 。为了解决数据持久化存储和共享的问题，Docker 引入了数据卷（Volume）的概念 。数据卷是一个可供容器使用的特殊目录，它将主机操作系统目录直接映射进容器，或者由 Docker 管理一个存储区域并挂载到容器中 。数据卷具有以下特点：</p>
<ul>
<li>
<p><strong>数据持久化</strong>：即使容器被删除，数据卷中的数据仍然会保留，不会丢失 。</p>
</li>
<li>
<p><strong>容器间共享</strong>：多个容器可以挂载同一个数据卷，实现数据的共享和传递 。</p>
</li>
<li>
<p><strong>读写性能高</strong>：数据卷直接绕过 Union File System，对数据卷的读写操作性能较高 。</p>
</li>
</ul>
</li>
<li>
<p><strong>创建数据卷</strong>：使用<code>docker volume create</code>命令可以创建一个数据卷 。例如，创建一个名为<code>my-data-volume</code>的数据卷，命令如下：</p>
</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker volume create my-data-volume</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>执行该命令后，Docker 会在主机上创建一个用于存储数据卷的目录，并生成一个唯一的数据卷 ID 。我们可以使用<code>docker volume ls</code>命令查看所有已创建的数据卷列表，使用<code>docker volume inspect my-data-volume</code>命令查看指定数据卷的详细信息，包括数据卷的名称、驱动、挂载点等 。</p><ul>
<li><strong>挂载数据卷到容器</strong>：在使用<code>docker run</code>命令创建容器时，可以通过<code>-v</code>或<code>--mount</code>参数将数据卷挂载到容器中 。例如，创建一个基于 Nginx 镜像的容器，并将名为<code>my-data-volume</code>的数据卷挂载到容器的<code>/usr/share/nginx/html</code>目录下，命令如下：</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker run -d -p 8080:80 --name my-nginx -v my-data-volume:/usr/share/nginx/html nginx</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>或者使用<code>--mount</code>参数的方式：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker run -d -p 8080:80 --name my-nginx --mount source=my-data-volume,target=/usr/share/nginx/html nginx</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这两种方式的效果是相同的，都是将<code>my-data-volume</code>数据卷挂载到容器的<code>/usr/share/nginx/html</code>目录，使得容器内该目录下的数据实际上存储在数据卷中 。这样，当容器被删除并重新创建时，只要挂载相同的数据卷，容器内<code>/usr/share/nginx/html</code>目录下的数据仍然会保留 。同时，如果有多个容器都挂载了同一个数据卷，它们之间就可以共享该数据卷中的数据 。</p></section></section><section><h2>实战演练<a href="#实战演练"><span>#</span></a></h2><p>为了更直观地感受 Docker 的强大功能和便捷性，我们通过一个具体的实战案例来深入了解它的使用方法。在这个案例中，我们将使用 Docker 部署一个简单的 Flask Web 应用 。Flask 是一个轻量级的 Python Web 框架，非常适合用于快速开发小型 Web 应用 。通过这个实战，你将掌握如何使用 Docker 构建、运行和管理一个 Web 应用容器 。</p><section><h3>项目准备<a href="#项目准备"><span>#</span></a></h3><ol>
<li><strong>创建项目目录</strong>：首先，在你的计算机上创建一个新的项目目录，例如<code>flask - docker - demo</code>，并进入该目录 。</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>mkdir flask - docker - demo</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>cd flask - docker - demo</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li><strong>初始化 Python 虚拟环境（可选）</strong>：为了避免项目依赖与系统环境冲突，建议在项目目录下创建一个 Python 虚拟环境 。如果你还没有安装<code>virtualenv</code>，可以使用以下命令进行安装（假设你已经安装了 Python）：</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>pip install virtualenv</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>创建并激活虚拟环境：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>virtualenv venv</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>source venv/bin/activate  # Windows下使用 \`venv\Scripts\activate\`</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li><strong>安装 Flask</strong>：在激活的虚拟环境中，使用<code>pip</code>安装 Flask：</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>pip install flask</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li><strong>编写 Flask 应用代码</strong>：使用你喜欢的文本编辑器，在项目目录下创建一个名为<code>app.py</code>的文件，并编写以下 Flask 应用代码：</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>from flask import Flask</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>app = Flask(\_\_name\_\_)</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>@app.route('/')</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>def hello\_world():</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>&amp;#x20;   return 'Hello, Docker!'</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>if \_\_name\_\_ == '\_\_main\_\_':</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>&amp;#x20;   app.run(host='0.0.0.0', port=5000)</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这段代码创建了一个简单的 Flask 应用，定义了一个根路由<code>/</code>，当访问该路由时，返回<code>Hello, Docker!</code> 。<code>app.run(host='``0.0.0.0``', port=5000)</code>表示应用监听在 0.0.0.0 地址的 5000 端口上，这样可以通过宿主机的 IP 地址和 5000 端口来访问该应用 。</p></section><section><h3>编写 Dockerfile<a href="#编写-dockerfile"><span>#</span></a></h3><p>接下来，我们需要编写一个<code>Dockerfile</code>来定义如何构建我们的 Docker 镜像 。在项目目录下创建一个名为<code>Dockerfile</code>的文件（注意文件名大小写，且没有文件扩展名），并写入以下内容：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>\# 使用官方Python 3.11镜像作为基础镜像</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>FROM python:3.11 - slim</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>\# 设置工作目录为/app</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>WORKDIR /app</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>\# 将当前目录下的所有文件复制到容器的/app目录中</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>COPY. /app</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>\# 安装项目依赖，假设项目依赖文件为requirements.txt，这里直接安装Flask</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>RUN pip install flask</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>\# 暴露容器的5000端口，用于Web应用的访问</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>EXPOSE 5000</span></div></div><div><div><div>20</div></div><div>
</div></div><div><div><div>21</div></div><div><span>\# 设置容器启动时执行的命令，运行Flask应用</span></div></div><div><div><div>22</div></div><div>
</div></div><div><div><div>23</div></div><div><span>CMD \["python", "app.py"]</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>这个<code>Dockerfile</code>的具体解释如下：</p><ul>
<li>
<p><code>FROM python:3.11 - slim</code>：指定使用官方的 Python 3.11 精简版镜像作为基础镜像，该镜像包含了 Python 3.11 运行环境，且体积相对较小 。</p>
</li>
<li>
<p><code>WORKDIR /app</code>：设置容器内的工作目录为<code>/app</code>，后续的操作将在这个目录下进行 。</p>
</li>
<li>
<p><code>COPY. /app</code>：将当前目录（即项目目录<code>flask - docker - demo</code>）下的所有文件复制到容器的<code>/app</code>目录中 。</p>
</li>
<li>
<p><code>RUN pip install flask</code>：在容器内运行<code>pip install flask</code>命令，安装 Flask 及其依赖项 。</p>
</li>
<li>
<p><code>EXPOSE 5000</code>：声明容器内的应用将监听 5000 端口，这只是一个声明，并不实际进行端口映射 。</p>
</li>
<li>
<p><code>CMD ["python", "``app.py``"]</code>：指定容器启动时执行的命令，这里是运行<code>app.py</code>文件来启动 Flask 应用 。</p>
</li>
</ul></section><section><h3>构建 Docker 镜像<a href="#构建-docker-镜像"><span>#</span></a></h3><p>在包含<code>Dockerfile</code>和<code>app.py</code>的项目目录下，打开终端，执行以下命令来构建 Docker 镜像：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker build -t flask - app.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在这个命令中：</p><ul>
<li>
<p><code>-t</code>参数用于指定镜像的标签，格式为<code>[仓库名/][镜像名]:[标签]</code> ，这里我们将镜像命名为<code>flask - app</code>，并使用默认的<code>latest</code>标签 。</p>
</li>
<li>
<p>最后的<code>.</code>表示构建上下文为当前目录，即<code>Dockerfile</code>所在的目录，Docker 会在这个目录及其子目录中查找构建镜像所需的文件 。</p>
</li>
</ul><p>执行构建命令后，Docker 会读取<code>Dockerfile</code>中的指令，逐步构建镜像 。在构建过程中，你会看到一系列的输出信息，显示每个步骤的执行情况 。如果构建成功，最终会显示<code>Successfully tagged flask - app:latest</code>，表示镜像构建完成，并打上了<code>flask - app:latest</code>的标签 。</p></section><section><h3>运行 Docker 容器<a href="#运行-docker-容器"><span>#</span></a></h3><p>镜像构建完成后，我们可以使用<code>docker run</code>命令来运行容器 。在终端中执行以下命令：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker run -d -p 8080:5000 --name flask - container flask - app</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这个命令的参数解释如下：</p><ul>
<li>
<p><code>-d</code>：表示以守护（后台）模式运行容器，容器会在后台运行，不会占用当前终端 。</p>
</li>
<li>
<p><code>-p 8080:5000</code>：将主机的 8080 端口映射到容器的 5000 端口，这样通过访问主机的 8080 端口，就可以访问到容器内 Flask 应用监听的 5000 端口 。</p>
</li>
<li>
<p><code>--name flask - container</code>：为容器指定一个名称<code>flask - container</code>，方便后续对容器进行管理和操作 。</p>
</li>
<li>
<p><code>flask - app</code>：指定要运行的镜像名称 。</p>
</li>
</ul><p>执行上述命令后，Docker 会从<code>flask - app</code>镜像创建一个容器并运行它 。你可以使用<code>docker ps</code>命令查看正在运行的容器列表，确认容器是否成功启动 。如果容器启动成功，在<code>docker ps</code>的输出中，你会看到<code>flask - container</code>容器正在运行，并且端口映射为<code>0.0.0.0:8080``-&gt;5000/tcp</code> 。</p></section><section><h3>访问 Web 应用<a href="#访问-web-应用"><span>#</span></a></h3><p>现在，打开你的浏览器，在地址栏中输入<code>http://localhost:8080</code>，如果一切顺利，你将看到浏览器页面上显示<code>Hello, Docker!</code> ，这表明我们使用 Docker 部署的 Flask Web 应用已经成功运行 。</p><p>通过这个实战案例，我们展示了使用 Docker 部署一个简单 Web 应用的完整过程，包括项目准备、编写<code>Dockerfile</code>、构建镜像和运行容器 。希望这个案例能帮助你更好地理解和掌握 Docker 的基本使用方法，为你在实际项目中应用 Docker 打下坚实的基础 。</p></section></section><section><h2>常见问题及解决方法<a href="#常见问题及解决方法"><span>#</span></a></h2><p>在安装和使用 Docker 的过程中，可能会遇到一些问题，下面为大家整理了一些常见问题及对应的解决方法 。</p><section><h3>镜像下载缓慢<a href="#镜像下载缓慢"><span>#</span></a></h3><ul>
<li>
<p><strong>问题描述</strong>：在使用<code>docker pull</code>命令下载镜像时，速度非常慢，甚至可能会出现下载超时的情况 。</p>
</li>
<li>
<p><strong>原因分析</strong>：Docker 默认使用的是国外的官方镜像源，由于网络原因，国内访问可能会受到限制，导致下载速度缓慢 。</p>
</li>
<li>
<p><strong>解决方法</strong>：可以通过配置国内的镜像加速器来提高镜像下载速度 。常见的国内镜像加速器有阿里云镜像加速器、网易云镜像加速器、中科大镜像加速器等 。以阿里云镜像加速器为例，配置步骤如下：</p>
<ul>
<li><strong>Windows 系统</strong>：打开 Docker Desktop，点击任务栏中的 Docker 图标，选择 “Settings”，在弹出的窗口中选择 “Docker Engine” 选项卡 。在 “Registry mirrors” 字段中，添加阿里云提供的专属镜像加速地址（需要先登录阿里云容器镜像服务获取），格式如下：</li>
</ul>
</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>&amp;#x20; "registry-mirrors": \["https://xxxxxx.mirror.aliyuncs.com"]</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>添加完成后，点击右下角的 “Apply &amp; Restart” 按钮，Docker 会自动重启并应用新的镜像源配置 。</p><ul>
<li><strong>Linux 系统</strong>：首先，创建或编辑 Docker 的配置文件<code>/etc/docker/daemon.json</code>（如果文件不存在则创建），添加以下内容：</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>&amp;#x20; "registry-mirrors": \["https://xxxxxx.mirror.aliyuncs.com"]</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后，保存文件并执行以下命令使配置生效：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo systemctl daemon-reload</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>sudo systemctl restart docker</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>配置完成后，可以使用<code>docker info</code>命令查看配置是否生效，在输出信息中找到 “Registry Mirrors” 字段，确认其值为配置的镜像加速地址 。之后再使用<code>docker pull</code>命令下载镜像，速度应该会有明显提升 。</p></section><section><h3>容器启动失败<a href="#容器启动失败"><span>#</span></a></h3><ul>
<li>
<p><strong>问题描述</strong>：使用<code>docker run</code>命令启动容器时，容器无法正常启动，可能会出现报错信息 。</p>
</li>
<li>
<p><strong>原因分析</strong>：容器启动失败的原因可能有很多，常见的包括镜像损坏、容器配置错误、端口冲突、依赖服务未启动等 。</p>
</li>
<li>
<p><strong>解决方法</strong>：</p>
<ul>
<li>
<p><strong>检查镜像完整性</strong>：首先，使用<code>docker images</code>命令查看本地镜像列表，确认要启动容器的镜像是否存在且完整 。如果镜像损坏，可以尝试重新下载或重新构建镜像 。例如，如果怀疑<code>nginx:latest</code>镜像有问题，可以先删除该镜像（<code>docker rmi nginx:latest</code>），然后重新下载（<code>docker pull nginx:latest</code>） 。</p>
</li>
<li>
<p><strong>检查容器配置</strong>：仔细检查<code>docker run</code>命令的参数是否正确，例如端口映射是否合理、容器名称是否重复等 。如果使用了<code>Dockerfile</code>构建镜像并启动容器，还要检查<code>Dockerfile</code>中的指令是否正确，例如工作目录是否设置正确、应用启动命令是否正确等 。</p>
</li>
<li>
<p><strong>检查端口冲突</strong>：如果在启动容器时指定了端口映射（如<code>-p 8080:80</code>），而该端口在主机上已经被其他进程占用，就会导致容器启动失败 。可以使用<code>netstat</code>命令或<code>lsof</code>命令检查端口占用情况 。以<code>netstat</code>命令为例，在 Linux 系统中，可以执行<code>netstat -tunlp | grep 8080</code>命令查看 8080 端口的占用情况 。如果发现端口被占用，可以修改容器的端口映射，或者停止占用该端口的进程 。</p>
</li>
<li>
<p><strong>检查依赖服务</strong>：如果容器依赖其他服务（如数据库、消息队列等），确保这些依赖服务已经正常启动并可以被容器访问 。例如，一个 Web 应用容器可能依赖 MySQL 数据库，在启动 Web 应用容器之前，要确保 MySQL 数据库已经正常运行，并且 Web 应用容器的数据库连接配置正确 。可以通过在容器内使用<code>ping</code>命令或其他工具测试对依赖服务的连通性 。如果是因为依赖服务未启动导致容器启动失败，先启动依赖服务，然后再尝试启动容器 。</p>
</li>
</ul>
</li>
</ul></section></section><section><h2>总结与展望<a href="#总结与展望"><span>#</span></a></h2><p>通过本文，我们全面了解了 Docker 这一强大的容器化技术，从它的基本概念、安装方法，到镜像操作、容器管理以及数据卷的使用，还通过一个 Flask Web 应用的实战案例，完整地体验了使用 Docker 进行应用部署的流程 。同时，我们也探讨了在使用过程中可能遇到的问题及解决办法 。</p><p>Docker 的出现，极大地改变了传统的应用部署和运维模式，它以其环境一致性、快速部署、高效资源利用等优势，成为了现代软件开发和运维的必备工具 。无论是开发个人项目，还是构建企业级的大型应用，Docker 都能为我们提供更加便捷、高效的解决方案 。</p><p>对于各位读者，希望你们能将所学的 Docker 知识运用到实际项目中 。在实践的过程中，不断探索 Docker 的更多高级特性和应用场景，例如使用 Docker Compose 进行多容器应用的编排，结合 Kubernetes 实现容器的自动化管理和集群部署等 。相信随着对 Docker 的深入了解和使用，它会为你的工作和学习带来意想不到的便利和效率提升 。</p><p>展望未来，随着云计算、大数据、人工智能等技术的不断发展，Docker 作为容器化技术的代表，将在这些领域发挥更加重要的作用 。在云计算中，Docker 将助力实现更加灵活、高效的云原生应用部署和管理；在大数据处理中，Docker 可以为不同的数据处理框架和工具提供统一的运行环境，提高数据处理的效率和可靠性；在人工智能领域，Docker 能够方便地部署和管理深度学习模型，加速模型的训练和推理过程 。可以预见，Docker 的应用前景将更加广阔，它将继续推动技术的创新和发展 。让我们一起期待 Docker 在未来带给我们更多的惊喜！</p><blockquote><p>（注：文档部分内容可能由 AI 生成）</p></blockquote></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/97c4431/</id>
      <title type="text">服务器安全管理不用愁！Jumpserver 开源堡垒机，企业级安全解决方案</title>
      <published>2026-04-11T18:31:13.000Z</published>
      <updated>2026-04-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/97c4431/"/>
      <summary type="text">今天我要给大家推荐一个超好用的开源堡垒机——**Jumpserver**，它开源免费、功能强大，而且部署简单，是企业级服务器安全管理的理想选择！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！服务器安全管理太头疼？<a href="#朋友们服务器安全管理太头疼"><span>#</span></a></h2><p>今天我要给大家推荐一个超好用的开源堡垒机——<strong>Jumpserver</strong>，它开源免费、功能强大，而且部署简单，是企业级服务器安全管理的理想选择！</p></section>
<section><h2>什么是 Jumpserver？<a href="#什么是-jumpserver"><span>#</span></a></h2><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/41ecd44d36c940d2800bdc6c1c49e39820260411204428241.png" alt="" />
Jumpserver 是国内开源的企业级堡垒机项目，专注于解决企业服务器访问安全管理问题。它就像服务器的”安全门卫”，统一管理所有服务器的访问权限，记录所有操作行为，让服务器管理变得既安全又高效。</p></section>
<section><h2>为什么推荐 Jumpserver？<a href="#为什么推荐-jumpserver"><span>#</span></a></h2><section><h3>1️⃣ 开源免费，零成本使用<a href="#1️⃣-开源免费零成本使用"><span>#</span></a></h3><p>Jumpserver 完全开源，免费使用，企业不需要为高昂的商业堡垒机 license 发愁，大大降低了企业的 IT 成本。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/18cd9b6275a04533951de8a3028a8ccb20260411204539425.png" alt="" /></p></section><section><h3>2️⃣ 统一认证，单点登录<a href="#2️⃣-统一认证单点登录"><span>#</span></a></h3><p>支持 LDAP、Radius、OAuth 等多种认证方式，实现单点登录，不用再记一堆账号密码，登录一次就能访问所有服务器。</p></section><section><h3>3️⃣ 细粒度权限控制<a href="#3️⃣-细粒度权限控制"><span>#</span></a></h3><p>基于用户、用户组、资产、资产组的四维度权限管理，精确控制谁能访问哪些服务器，权限设置非常灵活。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/78c48a2d065a4d62a32fc8812a117b6920260411205852154.png" alt="" /></p></section><section><h3>4️⃣ 完整审计，合规无忧<a href="#4️⃣-完整审计合规无忧"><span>#</span></a></h3><p>操作日志、命令记录、录像回放，所有操作都有迹可循，满足金融、政府等行业的严格合规要求。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/2a0beafdf18e44cdbe008d220afbdb4120260411205659448.png" alt="" /></p></section><section><h3>5️⃣ 多协议支持<a href="#5️⃣-多协议支持"><span>#</span></a></h3><p>SSH、RDP、Telnet、VNC 等多种协议统一管理，不管是什么类型的服务器，都能通过 Jumpserver 统一访问。</p></section><section><h3>6️⃣ 多云支持<a href="#6️⃣-多云支持"><span>#</span></a></h3><p>适配各种云环境和混合云架构，不管你的服务器在哪个云平台，都能统一管理。</p></section><section><h3>7️⃣ 安全加固<a href="#7️⃣-安全加固"><span>#</span></a></h3><p>支持 MFA、IP 限制、会话管理等安全措施，进一步提升服务器访问的安全性。</p></section></section>
<section><h2>如何部署 Jumpserver？<a href="#如何部署-jumpserver"><span>#</span></a></h2><ol>
<li>准备一台干净的 Linux 服务器 ( 64 位, &gt;= 4c8g )</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>curl</span><span> </span><span>-sSL</span><span> </span><span>https://github.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh</span><span> | </span><span>bash</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>在浏览器中访问 JumpServer，地址为 <a href="http://your-jumpserver-ip/" target="_blank">http://your-jumpserver-ip/</a></li>
</ol><ul>
<li>用户名: admin</li>
<li>密码: ChangeMe</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/d4aecc4249294f02bfa14c8668cea250640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></p><p>通过测试来看，Jumpserver 的功能非常强大，操作也很简单。呵呵是不是很实用？</p><p>最重要的是，Jumpserver 解决了传统服务器管理的安全痛点，让服务器管理变得既安全又高效，这一点真的很贴心！</p></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>企业 IT 运维团队</strong>：管理大量服务器的访问权限</li>
<li><strong>金融行业</strong>：需要满足严格的审计和合规要求</li>
<li><strong>DevOps 团队</strong>：为开发和运维提供安全的服务器访问通道</li>
<li><strong>多云环境</strong>：统一管理不同云平台的服务器资源</li>
<li><strong>远程办公</strong>：为远程办公提供安全的服务器访问方式</li>
</ul></section>
<section><h2>项目资源<a href="#项目资源"><span>#</span></a></h2><p>如果你对 Jumpserver 感兴趣，可以访问以下资源：</p><p><strong>GitHub地址</strong>: <a href="https://github.com/jumpserver/jumpserver" target="_blank">https://github.com/jumpserver/jumpserver</a></p><p>觉得项目不错可以点个赞。</p><p><strong>官方网站</strong>: <a href="https://www.jumpserver.org/" target="_blank">https://www.jumpserver.org/</a></p><p><strong>在线文档</strong>: <a href="https://docs.jumpserver.org/" target="_blank">https://docs.jumpserver.org/</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时是如何管理服务器的？使用 Jumpserver 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=102365809&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="http://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2046857375&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/a74d4930/</id>
      <title type="text">不用买Mac！飞牛NAS用 Docker 跑 macOS，当云电脑用真香！</title>
      <published>2026-04-11T18:31:13.000Z</published>
      <updated>2026-04-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/a74d4930/"/>
      <summary type="text">大家好呀～今天要给你们分享一个超酷的玩法！你是不是也想体验 macOS 系统，但又不想花大价钱买 Mac？或者偶尔需要用一下 Mac 环境，却没有设备？别着急，今天教你一个神操作——**用飞牛NAS + Docker 跑 macOS**，直接把 macOS 装进容器里，随时随地当云电脑用！</summary>
      <content type="html"><![CDATA[<p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/8914750e38e04acdbea280b873dfa408640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></p>
<section><h2>哈喽，小伙伴们！<a href="#哈喽小伙伴们"><span>#</span></a></h2><p>大家好呀～今天要给你们分享一个超酷的玩法！</p><p>你是不是也想体验 macOS 系统，但又不想花大价钱买 Mac？或者偶尔需要用一下 Mac 环境，却没有设备？</p><p>别着急，今天教你一个神操作——<strong>用飞牛NAS + Docker 跑 macOS</strong>，直接把 macOS 装进容器里，随时随地当云电脑用！</p></section>
<section><h2>为什么要这么玩？<a href="#为什么要这么玩"><span>#</span></a></h2><p>对于喜欢折腾 NAS、服务器或者开发环境的朋友来说，这种方式真的太香了：</p><ul>
<li>✅ <strong>省钱</strong>：不用买昂贵的 Mac 设备</li>
<li>✅ <strong>灵活</strong>：随时随地通过网络访问</li>
<li>✅ <strong>多用途</strong>：测试 macOS 软件、远程办公、开发环境</li>
<li>✅ <strong>好玩</strong>：体验一下把 macOS 装进容器的乐趣</li>
</ul></section>
<section><h2>飞牛 Docker 部署步骤<a href="#飞牛-docker-部署步骤"><span>#</span></a></h2><section><h3>1️⃣ 准备工作<a href="#1️⃣-准备工作"><span>#</span></a></h3><p>首先，我们需要创建一个文件夹，用来存放 docker-compose.yml 文件和相关配置。</p></section><section><h3>2️⃣ 部署容器<a href="#2️⃣-部署容器"><span>#</span></a></h3><p>打开 Docker，点击侧栏的「Compose」→「新增项目」→输入项目名称→设置路径选择刚才创建的文件夹→创建 docker-compose.yml 文件，把下面的代码复制进去：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>macos</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image</span><span>: </span><span>dockurr/macos</span></div></div><div><div><div>4</div></div><div><span>    </span><span>container_name</span><span>: </span><span>macos</span></div></div><div><div><div>5</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>6</div></div><div><span>      </span><span># CPU核心数（不得超出物理机总核心数）</span></div></div><div><div><div>7</div></div><div><span>      </span><span>CPU_CORES</span><span>: </span><span>"4"</span></div></div><div><div><div>8</div></div><div><span>      </span><span># macOS版本：</span></div></div><div><div><div>9</div></div><div><span>      </span><span>#     15  macOS 15  Sequoia</span></div></div><div><div><div>10</div></div><div><span>      </span><span>#     14  macOS 14  Sonoma</span></div></div><div><div><div>11</div></div><div><span>      </span><span>#     13  macOS 13  Ventura</span></div></div><div><div><div>12</div></div><div><span>      </span><span>#     12  macOS 12  Monterey</span></div></div><div><div><div>13</div></div><div><span>      </span><span>#     11  macOS 11  Big Sur</span></div></div><div><div><div>14</div></div><div><span>      </span><span>VERSION</span><span>: </span><span>"12"</span></div></div><div><div><div>15</div></div><div><span>      </span><span># 磁盘大小（单位G，必须携带）</span></div></div><div><div><div>16</div></div><div><span>      </span><span>DISK_SIZE</span><span>: </span><span>"60G"</span></div></div><div><div><div>17</div></div><div><span>      </span><span># 内存大小（单位G，必须携带）</span></div></div><div><div><div>18</div></div><div><span>      </span><span>RAM_SIZE</span><span>: </span><span>"8G"</span></div></div><div><div><div>19</div></div><div><span>    </span><span>devices</span><span>:</span></div></div><div><div><div>20</div></div><div><span><span>      </span></span><span>- </span><span>/dev/kvm</span></div></div><div><div><div>21</div></div><div><span><span>      </span></span><span>- </span><span>/dev/net/tun</span></div></div><div><div><div>22</div></div><div><span>    </span><span>cap_add</span><span>:</span></div></div><div><div><div>23</div></div><div><span><span>      </span></span><span>- </span><span>NET_ADMIN</span></div></div><div><div><div>24</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>25</div></div><div><span>      </span><span># 8006为 Web vnc 端口，5900为vnc端口</span></div></div><div><div><div>26</div></div><div><span>      </span><span># 修改端口仅改动冒号左侧，如：12345:8006</span></div></div><div><div><div>27</div></div><div><span><span>      </span></span><span>- </span><span>8006:8006</span></div></div><div><div><div>28</div></div><div><span><span>      </span></span><span>- </span><span>5900:5900/tcp</span></div></div><div><div><div>29</div></div><div><span><span>      </span></span><span>- </span><span>5900:5900/udp</span></div></div><div><div><div>30</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>31</div></div><div><span>        </span><span># macos为自己建的目录，挂载本地文件夹到容器，用于存储 macOS 系统文件</span></div></div><div><div><div>32</div></div><div><span><span>      </span></span><span>- </span><span>./macos:/storage</span></div></div><div><div><div>33</div></div><div><span>    </span><span>restart</span><span>: </span><span>always</span></div></div><div><div><div>34</div></div><div><span>    </span><span>stop_grace_period</span><span>: </span><span>2m</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>3️⃣ 查看部署进度<a href="#3️⃣-查看部署进度"><span>#</span></a></h3><p>构建完成后，去容器查看日志进度，当看到相关提示后，就可以在浏览器访问 <strong>ip&lt;8006&gt;</strong> 进入 web 端查看下载进度啦！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/abc01388cdbf44018ec25ae2d684483b640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></p></section><section><h3>4️⃣ 系统安装设置<a href="#4️⃣-系统安装设置"><span>#</span></a></h3><p>接下来就是 macOS 的安装过程，按照以下步骤操作：</p><ol>
<li><strong>选择语言</strong>：设置为中文
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/35d8de60227446828c58728ed94f72d5640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></li>
<li><strong>磁盘工具</strong>：双击打开磁盘工具
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/b16ad323a0274b8ab5ec8918878cb5a2640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></li>
<li><strong>格式化磁盘</strong>：选择最大容量的 Apple Inc. VirtIO Block Media 磁盘，点击抹掉，格式化为 APFS
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/b16ad323a0274b8ab5ec8918878cb5a2640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></li>
<li><strong>安装系统</strong>：关闭磁盘工具，双击重新安装 macOS Monterey
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/7970bb9a167e4dc8b3b8dac653728508640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></li>
<li><strong>完成设置</strong>：一路点击继续，选择刚才格式化的磁盘，耐心等待安装完成
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/cfe2bb6064c947f3ba1b403c7b33779f640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></li>
</ol></section></section>
<section><h2>实际使用体验<a href="#实际使用体验"><span>#</span></a></h2><p>部署完成后，你就拥有了一台可以远程访问的 macOS 云电脑！</p><ul>
<li><strong>流畅度</strong>：虽然通过网络访问，但是基本的日常使用完全没问题</li>
<li><strong>功能</strong>：可以安装各种 macOS 软件，满足基本需求</li>
<li><strong>便捷性</strong>：随时随地通过浏览器访问，不用携带设备</li>
</ul></section>
<section><h2>小提示<a href="#小提示"><span>#</span></a></h2><ul>
<li>部署时注意设置合适的磁盘大小，空间不够会导致部署失败</li>
<li>安装过程可能需要 1 小时左右，取决于你的存储设备速度</li>
</ul></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>用飞牛 NAS + Docker 跑 macOS，真的是一个既省钱又实用的方案！</p><p>不用花大价钱买 Mac，就能随时体验 macOS 系统，对于开发者、设计师或者只是想尝鲜的朋友来说，都是一个不错的选择。</p><p>你也可以把它当作一台云电脑，随时随地通过网络访问，处理一些需要 macOS 环境的任务。</p><p>感兴趣的小伙伴赶紧试试吧！如果遇到问题，欢迎在评论区留言讨论～</p><hr /><p><strong>互动时间</strong>：你最想在这台 macOS 云电脑上做什么？欢迎在评论区分享你的想法！</p><p>（注：文章部分图片来源于网络，如有侵权请联系删除）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/bf7c6035/</id>
      <title type="text">2026最新整理！这几款观影软件太香了，电影爱好者福音！</title>
      <published>2026-04-11T18:31:13.000Z</published>
      <updated>2026-04-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/bf7c6035/"/>
      <summary type="text">最近后台有好多读者问我：&quot;小王，有没有好用的看电影软件推荐？&quot;、&quot;片荒了，有没有什么好的观影工具？&quot;。</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！最近好多人问我要观影软件，安排上了！<a href="#朋友们最近好多人问我要观影软件安排上了"><span>#</span></a></h2><p>最近后台有好多读者问我：“小王，有没有好用的看电影软件推荐？”、“片荒了，有没有什么好的观影工具？”。</p><p>为了满足大家的需求，我花了几天时间整理了一波好用的观影软件，涵盖了不同平台、不同需求，现在分享给大家！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/7ad0484e3b7f4913b6bd9298615c096f20260410170802548.png" alt="" /></p></section>
<section><h2>整理的观影软件有哪些？<a href="#整理的观影软件有哪些"><span>#</span></a></h2><p>这次整理的观影软件包括：</p><ul>
<li><strong>Android 平台</strong>：适合安卓手机、平板用户的观影软件</li>
<li><strong>TV 端</strong>：适合智能电视、机顶盒用户的观影软件</li>
</ul></section>
<section><h2>为什么推荐这些软件？<a href="#为什么推荐这些软件"><span>#</span></a></h2><section><h3>1️⃣ 资源丰富<a href="#1️⃣-资源丰富"><span>#</span></a></h3><p>整理的软件涵盖了多种影视资源，包括电影、电视剧、动漫、综艺等，满足不同人的需求。</p></section><section><h3>2️⃣ 界面美观<a href="#2️⃣-界面美观"><span>#</span></a></h3><p>这些软件的界面设计都很美观，操作简单，用户体验良好。</p></section><section><h3>3️⃣ 播放流畅<a href="#3️⃣-播放流畅"><span>#</span></a></h3><p>大多数软件都支持多种清晰度选择，播放流畅，不会卡顿。</p></section><section><h3>4️⃣ 免费使用<a href="#4️⃣-免费使用"><span>#</span></a></h3><p>整理的软件都是免费使用的，不需要付费订阅。</p></section><section><h3>5️⃣ 安全可靠<a href="#5️⃣-安全可靠"><span>#</span></a></h3><p>我对每款软件都进行了测试，确保安全可靠，不会有恶意广告或插件。</p></section></section>
<section><h2>如何获取这些软件？<a href="#如何获取这些软件"><span>#</span></a></h2><p>我已经将整理好的软件打包上传到了 123 云盘，大家可以通过以下链接下载：
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/b70a8d8c8d5e435892deed953a95fbb320260410171540073.png" alt="" />
<strong>分享地址</strong>：<a href="https://www.123684.com/s/lIPjjv-yzKid?pwd=5O1T#" target="_blank">https://www.123684.com/s/lIPjjv-yzKid?pwd=5O1T#</a></p><p><strong>提取码</strong>：5O1T</p></section>
<section><h2>使用方法<a href="#使用方法"><span>#</span></a></h2><section><h3>步骤1：下载并安装软件<a href="#步骤1下载并安装软件"><span>#</span></a></h3><ol>
<li>点击上面的分享链接，输入提取码 5O1T</li>
<li>下载压缩包到本地</li>
<li>解压压缩包，里面包含了所有软件和使用说明</li>
<li>根据自己的设备类型选择对应的软件</li>
<li>安装软件到设备上</li>
</ol></section><section><h3>步骤2：配置源（以XMBOX为例）<a href="#步骤2配置源以xmbox为例"><span>#</span></a></h3><ol>
<li>
<p><strong>打开XMBOX应用</strong></p>
<ul>
<li>安装完成后，打开XMBOX应用
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/24ff0f77621b4667a3f09845687286f420260410170835681.png" alt="" /></li>
</ul>
</li>
<li>
<p><strong>进入设置界面</strong></p>
<ul>
<li>手机版：点击右上角的设置图标</li>
<li>TV版：使用遥控器导航到设置选项
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/270af7c24c73490eb999c5efb5ddecd820260410170917778.png" alt="" /></li>
</ul>
</li>
<li>
<p><strong>添加源</strong></p>
<ul>
<li>找到”配置”或”源管理”选项</li>
<li>点击”添加源”或”配置源”</li>
<li>在输入框中粘贴源地址</li>
<li>点击”确定”或”保存”按钮</li>
</ul>
</li>
<li>
<p><strong>开始使用</strong></p>
<ul>
<li>返回主界面，即可看到加载的影视资源</li>
<li>选择你想看的电影或电视剧开始观看</li>
</ul>
</li>
</ol><blockquote><p>其他观影软件的配置方法类似,本次这些软件都是多仓版本,输入多仓的源即可使用。如果你没有可用的源，可以私信小王发送【观影源】获取最新源地址，这些源小王都会定期更新的，建议大家保持关注哈。</p></blockquote></section></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ol>
<li>请在合法范围内使用这些软件，支持正版影视</li>
<li>部分软件可能需要网络环境支持，请确保网络畅通</li>
<li>如遇到软件无法使用的情况，可以在评论区留言，我会尽力解答</li>
<li>软件可能会定期更新，请关注最新版本</li>
<li>源地址可能会失效，需要定期更新源地址</li>
<li><strong>重要：部分源内有广告，请勿相信广告，请勿点击不明链接！！！</strong></li>
</ol></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时都用什么软件看电影？有什么好的观影软件推荐？使用我分享的软件后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p></section>
<section><h2>温馨提示<a href="#温馨提示"><span>#</span></a></h2><p>观影虽好，也要注意休息哦！建议大家合理安排观影时间，保护好眼睛。</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/tanNrcdkfexsT6pNm9035Q?token=102365809&amp;lang=zh_CN" target="_blank">解决GitHub访问慢的神器！fetch-github-hosts 让你秒开GitHub</a></li>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=102365809&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="http://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2046857375&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a>
（注：文章部分信息来源于个人整理和测试）</li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/fb714caf/</id>
      <title type="text">服务器运维新革命！GMSSH 桌面级AI运维系统，让小白也能轻松管理服务器</title>
      <published>2026-04-11T18:31:13.000Z</published>
      <updated>2026-04-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/fb714caf/"/>
      <summary type="text">今天我要给大家推荐一个超级好用的服务器运维工具——**GMSSH**，它是一个桌面级 AI 运维系统，让服务器管理变得可视化、智能化，即使是运维小白也能轻松上手！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！服务器运维太复杂？这个工具让运维变得超简单！<a href="#朋友们服务器运维太复杂这个工具让运维变得超简单"><span>#</span></a></h2><p>前几天有读者在后台问我：“小王，有没有什么好用的服务器管理工具推荐？“，作为一个经常需要管理服务器的人，我太懂这种感受了——传统的命令行操作太复杂，新手根本看不懂，而且容易出错。</p><p>今天我要给大家推荐一个超级好用的服务器运维工具——<strong>GMSSH</strong>，它是一个桌面级 AI 运维系统，让服务器管理变得可视化、智能化，即使是运维小白也能轻松上手！</p></section>
<section><h2>什么是 GMSSH？<a href="#什么是-gmssh"><span>#</span></a></h2><p>GMSSH 是一款桌面级 AI 运维系统，专为 Linux 服务器设计，通过 SSH 可视化管理工具，让服务器运维变得简单高效。它结合了桌面 GUI 和 AI 智能引导，让新手也能秒懂服务器状态，通过拖拽式操作轻松完成复杂任务。</p></section>
<section><h2>为什么推荐 GMSSH？<a href="#为什么推荐-gmssh"><span>#</span></a></h2><section><h3>1️⃣ 可视化桌面界面<a href="#1️⃣-可视化桌面界面"><span>#</span></a></h3><p>GMSSH 提供了直观的桌面界面，让服务器管理变得可视化：</p><ul>
<li>拖拽上传下载，就像操作本地文件夹</li>
<li>右键压缩/解压，支持 tar.gz、zip 等主流格式</li>
<li>双击在线编辑，语法高亮 + 自动保存</li>
<li>可视化权限管理，点击即改</li>
</ul></section><section><h3>2️⃣ AI 智能运维<a href="#2️⃣-ai-智能运维"><span>#</span></a></h3><p>这是 GMSSH 最具革命性的功能！通过自然语言交互，智能解析运维需求，自动执行命令、实时监控资源、精准定位问题，实现高效运维。</p><p>比如你可以直接说：</p><ul>
<li>“帮我部署一个 WordPress 网站”</li>
<li>“查看系统资源使用情况”</li>
<li>“优化服务器性能”</li>
</ul><p>AI 会自动帮你完成这些操作！</p></section><section><h3>3️⃣ 零侵入设计<a href="#3️⃣-零侵入设计"><span>#</span></a></h3><p>GMSSH 的设计非常轻量：</p><ul>
<li>等同原生命令行，不装代理</li>
<li>不开端口，不占资源</li>
<li>无需在服务器安装，直接通过 SSH 连接即可使用</li>
</ul></section><section><h3>4️⃣ 安全可靠<a href="#4️⃣-安全可靠"><span>#</span></a></h3><p>基于原生 SSH 通道，融合 MFA 多因素认证与全链路审计，安全无妥协，合规即就绪。复用现有密钥，通信全程防窃听、防篡改。</p></section><section><h3>5️⃣ 监控运维一体<a href="#5️⃣-监控运维一体"><span>#</span></a></h3><p>实时监控进程与系统资源，精准掌握 CPU、内存、磁盘、网络状态，低耗稳定连接，高负载下依旧流畅运行。</p></section></section>
<section><h2>主要功能<a href="#主要功能"><span>#</span></a></h2><section><h3>文件管理<a href="#文件管理"><span>#</span></a></h3><ul>
<li>拖拽上传下载文件</li>
<li>右键压缩/解压文件</li>
<li>在线编辑文件</li>
<li>可视化权限管理</li>
</ul></section><section><h3>用户管理<a href="#用户管理"><span>#</span></a></h3><ul>
<li>Linux 用户管理</li>
<li>SSH 配置与证书管理</li>
<li>DNS 设置</li>
<li>精细权限控制</li>
</ul></section><section><h3>系统监控<a href="#系统监控"><span>#</span></a></h3><ul>
<li>实时监控进程与系统资源</li>
<li>精准掌握 CPU、内存、磁盘、网络状态</li>
<li>低耗稳定连接</li>
</ul></section><section><h3>AI 智能运维<a href="#ai-智能运维"><span>#</span></a></h3><ul>
<li>自然语言交互</li>
<li>智能解析运维需求</li>
<li>自动执行命令</li>
<li>实时监控资源</li>
<li>精准定位问题</li>
</ul></section></section>
<section><h2>如何使用 GMSSH？<a href="#如何使用-gmssh"><span>#</span></a></h2><section><h3>步骤1：下载安装<a href="#步骤1下载安装"><span>#</span></a></h3><ol>
<li>访问 GMSSH 官网：<a href="https://www.gmssh.com/" target="_blank">https://www.gmssh.com/</a></li>
<li>下载适合你系统的安装包</li>
<li>运行安装程序，按照提示完成安装</li>
</ol></section><section><h3>步骤2：连接服务器<a href="#步骤2连接服务器"><span>#</span></a></h3><ol>
<li>打开 GMSSH 应用</li>
<li>点击”添加服务器”按钮</li>
<li>输入服务器 IP 地址、用户名和密码</li>
<li>点击”连接”按钮</li>
<li>等待连接成功</li>
</ol></section><section><h3>步骤3：开始管理<a href="#步骤3开始管理"><span>#</span></a></h3><p>连接成功后，你就可以通过可视化界面管理服务器了：</p><ul>
<li>拖拽文件进行上传下载</li>
<li>双击文件进行在线编辑</li>
<li>使用 AI 助手执行运维任务</li>
<li>查看系统资源使用情况</li>
</ul></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>使用 GMSSH 后，服务器管理变得非常简单：</p><ol>
<li><strong>可视化操作</strong>：不需要记住复杂的命令行，通过界面就能完成大部分操作</li>
<li><strong>AI 智能助手</strong>：遇到问题时可以直接问 AI，它会帮你分析和解决</li>
<li><strong>零侵入设计</strong>：不需要在服务器上安装任何额外软件</li>
<li><strong>安全可靠</strong>：基于 SSH 连接，安全有保障</li>
<li><strong>监控全面</strong>：可以实时查看系统资源使用情况</li>
</ol><p>相比之下，之前使用传统的命令行工具时，我需要记住各种命令，而且容易出错，现在通过 GMSSH 的可视化界面，一切都变得简单多了。</p></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>运维新手</strong>：不熟悉命令行操作的新手</li>
<li><strong>服务器管理员</strong>：需要管理多台服务器的管理员</li>
<li><strong>开发者</strong>：需要经常部署和管理应用的开发者</li>
<li><strong>任何人</strong>：需要管理 Linux 服务器的人</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 GMSSH 感兴趣，可以访问它的 GitHub 仓库：<a href="https://github.com/GMSSH/GMSSH" target="_blank">https://github.com/GMSSH/GMSSH</a></p></section>
<section><h2>官网地址<a href="#官网地址"><span>#</span></a></h2><p>你可以直接访问 GMSSH 的官网下载使用：<a href="https://www.gmssh.com/" target="_blank">https://www.gmssh.com/</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时是如何管理服务器的？使用过 GMSSH 吗？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="%E9%93%BE%E6%8E%A5">发现宝藏音乐播放器！MusicFree 让你告别广告和会员</a></li>
<li><a href="%E9%93%BE%E6%8E%A5">音乐自动化神器！Melody Hub 让你躺着听新歌</a></li>
<li><a href="%E9%93%BE%E6%8E%A5">解决GitHub访问慢的神器！fetch-github-hosts 让你秒开GitHub</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/2960131f/</id>
      <title type="text">NAS 玩家福音！Tugtainer 自动更新容器，告别繁琐操作</title>
      <published>2026-03-11T18:31:13.000Z</published>
      <updated>2026-03-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/2960131f/"/>
      <summary type="text">我的nas上部署了太多的容器，有用的没用的好几页，每次镜像更新都会比较苦恼，所以我就想有没有一个软件可以自动更新我的容器镜像？终于找到了一个工具，那就是 Tugtainer，大家有和我一样想法的一起来看看吧</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！NAS 上的容器更新太麻烦？我找到了解决方案！<a href="#朋友们nas-上的容器更新太麻烦我找到了解决方案"><span>#</span></a></h2><p>我的nas上部署了太多的容器，有用的没用的好几页，每次镜像更新都会比较苦恼，所以我就想有没有一个软件可以自动更新我的容器镜像？终于找到了一个工具，那就是 Tugtainer，大家有和我一样想法的一起来看看吧
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/bc262b4dbaf24cbc8085aedf06e513fd20260414172831836.png" alt="" /></p></section>
<section><h2>什么是 Tugtainer？<a href="#什么是-tugtainer"><span>#</span></a></h2><section><h3>Tugtainer<a href="#tugtainer"><span>#</span></a></h3><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/9240abf8b7ed4e4a9490fc5c66b683b420260414164342375.png" alt="" />
yt-dlp-webui 是一个为 yt-dlp 设计的网页界面，它允许你通过简单的 web UI 从各种平台下载视频和音频。它被设计为自托管的，意味着你可以在自己的服务器或电脑上运行它，更加安全和私密。</p></section></section>
<section><h2>为什么选择 Tugtainer？<a href="#为什么选择-tugtainer"><span>#</span></a></h2><section><h3>1️⃣ 有直观的 Web UI<a href="#1️⃣-有直观的-web-ui"><span>#</span></a></h3><p>这是 Tugtainer 最大的优势！Watchtower 是一个纯命令行工具，没有任何界面，你无法直观地看到哪些容器需要更新，更新状态如何。而 Tugtainer 提供了一个美观的 Web UI，让你可以：</p><ul>
<li>一目了然地看到所有容器的状态</li>
<li>手动触发更新</li>
<li>查看更新历史</li>
<li>配置更新策略</li>
</ul></section><section><h3>2️⃣ 更灵活的更新策略<a href="#2️⃣-更灵活的更新策略"><span>#</span></a></h3><p>Tugtainer 允许你为每个容器设置不同的更新策略，比如：</p><ul>
<li>自动更新</li>
<li>手动更新</li>
<li>忽略更新</li>
</ul><p>而 Watchtower 只能设置全局的更新策略，无法针对单个容器进行配置。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/24648f23664c4d259b4eded698b0fc5320260414164524047.png" alt="" /></p></section><section><h3>3️⃣ 通知功能<a href="#3️⃣-通知功能"><span>#</span></a></h3><p>Tugtainer 支持通过 Apprise 发送通知，当容器更新完成或失败时，你会收到通知。而 Watchtower 的通知功能相对简单。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/56006d64e07c4b77b9b5e56eb36dd6cf20260414164604169.png" alt="" /></p></section><section><h3>4️⃣ 更详细的更新历史<a href="#4️⃣-更详细的更新历史"><span>#</span></a></h3><p>Tugtainer 会记录详细的更新历史，你可以查看每个容器的更新记录，了解更新时间、版本变化等信息。而 Watchtower 只能通过日志查看更新情况，不够直观。</p></section><section><h3>5️⃣ 支持多服务器管理<a href="#5️⃣-支持多服务器管理"><span>#</span></a></h3><p>如果你有多个 Docker 服务器，Tugtainer 可以通过代理统一管理，而 Watchtower 只能管理单个服务器上的容器。</p></section></section>
<section><h2>如何部署 Tugtainer？<a href="#如何部署-tugtainer"><span>#</span></a></h2><section><h3>使用 Docker Compose 部署<a href="#使用-docker-compose-部署"><span>#</span></a></h3><ol>
<li><strong>创建 docker-compose.yml 文件</strong>
<ul>
<li>在一个空文件夹中创建 docker-compose.yml 文件</li>
<li>复制以下内容到文件中：</li>
</ul>
</li>
</ol><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>version</span><span>: </span><span>'3.8'</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>services</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>tugtainer</span><span>:</span></div></div><div><div><div>5</div></div><div><span>    </span><span>image</span><span>: </span><span>quenary/tugtainer:latest</span></div></div><div><div><div>6</div></div><div><span>    </span><span>container_name</span><span>: </span><span>tugtainer</span></div></div><div><div><div>7</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>8</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>- </span><span>"18890:80"</span></div></div><div><div><div>10</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>- </span><span>/var/run/docker.sock:/var/run/docker.sock:ro</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>- </span><span>./data:/tugtainer</span></div></div><div><div><div>13</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>14</div></div><div><span><span>      </span></span><span>- </span><span>TZ=Asia/Shanghai</span></div></div><div><div><div>15</div></div><div><span>    </span><span>networks</span><span>:</span></div></div><div><div><div>16</div></div><div><span><span>      </span></span><span>- </span><span>tugtainer_net</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>networks</span><span>:</span></div></div><div><div><div>19</div></div><div><span>  </span><span>tugtainer_net</span><span>:</span></div></div><div><div><div>20</div></div><div><span>    </span><span>driver</span><span>: </span><span>bridge</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><ol>
<li>
<p><strong>启动服务</strong></p>
<ul>
<li>在文件夹目录下执行命令：<code>docker-compose up -d</code></li>
<li>等待服务启动完成</li>
</ul>
</li>
<li>
<p><strong>访问 Web UI</strong></p>
<ul>
<li>打开浏览器，访问 <code>http://localhost:3000</code></li>
<li>你将看到 Tugtainer 的 Web 界面</li>
</ul>
</li>
</ol></section></section>
<section><h2>如何使用 Tugtainer？<a href="#如何使用-tugtainer"><span>#</span></a></h2><section><h3>1. 查看容器状态<a href="#1-查看容器状态"><span>#</span></a></h3><ul>
<li>登录 Tugtainer Web UI</li>
<li>在首页查看所有容器的状态，包括当前版本、可用版本等
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/1be7d591fd11438d8f2b3a5742384f5220260414164946639.png" alt="" /></li>
</ul></section><section><h3>2. 手动触发更新<a href="#2-手动触发更新"><span>#</span></a></h3><ul>
<li>在容器列表中，找到需要更新的容器</li>
<li>点击 “更新” 按钮</li>
<li>等待更新完成
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/aa5fb11a5e494ec382ee57ffd11e918c20260414164412704.png" alt="" /></li>
</ul></section><section><h3>3. 配置更新策略<a href="#3-配置更新策略"><span>#</span></a></h3><ul>
<li>点击容器名称进入详情页</li>
<li>在 “更新策略” 中设置自动更新、手动更新或忽略更新</li>
<li>点击 “保存” 按钮</li>
</ul></section><section><h3>4. 查看更新历史<a href="#4-查看更新历史"><span>#</span></a></h3><ul>
<li>在左侧菜单中点击 “历史”</li>
<li>查看所有容器的更新历史</li>
<li>点击具体更新记录查看详细信息
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/d6752fbe20dc49209c7e30faf0f206b420260414172343118.png" alt="" /></li>
</ul></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>使用 Tugtainer 后，我 NAS 上的容器管理变得非常简单：</p><ol>
<li><strong>一目了然</strong>：通过 Web UI 可以清晰地看到所有容器的状态</li>
<li><strong>操作便捷</strong>：可以手动触发更新，也可以设置自动更新</li>
<li><strong>灵活配置</strong>：可以为每个容器设置不同的更新策略</li>
<li><strong>通知及时</strong>：更新完成后会收到通知，不用时刻关注</li>
<li><strong>历史记录</strong>：可以查看详细的更新历史，了解容器的版本变化</li>
</ol><p>相比之下，之前使用 Watchtower 时，我只能通过命令行查看日志，无法直观地了解容器状态，也无法针对单个容器设置更新策略，非常不方便。</p></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>NAS 用户</strong>：拥有多个容器需要管理的 NAS 用户</li>
<li><strong>Docker 爱好者</strong>：喜欢使用 Docker 部署各种服务的用户</li>
<li><strong>服务器管理员</strong>：管理多个 Docker 服务器的管理员</li>
<li><strong>任何人</strong>：需要自动更新 Docker 容器的人</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><ul>
<li><strong>Tugtainer</strong>：<a href="https://github.com/Quenary/tugtainer" target="_blank">https://github.com/Quenary/tugtainer</a></li>
<li><strong>Watchtower</strong>：<a href="https://github.com/containrrr/watchtower" target="_blank">https://github.com/containrrr/watchtower</a></li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时是如何管理 NAS 上的容器的？使用过 Tugtainer 或 Watchtower 吗？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=1317674859&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/h_JXMjqBLO3ts9voz9qMsQ?token=1317674859&amp;lang=zh_CN" target="_blank">发现宝藏阅读软件！Legado 让你告别书源限制，一个软件看遍所有网络小说</a></li>
<li><a href="https://mp.weixin.qq.com/s/tanNrcdkfexsT6pNm9035Q?token=1317674859&amp;lang=zh_CN" target="_blank">解决GitHub访问慢的神器！fetch-github-hosts 让你秒开GitHub</a></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/465a1c16/</id>
      <title type="text">TVBox 源聚合神器！一个地址看遍全网资源，还能自动测速去重</title>
      <published>2026-03-11T18:31:13.000Z</published>
      <updated>2026-03-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/465a1c16/"/>
      <summary type="text">今天我要给大家推荐一个超级好用的开源项目——**TVBox Source Aggregator**，它是一个 TVBox 源聚合器，能将多个配置源合并成一个稳定的聚合地址，还能自动测速筛选、站点级去重，让你的追剧体验更稳定！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！TVBox 源总是失效？这个工具让你的追剧体验更稳定！<a href="#朋友们tvbox-源总是失效这个工具让你的追剧体验更稳定"><span>#</span></a></h2><p>前几天有朋友问我：“小王，TVBox 的源总是失效，有没有什么办法让它更稳定？“，作为一个资深 TVBox 用户，我太懂这种感受了——刚找到一个好用的源，没几天就失效了，又要到处找新源，简直让人崩溃。</p><p>今天我要给大家推荐一个超级好用的开源项目——<strong>TVBox Source Aggregator</strong>，它是一个 TVBox 源聚合器，能将多个配置源合并成一个稳定的聚合地址，还能自动测速筛选、站点级去重，让你的追剧体验更稳定！</p><p>这两天我用了之后简直爱不释手，今天就来和大家唠唠这个神奇的工具，看看它是怎么解决 TVBox 源不稳定的问题的。</p></section>
<section><h2>项目介绍<a href="#项目介绍"><span>#</span></a></h2><p><strong>TVBox Source Aggregator</strong> 是一个专为 TVBox 设计的源聚合工具，它的核心价值在于：<strong>将多个 TVBox 配置源合并成一个稳定的聚合地址，自动处理源的问题</strong>。</p><section><h3>✨ 核心特性<a href="#-核心特性"><span>#</span></a></h3><ul>
<li><strong>🚀 多源聚合</strong>：添加多个 TVBox 配置 JSON 地址，自动合并为一个</li>
<li><strong>🔍 站点去重</strong>：不同源中的相同站点只保留一份，避免重复内容</li>
<li><strong>🧠 Spider JAR 智能分配</strong>：自动处理 type&lt;3&gt; 站点的 JAR 依赖冲突</li>
<li><strong>⚡ 测速筛选</strong>：自动过滤不可达或高延迟的源，保证流畅体验</li>
<li><strong>💻 管理后台</strong>：网页端添加/删除源，触发刷新，操作简单</li>
<li><strong>⏰ 定时更新</strong>：每天自动重新聚合，客户端无感知</li>
<li><strong>🛡️ 容错设计</strong>：聚合失败时保留上次有效缓存，确保服务不中断</li>
</ul></section><section><h3>🛠️ 技术栈<a href="#️-技术栈"><span>#</span></a></h3>

<table><thead><tr><th>类别</th><th>技术/组件</th><th>说明</th></tr></thead><tbody><tr><td>后端</td><td>Node.js</td><td>核心运行环境</td></tr><tr><td>框架</td><td>Hono</td><td>HTTP 路由框架</td></tr><tr><td>存储</td><td>SQLite / JSON 文件 / Cloudflare KV</td><td>数据存储</td></tr><tr><td>部署</td><td>Docker / Cloudflare Worker / 本地运行</td><td>多种部署方式</td></tr><tr><td>语言</td><td>TypeScript</td><td>类型安全的代码</td></tr></tbody></table></section><section><h3>🎯 应用场景<a href="#-应用场景"><span>#</span></a></h3><ul>
<li><strong>家庭观影</strong>：在智能电视上使用 TVBox，享受稳定的视频源</li>
<li><strong>个人追剧</strong>：在手机上使用 TVBox，随时随地看剧</li>
<li><strong>源管理</strong>：集中管理多个 TVBox 源，避免源失效的困扰</li>
<li><strong>技术爱好者</strong>：自建服务，掌控自己的观影体验</li>
</ul></section></section>
<section><h2>部署实战<a href="#部署实战"><span>#</span></a></h2><section><h3>部署方式一：Docker（推荐）<a href="#部署方式一docker推荐"><span>#</span></a></h3><p>对于有服务器或 NAS 的用户，Docker 部署是最方便的方式：</p><ol>
<li>
<p><strong>克隆仓库</strong>：</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://gitee.com/tengxiaobao/tvbox-source-aggregator.git</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>tvbox-source-aggregator</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p><strong>配置环境变量</strong>：</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cp</span><span> </span><span>.env.example</span><span> </span><span>.env</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>编辑 <code>.env</code> 文件，至少修改 <code>ADMIN_TOKEN</code> 为你的管理密码</p>
</li>
<li>
<p><strong>启动容器</strong>：</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p><strong>访问管理后台</strong>：
打开 <code>http://你的IP:5678/admin</code>，输入密码登录管理</p>
</li>
</ol></section><section><h3>部署方式二：一键脚本<a href="#部署方式二一键脚本"><span>#</span></a></h3><p>适合没有 Docker 但有 Node.js 环境的用户：</p><ol>
<li>
<p><strong>克隆仓库</strong>：</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://gitee.com/tengxiaobao/tvbox-source-aggregator.git</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>tvbox-source-aggregator</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p><strong>一键启动</strong>：</p>
<ul>
<li><strong>Mac 用户</strong>：双击 <code>start.command</code> 文件</li>
<li><strong>Windows 用户</strong>：双击 <code>start.bat</code> 文件</li>
<li><strong>命令行用户</strong>：运行 <code>node scripts/start.js</code></li>
</ul>
</li>
<li>
<p><strong>后台运行</strong>（可选）：</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 使用 pm2</span></div></div><div><div><div>2</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>-g</span><span> </span><span>pm2</span></div></div><div><div><div>3</div></div><div><span>pm2</span><span> </span><span>start</span><span> </span><span>scripts/start.js</span><span> </span><span>--name</span><span> </span><span>tvbox</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ol></section><section><h3>部署方式三：Cloudflare Worker（免费）<a href="#部署方式三cloudflare-worker免费"><span>#</span></a></h3><p>不需要自己的服务器，完全免费：</p><ol>
<li>
<p><strong>准备环境</strong>：</p>
<ul>
<li>Cloudflare 账号（免费）</li>
<li>Node.js 18+</li>
</ul>
</li>
<li>
<p><strong>克隆仓库</strong>：</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://gitee.com/tengxiaobao/tvbox-source-aggregator.git</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>tvbox-source-aggregator</span></div></div><div><div><div>3</div></div><div><span>npm</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/23c59c78b2434b749fbf02102ce05d8c20260420140934338.png" alt="" /></p><ol>
<li><strong>登录 Cloudflare</strong>：
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npx</span><span> </span><span>wrangler</span><span> </span><span>login</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/1f2ad342b3f942e98d73329c70679b8520260420141005137.png" alt="" /></p><ol>
<li><strong>创建 KV 存储</strong>：
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npx</span><span> </span><span>wrangler</span><span> </span><span>kv</span><span> </span><span>namespace</span><span> </span><span>create</span><span> </span><span>KV</span></div></div><div><div><div>2</div></div><div><span>npx</span><span> </span><span>wrangler</span><span> </span><span>kv</span><span> </span><span>namespace</span><span> </span><span>create</span><span> </span><span>KV</span><span> </span><span>--preview</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/a3bbb854c2a3488183de0ef8414b6ae320260420141049114.png" alt="" /></p><ol>
<li><strong>设置密码</strong>：
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 记得 your-admin-password 改为你自己的密码</span></div></div><div><div><div>2</div></div><div><span>echo</span><span> </span><span>"your-admin-password"</span><span> | </span><span>npx</span><span> </span><span>wrangler</span><span> </span><span>secret</span><span> </span><span>put</span><span> </span><span>ADMIN_TOKEN</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/d4f697cf49374526b4593fe1d752e94f20260420141118496.png" alt="" /></p><ol>
<li><strong>部署</strong>：
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>run</span><span> </span><span>deploy</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/bfeebd60368d43339bce67ed3d09d53c20260420141323542.png" alt="" /></p><ol>
<li>自定义域名（推荐）</li>
</ol><p>Workers 默认的 <code>*.workers.dev</code> 域名在部分网络环境下不可直接访问。如果你有托管在 Cloudflare 的域名：</p><ol>
<li>在 Cloudflare DNS 添加记录：<code>AAAA tvbox 100::</code> （已代理）</li>
<li>取消 <code>wrangler.toml</code> 中 <code>routes</code> 的注释，填入你的域名和 Zone ID</li>
</ol></section></section>
<section><h2>使用指南<a href="#使用指南"><span>#</span></a></h2><section><h3>添加源<a href="#添加源"><span>#</span></a></h3><ol>
<li><strong>登录管理后台</strong>：打开 <code>http://你的地址/admin</code>，输入密码</li>
<li><strong>添加源</strong>：在输入框中填入 TVBox 配置 JSON URL，点击 Add</li>
<li><strong>管理源</strong>：可以删除不需要的源，或点击 Refresh 触发一次聚合
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/24d6f077029e4ec58df2d6120bd242bf20260420141653724.png" alt="" /></li>
</ol></section><section><h3>TVBox 配置<a href="#tvbox-配置"><span>#</span></a></h3><p>将你的聚合地址填入 TVBox 的接口地址：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>http://你的地址:5678/</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>端点说明<a href="#端点说明"><span>#</span></a></h3>

<table><thead><tr><th>端点</th><th>说明</th></tr></thead><tbody><tr><td><code>/</code></td><td>TVBox 配置 JSON（客户端填这个地址）</td></tr><tr><td><code>/status</code></td><td>监控仪表盘页面</td></tr><tr><td><code>/admin</code></td><td>管理后台（密码保护）</td></tr></tbody></table></section></section>
<section><h2>我的使用感受<a href="#我的使用感受"><span>#</span></a></h2><p>作为一个资深 TVBox 用户，我必须说 TVBox Source Aggregator 彻底改变了我的追剧体验。以前我总是为了源失效而发愁：</p><ul>
<li>要么是刚找到的源没几天就失效了</li>
<li>要么是多个源之间重复内容太多</li>
<li>要么是有些源速度太慢，播放卡顿</li>
</ul><p>现在有了 TVBox Source Aggregator，一切都变得超级简单：</p><ol>
<li><strong>稳定可靠</strong>：多个源聚合，一个失效了还有其他的，再也不用担心源失效的问题</li>
<li><strong>自动去重</strong>：不同源中的相同站点只保留一份，界面更整洁</li>
<li><strong>智能测速</strong>：自动过滤高延迟的源，保证播放流畅</li>
<li><strong>管理方便</strong>：网页端管理后台，添加删除源超级简单</li>
<li><strong>多种部署方式</strong>：不管是有服务器还是没有服务器，都能找到适合自己的部署方式</li>
</ol><p>前几天我用它部署了一个聚合源，添加了5个不同的 TVBox 源，聚合后的地址非常稳定，播放也很流畅，简直不要太香！</p></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>今天和大家分享了 TVBox Source Aggregator 这个开源项目，它通过聚合多个 TVBox 配置源，解决了 TVBox 源不稳定的问题。无论是自动去重、智能测速还是多种部署方式，都让我们的追剧体验变得更加稳定和流畅。</p><p>TVBox Source Aggregator 的核心优势在于：多源聚合提高稳定性、站点去重避免重复内容、Spider JAR 智能分配解决依赖冲突、测速筛选保证流畅体验、管理后台操作简单、定时更新客户端无感知、容错设计确保服务不中断。</p><p>无论是家庭观影、个人追剧还是源管理，TVBox Source Aggregator 都能满足你的需求。最重要的是，它完全开源免费，让每个人都能享受稳定的 TVBox 观影体验。</p></section>
<section><h2>项目资源<a href="#项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>：<a href="https://github.com/qq148376839/tvbox-source-aggregator" target="_blank">https://github.com/qq148376839/tvbox-source-aggregator</a>
<strong>Gitee地址</strong>：<a href="https://gitee.com/tengxiaobao/tvbox-source-aggregator" target="_blank">https://gitee.com/tengxiaobao/tvbox-source-aggregator</a></p><p>觉得项目不错的话，记得给作者点个star支持一下！</p><p><strong>项目特色</strong>：TVBox 源聚合器，将多个配置源合并成一个稳定的聚合地址，支持自动测速筛选、站点级去重、Spider JAR 智能分配，提供多种部署方式。</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你是不是已经跃跃欲试了？赶紧按照文中的步骤部署 TVBox Source Aggregator，体验稳定的 TVBox 观影体验吧！</p><p>如果你用了之后有什么有趣的体验，或者有什么问题，欢迎在评论区和我交流。我会定期分享更多好用的开源工具，记得关注我哦！</p><p>今天的分享就到这里结束了，我们下一篇文章见。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/6dc54909/</id>
      <title type="text">闲鱼卖家福音！AI自动值守神器，真正拥有“睡后收入”</title>
      <published>2026-03-11T18:31:13.000Z</published>
      <updated>2026-03-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/6dc54909/"/>
      <summary type="text">今天我要给大家推荐一个超级神器——**Xianyu AutoAgent**，它能7×24小时帮你自动值守闲鱼，智能回复消息，甚至还能帮你谈价格，彻底解放你的双手！</summary>
      <content type="html"><![CDATA[<section><h2>小王发现了一个超好用的闲鱼自动化工具！<a href="#小王发现了一个超好用的闲鱼自动化工具"><span>#</span></a></h2><p>今天我要给大家推荐一个超级神器——<strong>Xianyu AutoAgent</strong>，它能7×24小时帮你自动值守闲鱼，智能回复消息，甚至还能帮你谈价格，彻底解放你的双手！</p></section>
<section><h2>什么是 Xianyu AutoAgent？<a href="#什么是-xianyu-autoagent"><span>#</span></a></h2><p>Xianyu AutoAgent 是一个专为闲鱼平台打造的AI自动化值守解决方案，基于大模型实现，能实现7×24小时全天候自动化运营，支持智能对话、自动议价等功能。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/771b1cad1abe47afa7c446d012e7dd1b20260413091645225.png" alt="" /></p></section>
<section><h2>为什么推荐 Xianyu AutoAgent？<a href="#为什么推荐-xianyu-autoagent"><span>#</span></a></h2><section><h3>1️⃣ 7×24小时自动值守<a href="#1️⃣-724小时自动值守"><span>#</span></a></h3><p>不管你是在上班、睡觉还是出去玩，Xianyu AutoAgent 都能帮你实时回复买家消息，不错过任何一个潜在客户。</p></section><section><h3>2️⃣ 智能议价功能<a href="#2️⃣-智能议价功能"><span>#</span></a></h3><p>它能根据你设置的价格策略，自动与买家进行议价，既不会让你吃亏，又能提高成交率。</p></section><section><h3>3️⃣ 多场景对话支持<a href="#3️⃣-多场景对话支持"><span>#</span></a></h3><p>无论是技术问题、价格问题还是其他咨询，Xianyu AutoAgent 都能应对自如，提供专业的回复。</p></section><section><h3>4️⃣ 人工接管随时切换<a href="#4️⃣-人工接管随时切换"><span>#</span></a></h3><p>当遇到复杂问题时，你可以随时接管对话，处理完后再交给AI继续值守。</p></section><section><h3>5️⃣ 简单部署，轻松上手<a href="#5️⃣-简单部署轻松上手"><span>#</span></a></h3><p>只需要通过 Docker 部署，配置好相关参数，就能立即开始使用。</p></section></section>
<section><h2>前期准备<a href="#前期准备"><span>#</span></a></h2><p>在使用 Xianyu AutoAgent 之前，你需要准备以下东西：</p><section><h3>1. AI模型密钥<a href="#1-ai模型密钥"><span>#</span></a></h3><p>推荐使用硅基流动（国内访问稳定），注册后系统会自动赠送16元代金卷，足够体验使用了。</p><ul>
<li>注册地址：<a href="https://cloud.siliconflow.cn/i/xpMprZk4" target="_blank">https://cloud.siliconflow.cn/i/xpMprZk4</a></li>
<li>注册后进入【控制台】→【密钥】，点击”创建密钥”</li>
<li>复制保存生成的密钥（类似”sk-xxxxxx”的字符串）
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/01cdf619cd84410eadc70b416d60790720260413091851504.png" alt="" /></li>
<li>记录一下要使用的模型id（类似”deepseek-ai/DeepSeek-V3.2”）
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/ba3168556c1b4f369ad31a25d2e4216220260413092404989.png" alt="" /></li>
</ul></section><section><h3>2. 闲鱼Cookie<a href="#2-闲鱼cookie"><span>#</span></a></h3><ul>
<li>浏览器登录闲鱼官网：<a href="https://www.goofish.com/" target="_blank">https://www.goofish.com/</a></li>
<li>按 F12 打开开发者工具</li>
<li>转到 Network → 刷新页面 → 找到 Cookie</li>
<li>复制完整的 Cookie 字符串备用
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/f20925ac83064ccd9374c36fc62ed55120260413092139919.png" alt="" /></li>
</ul></section></section>
<section><h2>部署步骤<a href="#部署步骤"><span>#</span></a></h2><section><h3>方法一：Docker Compose 部署<a href="#方法一docker-compose-部署"><span>#</span></a></h3><ol>
<li>
<p><strong>创建目录</strong></p>
<ul>
<li>新建一个文件夹，用于存储配置文件和数据</li>
</ul>
</li>
<li>
<p><strong>创建 docker-compose.yml 文件</strong></p>
<ul>
<li>在文件夹中创建 docker-compose.yml 文件</li>
<li>复制以下内容到文件中：</li>
</ul>
</li>
</ol><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>XianyuAutoAgent</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image</span><span>: </span><span>shaxiu/xianyuautoagent:latest</span></div></div><div><div><div>4</div></div><div><span>    </span><span>container_name</span><span>: </span><span>xianyuautoagent</span></div></div><div><div><div>5</div></div><div><span>    </span><span>restart</span><span>: </span><span>always</span></div></div><div><div><div>6</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>./data:/app/data</span></div></div><div><div><div>8</div></div><div><span><span>      </span></span><span>- </span><span>./prompts:/app/prompts</span></div></div><div><div><div>9</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>10</div></div><div><span><span>      </span></span><span>- </span><span>TZ=Asia/Shanghai</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>- </span><span>API_KEY=sk-xxxxxxxxxxxxxx</span><span>  </span><span># 替换为你的硅基流动密钥</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>- </span><span>COOKIES_STR=xxxxxxxxxxxxxx</span><span>  </span><span># 替换为你的闲鱼Cookie</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span>- </span><span>MODEL_BASE_URL=https://api.siliconflow.cn/v1</span><span>  </span><span># 替换为你的模型基础URL</span></div></div><div><div><div>14</div></div><div><span><span>      </span></span><span>- </span><span>MODEL_NAME=deepseek-ai/DeepSeek-V3.2</span><span> </span><span># 替换为你的模型名称</span></div></div><div><div><div>15</div></div><div><span><span>      </span></span><span>- </span><span>TOGGLE_KEYWORDS=。</span><span>  </span><span># 切换关键词，用于人工接管</span></div></div><div><div><div>16</div></div><div><span><span>      </span></span><span>- </span><span>SIMULATE_HUMAN_TYPING=False</span><span>  </span><span># 模拟人工输入延迟，默认为False，True为开启</span></div></div><div><div><div>17</div></div><div><span>networks</span><span>:</span></div></div><div><div><div>18</div></div><div><span>  </span><span>xianyu-network</span><span>:</span></div></div><div><div><div>19</div></div><div><span>    </span><span>driver</span><span>: </span><span>bridge</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><ol>
<li><strong>启动服务</strong>
<ul>
<li>在文件夹目录下执行命令：<code>docker-compose up -d</code></li>
<li>等待服务启动完成</li>
</ul>
</li>
</ol></section><section><h3>方法二：NAS 部署<a href="#方法二nas-部署"><span>#</span></a></h3><p>如果你的 NAS 支持 Docker，也可以在 NAS 上部署 Xianyu AutoAgent，这样就能24小时稳定运行。</p></section></section>
<section><h2>提示词配置<a href="#提示词配置"><span>#</span></a></h2><p>Xianyu AutoAgent 使用4个提示词模板文件来指导AI回复不同类型的问题：</p><ul>
<li><code>classify_prompt.txt</code> - 分类提示词，用于识别用户意图</li>
<li><code>price_prompt.txt</code> - 价格相关提示词，用于回答价格问题</li>
<li><code>tech_prompt.txt</code> - 技术相关提示词，用于回答技术问题</li>
<li><code>default_prompt.txt</code> - 默认提示词，用于回答其他类型问题</li>
</ul><p>你可以根据自己的业务需求，修改这些提示词模板，让AI回复更加符合你的风格。</p></section>
<section><h2>使用体验<a href="#使用体验"><span>#</span></a></h2><p>部署完成后，Xianyu AutoAgent 会自动连接到闲鱼的服务器，开始工作。当买家给你发消息时，AI会自动回复，甚至可以帮你谈价格。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/1cb9a5452a3240a3a1e317a681e0467d20260413092548843.png" alt="" />
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/fbcbbf6b625344ef884499648777b36a20260413092559808.png" alt="" />
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/0a07f64961474e73b564eea6e885b13620260413092612126.png" alt="" /></p><section><h3>实时监控<a href="#实时监控"><span>#</span></a></h3><p>你可以通过查看日志，实时监控AI与买家的对话情况，了解AI的表现。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/d585f64c653444b595e4bc5ed14561d920260413092756551.png" alt="" /></p></section><section><h3>人工接管<a href="#人工接管"><span>#</span></a></h3><p>当遇到AI无法处理的复杂问题时，你可以在闲鱼聊天框输入”。“（中文句号），切换到人工模式，处理完后再次输入”。“，切换回AI模式。</p></section></section>
<section><h2>常见问题<a href="#常见问题"><span>#</span></a></h2><ol>
<li>Cookie有效期多久？</li>
</ol><ul>
<li>Cookie存在有效期，因此可能需要一星期（可能更久，以实际为准）重新更新一下cookie，cookie过期后控制台的日志会输出error告诉你是什么问题；</li>
<li>之前cookie过期以后会自动更新续期，但是最近闲鱼加强了风控，因此遇到哎呦喂挤爆了，即为触发风控，需要过滑块更新cookie</li>
</ul><ol>
<li>可以多账号部署嘛？</li>
</ol><ul>
<li>直接多开程序即可，复制多个程序文件夹，每个文件夹中的cookie为不同的账号的即可</li>
</ul><ol>
<li>支持本地大模型嘛？</li>
</ol><ul>
<li>通过ollama部署模型直接调用即可，.env文件中修改 模型名称 和 模型地址</li>
</ul><ol>
<li>报错：哎呦喂，挤爆了</li>
</ol><ul>
<li>解决办法：关闭程序-进入闲鱼网页版-点击消息-过滑块-重新获取cookie，将最新的cookie粘贴到env文件中</li>
</ul></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>闲鱼卖家</strong>：想要解放双手，提高运营效率</li>
<li><strong>兼职卖家</strong>：没有太多时间盯店</li>
<li><strong>多店运营</strong>：需要同时管理多个闲鱼账号</li>
<li><strong>新手卖家</strong>：不知道如何回复买家问题</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 Xianyu AutoAgent 感兴趣，可以访问它的 GitHub 仓库：<a href="https://github.com/shaxiu/XianyuAutoAgent" target="_blank">https://github.com/shaxiu/XianyuAutoAgent</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时在闲鱼卖货时遇到过什么问题？使用 Xianyu AutoAgent 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/LCN8quv3VG3MPd54vXv2ig?token=1317674859&amp;lang=zh_CN" target="_blank">音乐爱好者福音！MiMusic 自托管个人音乐服务器，简单自由又强大</a></li>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=1317674859&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/PetBOJ-4waImUBYpdeU_fw?token=1317674859&amp;lang=zh_CN" target="_blank">2026最新整理！这几款观影软件太香了，电影爱好者福音！附下载地址</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/7853fe77/</id>
      <title type="text">音乐爱好者福音！MiMusic 自托管个人音乐服务器，简单自由又强大</title>
      <published>2026-03-11T18:31:13.000Z</published>
      <updated>2026-03-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/7853fe77/"/>
      <summary type="text">今天我要给大家推荐一个超好用的自托管个人音乐服务器——**MiMusic**，它简单、自由、插件化，支持 6 个平台，让你随时随地享受自己的音乐！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！还在为音乐管理发愁？<a href="#朋友们还在为音乐管理发愁"><span>#</span></a></h2><p>今天我要给大家推荐一个超好用的自托管个人音乐服务器——<strong>MiMusic</strong>，它简单、自由、插件化，支持 6 个平台，让你随时随地享受自己的音乐！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/925ef7dc62164af0b65830130767fa8820260412124026312.png" alt="" /></p></section>
<section><h2>什么是 MiMusic？<a href="#什么是-mimusic"><span>#</span></a></h2><p>MiMusic 是一个自托管个人音乐服务器，专注于提供简单、自由的音乐管理和播放体验。它由 Go 语言编写，轻量高效，适合在 NAS、树莓派等低功耗设备上运行。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/f591d5601f6b40c2b1133a57c6d44a6420260412124349756.png" alt="" /></p></section>
<section><h2>为什么推荐 MiMusic？<a href="#为什么推荐-mimusic"><span>#</span></a></h2><section><h3>1️⃣ 本地音乐管理<a href="#1️⃣-本地音乐管理"><span>#</span></a></h3><p>扫描本地目录，自动提取 MP3/FLAC/WAV/APE/OGG/M4A 等格式的封面和元数据，让你的音乐库井井有条。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/0cff8386e8b14d4fad2fca86807a4fa920260412124450872.png" alt="" /></p></section><section><h3>2️⃣ WASM 插件体系<a href="#2️⃣-wasm-插件体系"><span>#</span></a></h3><p>WebAssembly 沙箱运行，支持多种扩展插件，功能无限扩展。</p></section></section>
<section><h2>🧩 插件合集<a href="#-插件合集"><span>#</span></a></h2><p>MiMusic 提供了丰富的插件，让你的音乐服务器功能更加强大：</p><section><h3>1. 音乐标签刮削<a href="#1-音乐标签刮削"><span>#</span></a></h3><p><strong>版本</strong>：2026.4.6
<strong>描述</strong>：从其他平台提取歌曲元数据（标题、专辑、艺术家、歌词、封面）
<strong>作者</strong>：MiMusic Team
<strong>下载地址</strong>：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://github.com/mimusic-org/mimusic-plugin-musictag/releases/download/v2026.4.6/musictag.wasm.zip</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这个插件可以自动为你的音乐文件添加完整的元数据，让你的音乐库更加规范和美观。</p></section><section><h3>2. Cloudflared 隧道<a href="#2-cloudflared-隧道"><span>#</span></a></h3><p><strong>版本</strong>：2026.4.10
<strong>描述</strong>：通过 Cloudflare Tunnel 将本地 MiMusic 服务暴露到公网，支持 cloudflared 的下载和管理
<strong>作者</strong>：MiMusic Team
<strong>下载地址</strong>：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://github.com/mimusic-org/mimusic-plugin-cloudflared/releases/download/v2026.4.10/cloudflared.wasm.zip</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>有了这个插件，你可以在任何地方访问你的音乐服务器，无需复杂的网络配置。</p></section><section><h3>3. 小米音箱插件<a href="#3-小米音箱插件"><span>#</span></a></h3><p><strong>版本</strong>：2026.4.10
<strong>描述</strong>：提供小米账号登录和小爱音箱控制功能，支持多账号管理
<strong>作者</strong>：MiMusic Team
<strong>下载地址</strong>：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://github.com/mimusic-org/plugins/releases/download/plugin-xiaomi-2026.4.10/xiaomi.wasm.zip</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>通过这个插件，你可以将 MiMusic 与你的小米音箱集成，用语音控制音乐播放。</p></section><section><h3>4. 洛雪音源<a href="#4-洛雪音源"><span>#</span></a></h3><p><strong>版本</strong>：2026.4.10
<strong>描述</strong>：管理洛雪音源，搜索和导入网络歌曲
<strong>作者</strong>：MiMusic Team
<strong>下载地址</strong>：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://github.com/mimusic-org/mimusic-plugin-lxmusic/releases/download/v2026.4.10/lxmusic.wasm.zip</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这个插件让你可以搜索和导入网络歌曲，丰富你的音乐库。</p></section><section><h3>如何安装插件<a href="#如何安装插件"><span>#</span></a></h3><ol>
<li>访问 MiMusic Web 界面</li>
<li>进入 “插件管理” 页面</li>
<li>点击 “上传插件” 按钮</li>
<li>选择下载好的插件文件（.wasm.zip 格式）</li>
<li>等待插件安装完成</li>
<li>启用插件并配置相关参数</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/899c5e37243341edacd02c7739aa1abf20260412191545705.png" alt="" /></p></section><section><h3>3️⃣ 跨平台客户端<a href="#3️⃣-跨平台客户端"><span>#</span></a></h3><p>Flutter 客户端支持 Android、iOS、macOS、Windows、Linux、Web 六端，随时随地听音乐。</p></section><section><h3>4️⃣ Web 界面<a href="#4️⃣-web-界面"><span>#</span></a></h3><p>完整版内置 Web 前端，开箱即用，无需额外配置。</p></section><section><h3>6️⃣ 网络歌曲 &amp; 电台<a href="#6️⃣-网络歌曲--电台"><span>#</span></a></h3><p>支持添加网络歌曲和网络电台，丰富你的音乐来源。</p></section><section><h3>8️⃣ 轻量高效<a href="#8️⃣-轻量高效"><span>#</span></a></h3><p>Go 编写，CGO-free，无外部依赖，适合 NAS / 树莓派等低功耗设备。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/ab7d8ce99b31426192166e48d8c99e6b20260412124531818.png" alt="" /></p></section></section>
<section><h2>MiMusic 版本说明<a href="#mimusic-版本说明"><span>#</span></a></h2><p>MiMusic 提供两种版本，满足不同使用场景：</p>

<table><thead><tr><th>版本</th><th>说明</th><th>适用场景</th></tr></thead><tbody><tr><td>完整版-full</td><td>包含 Web 前端，开箱即用</td><td>推荐初次使用，访问服务地址即可看到 Web 界面</td></tr><tr><td>精简版</td><td>不包含 Web 前端，体积更小</td><td>配合 Flutter 桌面/移动客户端，或前后端分离部署</td></tr></tbody></table><p><strong>推荐</strong>：初次使用建议下载 完整版（-full），开箱即用，无需额外配置前端。</p></section>
<section><h2>如何部署 MiMusic？<a href="#如何部署-mimusic"><span>#</span></a></h2><section><h3>方式一：直接运行二进制文件<a href="#方式一直接运行二进制文件"><span>#</span></a></h3><p><strong>Linux / macOS</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 1️⃣ 下载对应平台的二进制文件（推荐完整版）</span></div></div><div><div><div>2</div></div><div><span># 例如 Linux x86_64 完整版:</span></div></div><div><div><div>3</div></div><div><span>wget</span><span> </span><span>https://github.com/mimusic-org/mimusic/releases/latest/download/mimusic-linux-amd64-full</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># 2️⃣ 添加执行权限</span></div></div><div><div><div>6</div></div><div><span>chmod</span><span> </span><span>+x</span><span> </span><span>mimusic-linux-amd64-full</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span># 3️⃣ 创建必要目录</span></div></div><div><div><div>9</div></div><div><span>mkdir</span><span> </span><span>-p</span><span> </span><span>music</span><span> </span><span>data</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span># 4️⃣ 运行</span></div></div><div><div><div>12</div></div><div><span>./mimusic-linux-amd64-full</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>Windows</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 1️⃣ 下载对应平台的二进制文件（推荐完整版）</span></div></div><div><div><div>2</div></div><div><span># 例如 Windows x86_64 完整版: mimusic-windows-amd64-full.exe</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 2️⃣ 创建必要目录</span></div></div><div><div><div>5</div></div><div><span>mkdir music</span></div></div><div><div><div>6</div></div><div><span>mkdir </span><span>data</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span># 3️⃣ 运行</span></div></div><div><div><div>9</div></div><div><span>.</span><span>imusic-windows-amd64-full.exe</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://mypicture-1258720957.cos.ap-nanjing.myqcloud.com/image-20260412-100002.png" alt="二进制部署" /><figcaption>二进制部署</figcaption></figure><p></p></section><section><h3>方式二：Docker 部署<a href="#方式二docker-部署"><span>#</span></a></h3><p><strong>从 Docker Hub 拉取（推荐）</strong></p><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 🌟 拉取完整版镜像（推荐，包含 Web 前端）</span></div></div><div><div><div>2</div></div><div><span>version:</span><span> </span><span>'3.8'</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>services:</span></div></div><div><div><div>5</div></div><div><span>  </span><span>mimusic:</span></div></div><div><div><div>6</div></div><div><span>    </span><span>image:</span><span> </span><span>hanxi/mimusic:full</span></div></div><div><div><div>7</div></div><div><span>    </span><span>container_name:</span><span> </span><span>mimusic</span></div></div><div><div><div>8</div></div><div><span>    </span><span>restart:</span><span> </span><span>always</span></div></div><div><div><div>9</div></div><div><span>    </span><span>ports:</span></div></div><div><div><div>10</div></div><div><span>      </span><span>-</span><span> </span><span>"58091:58091"</span></div></div><div><div><div>11</div></div><div><span>    </span><span>volumes:</span></div></div><div><div><div>12</div></div><div><span>      </span><span># 音乐文件目录（你可以改成自己的真实路径）</span></div></div><div><div><div>13</div></div><div><span>      </span><span>-</span><span> </span><span>./music:/app/music</span></div></div><div><div><div>14</div></div><div><span>      </span><span># 数据配置目录</span></div></div><div><div><div>15</div></div><div><span>      </span><span>-</span><span> </span><span>./data:/app/data</span></div></div><div><div><div>16</div></div><div><span>    </span><span>environment:</span></div></div><div><div><div>17</div></div><div><span>      </span><span>-</span><span> </span><span>ADMIN_USERNAME=admin</span></div></div><div><div><div>18</div></div><div><span>      </span><span>-</span><span> </span><span>ADMIN_PASSWORD=your_secure_password</span><span>  </span><span># 记得改成你自己的密码</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/604cf745f1144f3387f00c4c363175f420260412190258692.png" alt="" /></p></section><section><h3>配置说明<a href="#配置说明"><span>#</span></a></h3><p><strong>环境变量</strong></p>

<table><thead><tr><th>变量名</th><th>说明</th><th>默认值</th></tr></thead><tbody><tr><td>ADMIN_USERNAME</td><td>管理员用户名</td><td>admin</td></tr><tr><td>ADMIN_PASSWORD</td><td>管理员密码</td><td>admin</td></tr><tr><td>LISTEN_PORT</td><td>服务端口</td><td>58091</td></tr><tr><td>MUSIC_PATH</td><td>音乐文件路径</td><td>./music</td></tr><tr><td>DATA_PATH</td><td>数据存储路径</td><td>./data</td></tr></tbody></table></section><section><h3>访问服务<a href="#访问服务"><span>#</span></a></h3><p>服务启动后，通过以下方式访问：</p><p><strong>Web 界面</strong>：<a href="http://%E6%9C%8D%E5%8A%A1%E5%99%A8IP:58091" target="_blank">http://服务器IP:58091</a></p><p><strong>API 文档</strong>：<a href="http://%E6%9C%8D%E5%8A%A1%E5%99%A8IP:58091/api/docs" target="_blank">http://服务器IP:58091/api/docs</a></p><p><strong>默认账号</strong>：admin / admin（首次登录后请修改密码）</p></section><section><h3>上传音乐<a href="#上传音乐"><span>#</span></a></h3><p>将你的音乐文件复制到音乐目录（默认为 <code>./music</code>），MiMusic 会自动扫描并添加到音乐库。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 上传音乐文件到服务器</span></div></div><div><div><div>2</div></div><div><span>scp</span><span> </span><span>-r</span><span> </span><span>/path/to/your/music/</span><span>*</span><span> </span><span>root@服务器IP:/path/to/music/</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>测试验证<a href="#测试验证"><span>#</span></a></h3><p><strong>登录系统</strong></p><p>使用默认账号登录 MiMusic Web 界面。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/8308ec3060d34856aceaa651f29de2b420260412190422278.png" alt="" /></p><p><strong>浏览音乐库</strong></p><p>查看自动扫描的音乐文件。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/4769b44d200f40d2bac6754c24eb7eb520260412190658505.png" alt="" /></p><p><strong>多设备测试</strong></p><p>在不同设备上测试 MiMusic 的跨平台功能。</p></section><section><h3>移动端<a href="#移动端"><span>#</span></a></h3><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/60d524d35a37451794b1ccf51e9c657920260412191023764.png" alt="" /></p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/3b6c19addf6d46339902d227b9ca71ac20260412191036574.png" alt="" /></p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/ae09e1560a744ddfb916c1129a9b266620260412191059376.png" alt="" /></p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/bb304b0228254306880939af42ea5d7320260412191118759.png" alt="" /></p></section><section><h3>平板<a href="#平板"><span>#</span></a></h3><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/a16ea16059ae4bb08bf19c543336ab1b20260412191135290.png" alt="" /></p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/60ab3a4b3c4746e591c14125565589f420260412191151959.png" alt="" /></p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/c5858af741434e019f6d8cee820894d520260412191207163.png" alt="" /></p><p>通过测试来看，MiMusic 的功能非常强大，部署也很简单。呵呵是不是很实用？</p></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>前几天我试用了 MiMusic，体验真的非常好：</p><ol>
<li><strong>部署简单</strong>：无论是直接运行二进制文件还是 Docker 部署，都非常方便</li>
<li><strong>界面美观</strong>：Web 界面设计现代简约，操作直观</li>
<li><strong>功能丰富</strong>：本地音乐管理、网络歌曲、电台等功能应有尽有</li>
<li><strong>跨平台</strong>：在电脑、手机、平板上都能无缝使用</li>
<li><strong>轻量高效</strong>：在我的树莓派上运行流畅，占用资源少</li>
</ol><p>最重要的是，MiMusic 让我完全掌控自己的音乐库，不用依赖第三方音乐平台，这一点真的很贴心！</p></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>音乐爱好者</strong>：拥有大量本地音乐，需要统一管理的人</li>
<li><strong>NAS 用户</strong>：在 NAS 上搭建个人音乐服务器的人</li>
<li><strong>树莓派玩家</strong>：利用树莓派构建家庭媒体中心的人</li>
<li><strong>隐私关注者</strong>：不想将音乐数据存储在第三方平台的人</li>
<li><strong>开发者</strong>：想要定制自己的音乐服务器的人</li>
</ul></section>
<section><h2>项目资源<a href="#项目资源"><span>#</span></a></h2><p>如果你对 MiMusic 感兴趣，可以访问以下资源：</p><p><strong>GitHub地址</strong>: <a href="https://github.com/mimusic-org/mimusic" target="_blank">https://github.com/mimusic-org/mimusic</a></p><p><strong>客户端下载地址</strong>: <a href="https://github.com/mimusic-org/frontend" target="_blank">https://github.com/mimusic-org/frontend</a></p><p>觉得项目不错可以点个赞。</p><p><strong>官方文档</strong>: <a href="https://mimusic.hanxi.cc/" target="_blank">https://mimusic.hanxi.cc/</a></p><p><strong>在线演示</strong>：<a href="https://mimusic.hanxi.cc/%EF%BC%88%E8%B4%A6%E5%8F%B7/%E5%AF%86%E7%A0%81%EF%BC%9Aadmin%EF%BC%89" target="_blank">https://mimusic.hanxi.cc/（账号/密码：admin）</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时是如何管理自己的音乐的？使用 MiMusic 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=102365809&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/kG5HvrifueIWsHaWWdTbrQ?token=102365809&amp;lang=zh_CN" target="_blank">发现宝藏聚合软件！益达 APP 让你告别多 app 切换，一个软件看遍小说漫画影视</a></li>
<li><a href="http://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2046857375&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/80cbc609/</id>
      <title type="text">GitHub热门项目！Voicebox，开源语音合成的终极解决方案</title>
      <published>2026-03-11T18:31:13.000Z</published>
      <updated>2026-03-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/80cbc609/"/>
      <summary type="text">今天我要给大家推荐一个超级好用的语音合成工具——**Voicebox**，它是一个本地优先的开源语音克隆工作室，完全免费，在你的电脑上本地运行，保护隐私的同时，提供专业级的语音合成能力！这两天这个项目在技术圈子里特别火，今天我就来和大家唠唠这个神奇的工具，看看它是怎么让我们这些普通用户也能拥有专业级语音合成能力的。</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！AI语音合成太贵？试试这个开源神器，完全免费还保护隐私！<a href="#朋友们ai语音合成太贵试试这个开源神器完全免费还保护隐私"><span>#</span></a></h2><p>今天我要给大家推荐一个超级好用的语音合成工具——<strong>Voicebox</strong>，它是一个本地优先的开源语音克隆工作室，完全免费，在你的电脑上本地运行，保护隐私的同时，提供专业级的语音合成能力！</p><p>这两天这个项目在技术圈子里特别火，今天我就来和大家唠唠这个神奇的工具，看看它是怎么让我们这些普通用户也能拥有专业级语音合成能力的。</p></section>
<section><h2>项目介绍<a href="#项目介绍"><span>#</span></a></h2><p>Voicebox 是一个完全开源的语音合成工作室，它的核心价值在于：<strong>在你的本地设备上克隆声音、生成多语言语音、应用专业音频效果，并且完全保护你的隐私</strong>。</p><section><h3>✨ 核心特性<a href="#-核心特性"><span>#</span></a></h3><ul>
<li><strong>🚀 本地优先</strong>：所有模型和语音数据都在你的电脑上运行，完全保护隐私</li>
<li><strong>🎯 多引擎支持</strong>：集成5个TTS引擎（Qwen3-TTS、LuxTTS、Chatterbox Multilingual、Chatterbox Turbo、HumeAI TADA）</li>
<li><strong>🌍 多语言覆盖</strong>：支持23种语言，从英语到阿拉伯语、日语、印地语、斯瓦希里语等</li>
<li><strong>🎨 专业音频效果</strong>：8种后期处理效果（音高调整、混响、延迟、合唱、压缩、滤波器等）</li>
<li><strong>😊 情感表达</strong>：支持 [laugh]、[sigh]、[gasp] 等情感标签（Chatterbox Turbo引擎）</li>
<li><strong>📜 无限长度</strong>：自动分块处理，支持超长文本生成</li>
<li><strong>🎬 故事编辑器</strong>：多音轨时间线编辑器，适合对话、播客和叙事内容</li>
<li><strong>🔌 API支持</strong>：REST API便于集成到自己的项目中</li>
<li><strong>⚡ 原生性能</strong>：基于Tauri（Rust）构建，不是Electron，性能更优</li>
<li><strong>🌐 跨平台</strong>：支持macOS（MLX/Metal）、Windows（CUDA）、Linux、AMD ROCm、Intel Arc、Docker</li>
</ul></section><section><h3>🛠️ 技术栈<a href="#️-技术栈"><span>#</span></a></h3>

<table><thead><tr><th>类别</th><th>技术/组件</th><th>说明</th></tr></thead><tbody><tr><td>前端</td><td>Tauri (Rust)</td><td>跨平台桌面应用框架，性能优于Electron</td></tr><tr><td>后端</td><td>Python</td><td>语音合成引擎和API服务</td></tr><tr><td>TTS引擎</td><td>Qwen3-TTS</td><td>高质量多语言克隆，支持 delivery instructions</td></tr><tr><td>TTS引擎</td><td>LuxTTS</td><td>轻量级（~1GB显存），48kHz输出，CPU上150x实时速度</td></tr><tr><td>TTS引擎</td><td>Chatterbox Multilingual</td><td>支持23种语言，覆盖面最广</td></tr><tr><td>TTS引擎</td><td>Chatterbox Turbo</td><td>快速350M模型，支持情感/声音标签</td></tr><tr><td>TTS引擎</td><td>TADA</td><td>HumeAI语音语言模型，700s+连贯音频</td></tr><tr><td>音频处理</td><td>Spotify pedalboard</td><td>专业音频效果处理库</td></tr><tr><td>转录</td><td>Whisper</td><td>自动语音转文字</td></tr></tbody></table></section><section><h3>🎯 应用场景<a href="#-应用场景"><span>#</span></a></h3><ul>
<li><strong>内容创作</strong>：视频配音、有声书制作、播客生成</li>
<li><strong>辅助工具</strong>：为视障人士提供语音导航、文档朗读</li>
<li><strong>游戏开发</strong>：角色语音、NPC对话生成</li>
<li><strong>教育领域</strong>：多语言教学内容、有声教材</li>
<li><strong>商业应用</strong>：客服语音、产品介绍、营销内容</li>
</ul></section></section>
<section><h2>实战体验<a href="#实战体验"><span>#</span></a></h2><section><h3>环境准备<a href="#环境准备"><span>#</span></a></h3><p>用Voicebox真的超级简单，不需要复杂的配置，只要你的电脑满足基本要求：</p><ul>
<li><strong>Windows</strong>：支持CUDA的NVIDIA显卡</li>
<li><strong>macOS</strong>：Apple Silicon或Intel处理器</li>
<li><strong>Linux</strong>：支持AMD ROCm或Intel Arc</li>
</ul></section><section><h3>项目下载<a href="#项目下载"><span>#</span></a></h3><p>首先，咱们去GitHub看看这个宝藏仓库：<a href="https://github.com/jamiepine/voicebox" target="_blank">https://github.com/jamiepine/voicebox</a></p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/5ca040f533f54964bc95cc826bd5c41220260415155317223.png" alt="" /></p><p>根据你的操作系统选择对应的下载链接：</p>

<table><thead><tr><th>平台</th><th>下载方式</th></tr></thead><tbody><tr><td>macOS (Apple Silicon)</td><td>下载DMG</td></tr><tr><td>macOS (Intel)</td><td>下载DMG</td></tr><tr><td>Windows</td><td>下载MSI</td></tr><tr><td>Docker</td><td><code>docker compose up</code></td></tr><tr><td>Linux</td><td>源码编译（见官方文档）</td></tr></tbody></table></section><section><h3>安装体验<a href="#安装体验"><span>#</span></a></h3><p>下载完成后，按照常规软件安装步骤进行安装。安装过程非常简单，一路点击下一步即可。</p><p>安装完成后，启动Voicebox，第一次运行时会自动下载所需的模型文件。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/25b657c3b91c4111b125325504ed664020260415160117239.png" alt="" /></p></section><section><h3>Docker部署<a href="#docker部署"><span>#</span></a></h3><p>除了直接安装，Voicebox还支持通过Docker部署，这对于服务器环境或需要隔离运行的场景非常方便：</p><ol>
<li>
<p><strong>环境准备</strong>：确保你的系统已安装Docker和Docker Compose</p>
<ul>
<li>Windows：下载并安装Docker Desktop</li>
<li>macOS：下载并安装Docker Desktop</li>
<li>Linux：使用包管理器安装Docker</li>
</ul>
</li>
<li>
<p><strong>获取项目</strong>：克隆Voicebox仓库</p>
<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span> </span><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>     </span><span>voicebox</span><span>:</span></div></div><div><div><div>3</div></div><div><span>         </span><span>build</span><span>: </span><span>.</span></div></div><div><div><div>4</div></div><div><span>         </span><span>container_name</span><span>: </span><span>voicebox</span></div></div><div><div><div>5</div></div><div><span>         </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>         </span><span>ports</span><span>:</span></div></div><div><div><div>8</div></div><div><span>         </span><span># Bind to localhost only for security</span></div></div><div><div><div>9</div></div><div><span><span>         </span></span><span>- </span><span>"127.0.0.1:17493:17493"</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>         </span><span>volumes</span><span>:</span></div></div><div><div><div>12</div></div><div><span>         </span><span># Bind-mount for generated audio (customize the host path as needed)</span></div></div><div><div><div>13</div></div><div><span>         </span><span># Host side:      ./output/</span></div></div><div><div><div>14</div></div><div><span>         </span><span># Container side: /app/data/generations/</span></div></div><div><div><div>15</div></div><div><span><span>         </span></span><span>- </span><span>./output:/app/data/generations</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>         </span><span># Named volume for profiles, DB, cache (persists across container restarts)</span></div></div><div><div><div>18</div></div><div><span><span>         </span></span><span>- </span><span>voicebox-data:/app/data</span></div></div><div><div><div>19</div></div><div>
</div></div><div><div><div>20</div></div><div><span>         </span><span># HuggingFace model cache (so models aren't re-downloaded on rebuild)</span></div></div><div><div><div>21</div></div><div><span><span>         </span></span><span>- </span><span>huggingface-cache:/home/voicebox/.cache/huggingface</span></div></div><div><div><div>22</div></div><div>
</div></div><div><div><div>23</div></div><div><span>         </span><span>environment</span><span>:</span></div></div><div><div><div>24</div></div><div><span><span>         </span></span><span>- </span><span>LOG_LEVEL=info</span></div></div><div><div><div>25</div></div><div>
</div></div><div><div><div>26</div></div><div><span>         </span><span>networks</span><span>:</span></div></div><div><div><div>27</div></div><div><span><span>         </span></span><span>- </span><span>voicebox-net</span></div></div><div><div><div>28</div></div><div>
</div></div><div><div><div>29</div></div><div><span>         </span><span>deploy</span><span>:</span></div></div><div><div><div>30</div></div><div><span>         </span><span>resources</span><span>:</span></div></div><div><div><div>31</div></div><div><span>             </span><span>limits</span><span>:</span></div></div><div><div><div>32</div></div><div><span>             </span><span>cpus</span><span>: </span><span>'4'</span></div></div><div><div><div>33</div></div><div><span>             </span><span>memory</span><span>: </span><span>8G</span></div></div><div><div><div>34</div></div><div><span>     </span><span>networks</span><span>:</span></div></div><div><div><div>35</div></div><div><span>     </span><span>voicebox-net</span><span>:</span></div></div><div><div><div>36</div></div><div><span>         </span><span>driver</span><span>: </span><span>bridge</span></div></div><div><div><div>37</div></div><div>
</div></div><div><div><div>38</div></div><div><span>     </span><span>volumes</span><span>:</span></div></div><div><div><div>39</div></div><div><span>     </span><span>voicebox-data</span><span>:</span></div></div><div><div><div>40</div></div><div><span>     </span><span>huggingface-cache</span><span>:</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
</li>
<li>
<p><strong>启动容器</strong>：使用Docker Compose启动</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p><strong>访问应用</strong>：启动完成后，在浏览器中访问 <code>http://localhost:17493</code></p>
</li>
</ol></section><section><h3>声音克隆<a href="#声音克隆"><span>#</span></a></h3><p>Voicebox最强大的功能之一就是声音克隆，只需几秒钟的音频样本就能创建属于你自己的语音模型。</p><ol>
<li><strong>创建语音配置文件</strong>：点击”Create Profile”按钮</li>
<li><strong>上传音频样本</strong>：可以上传多个音频文件或直接在应用内录制</li>
<li><strong>等待处理</strong>：系统会自动分析音频并创建语音模型</li>
<li><strong>测试生成</strong>：输入文本，选择刚创建的语音配置文件进行测试
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/225f6c457b8d4f6abd4fb5941b33ba7520260415160026924.png" alt="" /></li>
</ol></section><section><h3>多语言生成<a href="#多语言生成"><span>#</span></a></h3><p>Voicebox支持23种语言的语音生成，让你轻松创建多语言内容：</p><ol>
<li><strong>选择语言</strong>：在生成界面选择目标语言</li>
<li><strong>输入文本</strong>：用对应语言输入文本内容</li>
<li><strong>选择引擎</strong>：不同引擎对不同语言有不同的优势</li>
<li><strong>生成语音</strong>：点击生成按钮，等待结果</li>
</ol></section><section><h3>音频效果处理<a href="#音频效果处理"><span>#</span></a></h3><p>Voicebox内置8种专业音频效果，让你的语音更加专业：</p><ol>
<li><strong>选择效果</strong>：在效果面板选择需要的效果</li>
<li><strong>调整参数</strong>：根据需要调整效果参数</li>
<li><strong>实时预览</strong>：调整后可以实时预览效果</li>
<li><strong>应用效果</strong>：点击应用按钮，生成带有效果的语音</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/733c8ac19a63430fa59eb9be738eba3f20260415155845317.png" alt="" /></p></section><section><h3>故事编辑器<a href="#故事编辑器"><span>#</span></a></h3><p>对于需要多角色对话的场景，Voicebox的故事编辑器非常实用：</p><ol>
<li><strong>创建新项目</strong>：在故事编辑器中创建新项目</li>
<li><strong>添加音轨</strong>：为每个角色创建独立音轨</li>
<li><strong>输入文本</strong>：为每个音轨输入对应的文本</li>
<li><strong>调整时间线</strong>：拖动调整各部分的时间位置</li>
<li><strong>预览和导出</strong>：预览整体效果后导出最终音频</li>
</ol><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/df78607ccc064ebf88cfefd5a52a791520260415155913274.png" alt="" /></p></section></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>今天和大家分享了Voicebox这个开源语音合成的宝藏项目，它用”本地优先 + 多引擎集成”的方式，完美解决了传统语音合成的诸多痛点。通过简单的安装和操作，我们这些普通用户也能轻松获得专业级的语音合成能力。</p><p>Voicebox的核心优势在于：本地运行保护隐私、多引擎支持满足不同需求、多语言覆盖拓展应用场景、专业音频效果提升品质、情感表达增加自然度、无限长度支持长内容、故事编辑器简化多角色内容创作。</p><p>无论是内容创作者、教育工作者、游戏开发者还是普通用户，Voicebox都能为你提供强大而灵活的语音合成解决方案。最重要的是，它完全开源免费，让每个人都能享受AI语音技术的便利。</p></section>
<section><h2>项目资源<a href="#项目资源"><span>#</span></a></h2><p><strong>GitHub地址</strong>：<a href="https://github.com/jamiepine/voicebox" target="_blank">https://github.com/jamiepine/voicebox</a></p><p>觉得项目不错的话，记得给作者点个star支持一下！</p><p><strong>项目特色</strong>：本地优先的开源语音合成工作室，集成5个TTS引擎，支持23种语言，提供专业音频效果，保护隐私，完全免费。</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你是不是已经跃跃欲试了？赶紧去GitHub下载适合你系统的版本，试试这个神奇的语音合成工具吧！</p><p>如果你用了之后有什么有趣的体验，或者有什么问题，欢迎在评论区和我交流。我会定期分享更多好用的开源工具，记得关注我哦！</p><p>今天的分享就到这里结束了，我们下一篇文章见。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/8bbd0f9d/</id>
      <title type="text">你的NAS除了存小姐姐还能干啥？Docker部署「闲鱼管理系统」轻松赚奶茶钱！！</title>
      <published>2026-03-11T18:31:13.000Z</published>
      <updated>2026-03-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/8bbd0f9d/"/>
      <summary type="text">嘿，各位NAS玩家！机器折腾好了，电影下满了，然后呢？是不是又开始觉得，这台24小时开机的“小电脑”，除了存片儿和偶尔同步下文件，好像……还有点“大材小用”？折腾的心有点冷却了？今天，我给你指条“野路子”——让你家的飞牛NAS，变身一台24小时在线的“自动售货机”，帮你卖点虚拟商品，赚点零花钱！</summary>
      <content type="html"><![CDATA[<p>​	嘿，各位NAS玩家！机器折腾好了，电影下满了，然后呢？是不是又开始觉得，这台24小时开机的“小电脑”，除了存片儿和偶尔同步下文件，好像……还有点“大材小用”？折腾的心有点冷却了？</p>
<p>​	今天，我给你指条“野路子”——让你家的飞牛NAS，变身一台24小时在线的“自动售货机”，帮你卖点虚拟商品，赚点零花钱！</p>
<p>啥是虚拟商品？比如：</p>
<ul>
<li>
<p>你整理的软件安装包、素材资源（放网盘，卖链接）</p>
</li>
<li>
<p>你开发的小工具、脚本（卖卡密授权）</p>
</li>
<li>
<p>你买的付费教程、课程（转卖观看权）</p>
</li>
<li>
<p>各类游戏激活码、会员账号等等</p>
</li>
</ul>
<p>​	这些东西，成本极低，几乎不用操心库存和物流。最大的痛点是什么？需要人工盯着闲鱼，回复买家的咨询，手动发卡密或链接，烦都烦死了！</p>
<p>如果有一个工具，能自动回复买家问题，收到付款后自动发货，甚至能智能聊天……那不就解放了？</p>
<p>还真有！而且，它就能完美运行在你的飞牛NAS上！</p>
<p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/01/5f4b20b5dad94252a9fc57e5bd81f9c2640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></p>
<section><h3>详细介绍<a href="#详细介绍"><span>#</span></a></h3><p>今天的主角， 「闲鱼自动回复与发货系统」</p><p>你可以把它理解成一个 “数字店员” ，专门帮你打理闲鱼店铺。它的本事可大了：</p><ul>
<li>智能自动回复：买家问“在吗？”“怎么用？”“有教程吗？”，它都能根据你设置的关键词自动回答，还能接入AI（比如ChatGPT），进行有上下文的理解式聊天！</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/01/bdf85a0d30444b65a83795870af1891e640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/01/786c81bd0d3c47d2839f4449bae0f03c640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></p><ul>
<li>多账号管理：支持扫码登录、账户密码登录、Cookie方式登录。你手头有几个闲鱼号？它能同时管！数据完全隔离，安全得很。</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/01/16c10e8adb53409f8f2969a472f44e9c640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></p><ul>
<li>卡卷管理：支持扫码登录、账户密码登录、Cookie方式登录。</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/01/faf6e6e09aae4fa8915a2fa1d4f40509640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></p><ul>
<li>全自动发货：买家一旦付款，系统立刻触发发货规则。可以自动发送网盘链接、卡密文本，甚至调用API生成卡密，完全不用你动手。</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/01/394f5370ed0642fe98e7616e6e6f38cb640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></p><ul>
<li>
<p>自动确认发货：发货后，还能自动调用闲鱼官方接口，帮你点击“确认发货”，流程一气呵成。</p>
</li>
<li>
<p>多种通知渠道：重要消息不遗漏！</p>
</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/01/dcf366cb05d0472283fb64b6a7f42b1a640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></p><ul>
<li>商品与数据管理：自动收集上架的商品，管理海量的关键词回复库，所有操作都有日志，清清楚楚。</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/01/d41c50c71aff4b9b92ae5c5d707b68d6640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></p><p>说白了，你只需要：1. 上架商品。2. 设置好回复话术和发货规则。剩下的事情，就交给NAS里的这个“数字店员”吧！ 你该上班上班，该睡觉睡觉，钱悄悄地就进来了。</p></section>
<section><h3>Docker Compose 一键部署<a href="#docker-compose-一键部署"><span>#</span></a></h3><p>部署过程依然是熟悉的“抄作业”环节，我们主打一个“复制粘贴就能用”。</p><p>第一步：创建它的“小单间”</p><ul>
<li>
<p>在你的NAS上，比如在 docker 文件夹里</p>
</li>
<li>
<p>新建一个 <code>xianyu</code>目录。</p>
</li>
</ul><p>第二步：编写 <code>docker-compose</code></p><ul>
<li>
<p>打开飞牛桌面上的Docker界面 -&gt; Compose</p>
</li>
<li>
<p>写一个项目名称，选择储存路径</p>
</li>
</ul><p>（例如你之前创建的目录/vol1/1000/docker/xianyu）</p><ul>
<li>创建 docker-compose.yml 文件，把下面的“咒语”复制粘贴进去</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services:</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>xianyu:</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>image: crpi-ewihweek11p6l2rf.cn-shanghai.personal.cr.aliyuncs.com/price_ma/xianyu-replay-fixed:latest</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>container_name: xianyu</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>restart: unless-stopped</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>ports:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- "3351:8080"  # 左侧3351端口可修改</span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>volumes:</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>- ./data:/app/data</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/01/8db4f107a12d44249634c2f41cf8c46e640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></p><p>第三步：启动！！</p><ul>
<li>
<p>启动 -&gt; 自动拉取镜像并构建坐等完成。</p>
</li>
<li>
<p>打开浏览器，访问：<a href="http://%E4%BD%A0%E7%9A%84%E9%A3%9E%E7%89%9BNAS" target="_blank">http://你的飞牛NAS</a> IP&lt;3351&gt;</p>
</li>
<li>
<p>默认用户名：admin</p>
</li>
<li>
<p>默认密码：admin123</p>
</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/01/436f34312fa44a179ed5c38607d3982d640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/01/196cda01b5234907ae0b8cd6e275dae5640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></p><p>登录后，别慌，咱们一步步来设置。</p><p><strong>第一环：绑定你的闲鱼账号</strong></p><ul>
<li>
<p>在系统里，找到“闲鱼账号管理”，点击“添加账号”。</p>
</li>
<li>
<p>这时会弹出一个二维码。<strong>注意！请务必使用闲鱼APP（不是淘宝APP）扫码登录！</strong></p>
</li>
<li>
<p>扫码后，手机上确认登录。系统就成功绑定你的闲鱼账号了。可以绑定多个哦！</p>
</li>
</ul><p><strong>第二环：设置“自动回复”</strong></p><ul>
<li>
<p><strong>通用关键词：在“关键词回复”设置里，添加一些通用问答。</strong></p>
</li>
<li>
<p><strong>比如：</strong></p>
</li>
<li>
<p>关键词： → 回复：</p>
</li>
<li>
<p>关键词： → 回复：</p>
</li>
<li>
<p>关键词： → 回复：</p>
</li>
<li>
<p><strong>商品专用回复：针对某个具体商品（比如你卖的“XX软件”），可以设置更精准的回复。优先级最高。</strong></p>
</li>
<li>
<p><strong>AI智能回复（高阶玩法）：如果你有OpenAI的API密钥，可以开启这个功能。店员就能像真人一样，理解复杂的上下文问题，非常强大。</strong></p>
</li>
</ul><p><strong>第三环：设置“自动发货”</strong></p><ul>
<li>
<p>在“自动发货规则”里，点击“创建规则”。</p>
</li>
<li>
<p><strong>匹配商品：可以按商品标题关键词匹配，也可以选择具体商品。</strong></p>
</li>
<li>
<p><strong>发货方式：</strong></p>
</li>
<li>
<p><strong>文本内容：最简单，直接填上你的网盘链接和提取码。</strong></p>
</li>
<li>
<p><strong>卡密文件：如果你有一批卡密（比如，），可以上传一个txt文件，每行一个。系统会自动按顺序发送，并且标记已使用，防止重复。</strong></p>
</li>
<li>
<p>**API调用：**<strong>最灵活，可以对接你自己的发卡网站API，实时生成卡密。</strong></p>
</li>
<li>
<p><strong>触发条件：一定要勾选 <strong>“付款消息”</strong>！这样买家一付款，立刻触发发货。</strong></p>
</li>
<li>
<p><strong>延时发货：可以设置几秒到几分钟的延迟，显得更“真人”一点。</strong></p>
</li>
</ul><p><strong>第四环：测试！测试！测试！</strong></p><ul>
<li><strong>自己用小号，在闲鱼上给自己的商品发消息、下单付款，看看整个流程是否顺畅：自动回复了吗？付款后自动发货了吗？发货内容正确吗？</strong></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/bd39471b/</id>
      <title type="text">小白福利！这个神器让你轻松下载全网视频，再也不用为会员发愁了</title>
      <published>2026-03-11T18:31:13.000Z</published>
      <updated>2026-03-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/bd39471b/"/>
      <summary type="text">今天我要给大家推荐一个超级好用的视频下载工具——**MeTube**，它是一个免费开源的视频下载平台，操作超级简单，支持下载 YouTube 和几十个其他网站的视频，而且完全免费！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！想下载视频却找不到好用的工具？试试这个免费开源的神器！<a href="#朋友们想下载视频却找不到好用的工具试试这个免费开源的神器"><span>#</span></a></h2><p>前几天有朋友问我：“小王，有没有什么简单的方法可以下载网上的视频？“，作为一个经常需要保存视频资料的人，我太懂这种感受了——要么是网站不让下载，要么是各种下载工具操作复杂，要么是限速严重，简直让人崩溃。</p><p>今天我要给大家推荐一个超级好用的视频下载工具——<strong>MeTube</strong>，它是一个免费开源的视频下载平台，操作超级简单，支持下载 YouTube 和几十个其他网站的视频，而且完全免费！</p><p>这两天我用了之后简直爱不释手，今天就来和大家唠唠这个神奇的工具，看看它是怎么让我们这些小白也能轻松下载视频的。</p></section>
<section><h2>项目介绍<a href="#项目介绍"><span>#</span></a></h2><p>MeTube 是一个基于 Web 的视频下载工具，它的核心价值在于：<strong>让视频下载变得超级简单，任何人都能轻松上手</strong>。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/81e3ab008eef4dbbb9b4da13511b249c20260417093931191.png" alt="" /></p><section><h3>✨ 核心特性<a href="#-核心特性"><span>#</span></a></h3><ul>
<li><strong>🚀 操作简单</strong>：基于网页界面，不用安装复杂软件，打开浏览器就能用</li>
<li><strong>🌐 支持多网站</strong>：不仅支持 YouTube，还支持几十个其他视频网站</li>
<li><strong>📋 播放列表下载</strong>：支持整个播放列表批量下载，不用一个个点</li>
<li><strong>🎯 多种格式选择</strong>：支持选择不同质量和格式，满足不同需求</li>
<li><strong>🐳 容器化部署</strong>：支持 Docker 运行，安装超级方便</li>
<li><strong>🔧 自定义配置</strong>：可以设置下载模式、文件命名规则等</li>
<li><strong>📱 跨平台</strong>：在任何支持现代浏览器的设备上都能使用</li>
<li><strong>💾 本地存储</strong>：下载的视频保存在自己的设备上，完全掌控</li>
<li><strong>🔒 隐私保护</strong>：不需要登录账号，保护个人隐私</li>
<li><strong>💰 完全免费</strong>：开源项目，没有任何隐藏费用</li>
</ul></section><section><h3>🎯 应用场景<a href="#-应用场景"><span>#</span></a></h3><ul>
<li><strong>学习资料</strong>：下载在线课程、教程视频，离线观看</li>
<li><strong>娱乐休闲</strong>：下载电影、电视剧、综艺节目，随时观看</li>
<li><strong>素材收集</strong>：下载视频素材，用于自己的创作</li>
<li><strong>备份存档</strong>：备份重要的视频内容，防止失效</li>
<li><strong>旅行途中</strong>：提前下载视频，在没有网络的地方观看</li>
</ul></section></section>
<section><h2>实战体验<a href="#实战体验"><span>#</span></a></h2><section><h3>环境准备<a href="#环境准备"><span>#</span></a></h3><p>用 MeTube 真的超级简单，只需要一点小准备：</p><ul>
<li><strong>有网络的电脑</strong>：任何能上网的电脑都行</li>
<li><strong>Docker</strong>：如果用 Docker 部署的话，需要安装 Docker</li>
</ul></section><section><h3>Docker 部署<a href="#docker-部署"><span>#</span></a></h3><p>对于小白来说，Docker 部署是最方便的方式：</p><ol>
<li><strong>安装 Docker</strong>：如果还没安装 Docker，可以去官网下载 Docker Desktop 并安装</li>
<li><strong>启动容器</strong>：打开命令行，输入以下命令
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>services:</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ol><p>metube:
image: ghcr.io/alexta69/metube
container_name: metube
restart: unless-stopped
ports:
- “8081&lt;8081&gt;”
volumes:
- /path/to/downloads:/downloads</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>（把 `/path/to/downloads` 换成你想保存视频的文件夹）</span></div></div><div><div><div>2</div></div><div><span>3. **访问应用**：打开浏览器，访问 `http://localhost:8081`</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>![](https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/f425353cb4f64a2f9b22d53cbb254559screenshot.gif)</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>### 下载视频</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span>下载视频的步骤超级简单，一看就会：</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>1. **复制链接**：从视频网站复制视频链接</span></div></div><div><div><div>11</div></div><div><span>2. **粘贴链接**：在 MeTube 网页的输入框中粘贴链接</span></div></div><div><div><div>12</div></div><div><span>3. **选择选项**：选择你想要的视频质量和格式</span></div></div><div><div><div>13</div></div><div><span>4. **开始下载**：点击下载按钮，等待下载完成</span></div></div><div><div><div>14</div></div><div><span>5. **查看结果**：下载完成后，在下载文件夹中找到视频</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span>### 播放列表下载</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>如果你想下载整个播放列表，步骤也差不多：</span></div></div><div><div><div>19</div></div><div>
</div></div><div><div><div>20</div></div><div><span>1. **复制播放列表链接**：从视频网站复制整个播放列表的链接</span></div></div><div><div><div>21</div></div><div><span>2. **粘贴链接**：在 MeTube 网页的输入框中粘贴链接</span></div></div><div><div><div>22</div></div><div><span>3. **选择选项**：选择你想要的视频质量和格式</span></div></div><div><div><div>23</div></div><div><span>4. **开始下载**：点击下载按钮，MeTube 会自动下载整个播放列表</span></div></div><div><div><div>24</div></div><div>
</div></div><div><div><div>25</div></div><div><span>## 我的使用感受</span></div></div><div><div><div>26</div></div><div>
</div></div><div><div><div>27</div></div><div><span>作为一个技术小白，我必须说 MeTube 彻底改变了我下载视频的方式。以前我总是为了下载视频而发愁：</span></div></div><div><div><div>28</div></div><div>
</div></div><div><div><div>29</div></div><div><span>- 要么是网站的下载按钮要付费</span></div></div><div><div><div>30</div></div><div><span>- 要么是各种下载软件操作复杂，根本不会用</span></div></div><div><div><div>31</div></div><div><span>- 要么是下载速度慢得要死，等半天才能下完</span></div></div><div><div><div>32</div></div><div>
</div></div><div><div><div>33</div></div><div><span>现在有了 MeTube，一切都变得超级简单：</span></div></div><div><div><div>34</div></div><div>
</div></div><div><div><div>35</div></div><div><span>1. **操作简单**：打开网页，粘贴链接，点击下载，就这么简单</span></div></div><div><div><div>36</div></div><div><span>2. **速度快**：下载速度超级快，比我以前用的工具快多了</span></div></div><div><div><div>37</div></div><div><span>3. **批量下载**：播放列表一键下载，不用一个个点，省了好多时间</span></div></div><div><div><div>38</div></div><div><span>4. **格式多样**：可以选择不同质量和格式，满足不同需求</span></div></div><div><div><div>39</div></div><div><span>5. **完全免费**：没有任何费用，想下多少下多少</span></div></div><div><div><div>40</div></div><div>
</div></div><div><div><div>41</div></div><div><span>前几天我用它下载了一个学习课程的整个播放列表，以前要一个个下载，现在一键搞定，简直不要太方便！</span></div></div><div><div><div>42</div></div><div>
</div></div><div><div><div>43</div></div><div><span>## 项目资源</span></div></div><div><div><div>44</div></div><div>
</div></div><div><div><div>45</div></div><div><span>**GitHub地址**：https://github.com/alexta69/metube</span></div></div><div><div><div>46</div></div><div>
</div></div><div><div><div>47</div></div><div><span>觉得项目不错的话，记得给作者点个star支持一下！</span></div></div><div><div><div>48</div></div><div>
</div></div><div><div><div>49</div></div><div><span>**项目特色**：免费开源的视频下载平台，基于 Web 界面，支持多网站下载，支持播放列表批量下载，操作简单，完全免费。</span></div></div><div><div><div>50</div></div><div>
</div></div><div><div><div>51</div></div><div><span>## 互动时间</span></div></div><div><div><div>52</div></div><div>
</div></div><div><div><div>53</div></div><div><span>你是不是已经跃跃欲试了？赶紧按照文中的步骤部署 MeTube，试试这个神奇的视频下载工具吧！</span></div></div><div><div><div>54</div></div><div>
</div></div><div><div><div>55</div></div><div><span>如果你用了之后有什么有趣的体验，或者有什么问题，欢迎在评论区和我交流。我会定期分享更多好用的开源工具，记得关注我哦！</span></div></div><div><div><div>56</div></div><div>
</div></div><div><div><div>57</div></div><div><span>今天的分享就到这里结束了，我们下一篇文章见。</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/c42f1bd0/</id>
      <title type="text">哇！这个免费工具能转换1000+种文件格式，还能自己部署超安全</title>
      <published>2026-03-11T18:31:13.000Z</published>
      <updated>2026-03-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/c42f1bd0/"/>
      <summary type="text">作为一个经常和各种文件打交道的人，我太懂这种感受了——想转个文件吧，要么是在线工具慢得要死，要么是格式支持不全，要么是担心文件隐私问题，简直让人崩溃。不过最近我发现了一个超级好用的工具，必须要分享给大家——**ConvertX**！这是一个可以自己部署的在线文件转换器，支持1000多种格式，完全免费，最重要的是文件都在自己服务器上处理，隐私超安全！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！还在为文件格式转换发愁吗？这个神器帮你搞定一切！<a href="#朋友们还在为文件格式转换发愁吗这个神器帮你搞定一切"><span>#</span></a></h2><p>前几天有朋友给我发消息：“小王，你知道有什么好用的文件转换工具吗？我想把视频转成GIF，试了好几个在线工具要么限速要么要会员，太麻烦了！”</p><p>作为一个经常和各种文件打交道的人，我太懂这种感受了——想转个文件吧，要么是在线工具慢得要死，要么是格式支持不全，要么是担心文件隐私问题，简直让人崩溃。</p><p>不过最近我发现了一个超级好用的工具，必须要分享给大家——<strong>ConvertX</strong>！这是一个可以自己部署的在线文件转换器，支持1000多种格式，完全免费，最重要的是文件都在自己服务器上处理，隐私超安全！</p><p>这两天我用了之后简直爱到不行，今天就来和大家聊聊这个神器，看看它是怎么解决文件转换难题的。</p></section>
<section><h2>这是个什么工具？<a href="#这是个什么工具"><span>#</span></a></h2><p>简单来说，ConvertX就是一个全能的文件转换工厂，你可以把它部署在自己的电脑或服务器上，然后通过浏览器访问，就能转换各种类型的文件。</p><p>想象一下，不管是视频转音频、图片改格式、文档互转，还是电子书转换，都能在一个地方搞定，而且完全免费，不用看广告，也不用担心文件被上传到别人的服务器。</p><section><h3>它有什么特别的？<a href="#它有什么特别的"><span>#</span></a></h3><ul>
<li><strong>格式超级多</strong>：支持1000多种格式，从常见的MP4、JPG、PDF，到冷门的专业格式，几乎都能搞定</li>
<li><strong>批量转换</strong>：一次上传多个文件，一起转换，省时间又方便</li>
<li><strong>自己部署</strong>：文件在本地服务器处理，隐私有保障，不用担心敏感文件泄露</li>
<li><strong>操作简单</strong>：网页界面一目了然，不用安装任何软件，打开浏览器就能用</li>
<li><strong>多账户支持</strong>：如果和家人朋友一起用，每个人都可以有自己的账户</li>
<li><strong>历史记录</strong>：随时查看之前的转换记录，方便管理</li>
<li><strong>自动清理</strong>：可以设置自动删除旧文件，不会占满存储空间</li>
</ul></section><section><h3>能转换哪些类型的文件？<a href="#能转换哪些类型的文件"><span>#</span></a></h3><ul>
<li><strong>视频</strong>：MP4、AVI、MKV、WebM等各种视频格式互转</li>
<li><strong>图片</strong>：JPG、PNG、GIF、SVG等图片格式转换</li>
<li><strong>文档</strong>：Word、Excel、PDF、PPT等办公文档互转</li>
<li><strong>电子书</strong>：EPUB、MOBI、PDF等电子书格式转换</li>
<li><strong>3D文件</strong>：各种3D模型格式转换</li>
<li><strong>其他</strong>：还有很多专业格式，比如LaTeX、数据文件等</li>
</ul></section></section>
<section><h2>怎么部署使用？<a href="#怎么部署使用"><span>#</span></a></h2><section><h3>最简单的方法：Docker部署<a href="#最简单的方法docker部署"><span>#</span></a></h3><p>如果你有Docker，部署超级简单，就像装个普通软件一样：</p><ol>
<li>
<p><strong>创建配置文件</strong>：在电脑上新建一个文件夹，比如叫convertx，然后在里面创建一个叫docker-compose.yml的文件，内容如下：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>convertx</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image</span><span>: </span><span>ghcr.io/c4illin/convertx</span></div></div><div><div><div>4</div></div><div><span>    </span><span>container_name</span><span>: </span><span>convertx</span></div></div><div><div><div>5</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>6</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>"3000:3000"</span></div></div><div><div><div>8</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>- </span><span>JWT_SECRET=随便写个长一点的密码</span></div></div><div><div><div>10</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>- </span><span>./data:/app/data</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p><strong>启动服务</strong>：打开命令行，进入刚才创建的文件夹，运行：</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p><strong>开始使用</strong>：打开浏览器，访问 <code>http://localhost:3000</code>，第一次访问会让你创建账户，设置个密码就好</p>
</li>
</ol></section><section><h3>没有Docker怎么办？<a href="#没有docker怎么办"><span>#</span></a></h3><p>如果你没有Docker，也可以直接运行：</p><ol>
<li><strong>安装Bun</strong>：先去 <a href="https://bun.sh" target="_blank">bun.sh</a> 下载并安装Bun（这是一个现代的JavaScript运行时）</li>
<li><strong>下载代码</strong>：运行 <code>git clone https://github.com/C4illin/ConvertX.git</code>，然后进入文件夹</li>
<li><strong>安装依赖</strong>：运行 <code>bun install</code></li>
<li><strong>启动服务</strong>：运行 <code>bun run dev</code></li>
</ol></section><section><h3>怎么用它转换文件？<a href="#怎么用它转换文件"><span>#</span></a></h3><ol>
<li><strong>登录</strong>：打开 <code>http://localhost:3000</code>，输入你创建的账户密码</li>
<li><strong>上传文件</strong>：点击上传按钮，选择要转换的文件（可以一次选多个）</li>
<li><strong>选择格式</strong>：在下拉菜单里选择你想要的目标格式</li>
<li><strong>开始转换</strong>：点击转换按钮，等一会儿就好了</li>
<li><strong>下载文件</strong>：转换完成后，点击下载按钮就能拿到转换后的文件</li>
</ol></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>作为一个经常需要处理各种文件的人，我必须说ConvertX真的改变了我的工作方式。</p><p>以前我转换文件的流程是这样的：</p><ul>
<li>想转视频，找在线工具，结果限速，大文件要等半天</li>
<li>想转图片，用PS太麻烦，在线工具又担心画质</li>
<li>想转文档，要么用付费软件，要么担心格式错乱</li>
<li>最头疼的是，有些敏感文件根本不敢上传到在线服务</li>
</ul><p>现在有了ConvertX，一切都变得超级简单：</p><ul>
<li><strong>想转什么转什么</strong>：不管是视频、图片还是文档，一个工具全搞定</li>
<li><strong>速度超级快</strong>：在自己的服务器上处理，速度取决于自己的硬件，比在线工具快多了</li>
<li><strong>质量有保证</strong>：用的都是专业转换引擎，转换效果特别好</li>
<li><strong>隐私超安全</strong>：文件从来不出本地服务器，敏感文件也不用担心</li>
<li><strong>操作超简单</strong>：网页界面一目了然，我妈都能学会用</li>
</ul><p>前几天我用它把一个1GB的视频转换成GIF，只用了几分钟，效果还特别好，简直不要太香！</p></section>
<section><h2>总结一下<a href="#总结一下"><span>#</span></a></h2><p>ConvertX真的是一个超级实用的工具，它解决了我们在文件转换中遇到的几乎所有问题：</p><ul>
<li>不用再为限速、会员费发愁</li>
<li>不用担心格式支持不全</li>
<li>不用害怕文件隐私泄露</li>
<li>操作简单，谁都能学会</li>
</ul><p>最重要的是，它完全免费，开源，你想怎么用就怎么用。</p><p>不管你是学生、上班族，还是技术爱好者，只要你经常需要转换文件，ConvertX都能帮你节省大量时间和精力。</p></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p><strong>GitHub</strong>：<a href="https://github.com/C4illin/ConvertX" target="_blank">https://github.com/C4illin/ConvertX</a></p><p>觉得好用的话，记得给作者点个star支持一下！</p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你是不是已经迫不及待想试试了？赶紧按照文中的步骤部署一个ConvertX，体验一下全能文件转换的乐趣吧！</p><p>如果你用了之后有什么有趣的体验，或者遇到了什么问题，欢迎在评论区和我交流。我会定期分享更多好用的开源工具，记得关注我哦！</p><p>今天的分享就到这里，我们下一篇文章见～</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/f5278042/</id>
      <title type="text">docker 离线安装（分步法&amp;一键法）</title>
      <published>2026-03-11T18:31:13.000Z</published>
      <updated>2026-03-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/f5278042/"/>
      <summary type="text">本文介绍在无法连接外网的服务器上通过离线方式安装Docker的方法，包括分步安装和一键安装两种方案，并提供了详细的步骤说明。</summary>
      <content type="html"><![CDATA[<p>原文：<a href="https://www.cnblogs.com/505donkey/p/18151705" target="_blank">https://www.cnblogs.com/505donkey/p/18151705</a></p>
<section><h3>一、安装环境<a href="#一安装环境"><span>#</span></a></h3><p>操作系统：Centos7.99
内核版本：3.10.0-1160.el7.x86_64
安装用户：root</p></section>
<section><h3>二、docker 离线安装<a href="#二docker-离线安装"><span>#</span></a></h3><section><h4>1. 下载压缩包<a href="#1-下载压缩包"><span>#</span></a></h4><p>官网下载地址：<a href="https://download.docker.com/linux/static/stable/x86_64/" target="_blank">https://download.docker.com/linux/static/stable/x86_64/</a></p><p>这里默认选择最新版本（28.1.1）</p></section><section><h4>2. 上传压缩包并解压<a href="#2-上传压缩包并解压"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>tar</span><span> </span><span>zxvf</span><span> </span><span>docker-28.1.1.tgz</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>3. 配置docker命令<a href="#3-配置docker命令"><span>#</span></a></h4><p>将解压后的docker命令拷贝到 /usr/bin/ 下。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>cp docker/\* /usr/bin/</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>4. 创建启动单元配置<a href="#4-创建启动单元配置"><span>#</span></a></h4><p>创建启动单元配置 <code>/etc/systemd/system/docker.service</code>，配置示例如下。</p><p>如果有需要，也可以在<code>ExecStart=/usr/bin/dockerd</code>后面加命令行参数，比如我想指定<code>--data-root=/data/docker</code></p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[Unit]</span></div></div><div><div><div>2</div></div><div><span>Description=Docker Application Container Engine</span></div></div><div><div><div>3</div></div><div><span>Documentation=https://docs.docker.com</span></div></div><div><div><div>4</div></div><div><span>After=network-online.target firewalld.service</span></div></div><div><div><div>5</div></div><div><span>Wants=network-online.target</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>[Service]</span></div></div><div><div><div>8</div></div><div><span>Type=notify</span></div></div><div><div><div>9</div></div><div><span>ExecStart=/usr/bin/dockerd</span></div></div><div><div><div>10</div></div><div><span>ExecReload=/bin/kill -s HUP $MAINPID</span></div></div><div><div><div>11</div></div><div><span>LimitNOFILE=infinity</span></div></div><div><div><div>12</div></div><div><span>LimitNPROC=infinity</span></div></div><div><div><div>13</div></div><div><span>TimeoutStartSec=0</span></div></div><div><div><div>14</div></div><div><span>Delegate=yes</span></div></div><div><div><div>15</div></div><div><span>KillMode=process</span></div></div><div><div><div>16</div></div><div><span>Restart=on-failure</span></div></div><div><div><div>17</div></div><div><span>StartLimitBurst=3</span></div></div><div><div><div>18</div></div><div><span>StartLimitInterval=60s</span></div></div><div><div><div>19</div></div><div>
</div></div><div><div><div>20</div></div><div><span>[Install]</span></div></div><div><div><div>21</div></div><div><span>WantedBy=multi-user.target</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>5. 给启动配置赋权<a href="#5-给启动配置赋权"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 给启动配置添加执行权限</span></div></div><div><div><div>2</div></div><div><span>chmod +x /etc/systemd/system/docker.service</span></div></div><div><div><div>3</div></div><div><span># 重载单元服务配置</span></div></div><div><div><div>4</div></div><div><span>systemctl daemon -reload</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>6. 启动docker<a href="#6-启动docker"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 添加 docker 开机自启</span></div></div><div><div><div>2</div></div><div><span>systemctl enable docker</span></div></div><div><div><div>3</div></div><div><span># 启动 docker</span></div></div><div><div><div>4</div></div><div><span>systemctl start docker</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>7. 安装验证<a href="#7-安装验证"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker -v</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h3>三、一键安装法<a href="#三一键安装法"><span>#</span></a></h3><p>如果您觉得上边的步骤繁琐，也可以用下边的办法，一键安装docker。</p><section><h4>3.1 制作docker.service文件<a href="#31-制作dockerservice文件"><span>#</span></a></h4><p>在docker-18.06.3-ce.tgz同目录下，创建docker.service，打开编辑文件，文件内容与2.4节完全一样，此处不再赘述。</p></section><section><h4>3.2 制作一键安装脚本<a href="#32-制作一键安装脚本"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>touch install.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>打开编辑install.sh，将以下内容复制到install.sh，保存退出。</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/bin/sh</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>echo '解压tar包'</span></div></div><div><div><div>4</div></div><div><span>tar -xvf $1</span></div></div><div><div><div>5</div></div><div><span>echo '将docker目录下所有文件复制到/usr/bin目录'</span></div></div><div><div><div>6</div></div><div><span>cp docker/* /usr/bin</span></div></div><div><div><div>7</div></div><div><span>echo '将docker.service 复制到/etc/systemd/system/目录'</span></div></div><div><div><div>8</div></div><div><span>cp docker.service /etc/systemd/system/</span></div></div><div><div><div>9</div></div><div><span>echo '添加文件可执行权限'</span></div></div><div><div><div>10</div></div><div><span>chmod +x /etc/systemd/system/docker.service</span></div></div><div><div><div>11</div></div><div><span>echo '重新加载配置文件'</span></div></div><div><div><div>12</div></div><div><span>systemctl daemon-reload</span></div></div><div><div><div>13</div></div><div><span>echo '启动docker'</span></div></div><div><div><div>14</div></div><div><span>systemctl start docker</span></div></div><div><div><div>15</div></div><div><span>echo '设置开机自启'</span></div></div><div><div><div>16</div></div><div><span>systemctl enable docker.service</span></div></div><div><div><div>17</div></div><div><span>echo 'docker安装成功'</span></div></div><div><div><div>18</div></div><div><span>docker -v</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>3.3 制作一键卸载脚本<a href="#33-制作一键卸载脚本"><span>#</span></a></h4><p>Touch uninstall.sh，将以下内容复制到uninstall.sh，保存退出。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/bin/sh</span></div></div><div><div><div>2</div></div><div><span>echo '停止docker'</span></div></div><div><div><div>3</div></div><div><span>systemctl stop docker</span></div></div><div><div><div>4</div></div><div><span>echo '删除docker.service'</span></div></div><div><div><div>5</div></div><div><span>rm -f /etc/systemd/system/docker.service</span></div></div><div><div><div>6</div></div><div><span>echo '删除docker文件'</span></div></div><div><div><div>7</div></div><div><span>rm -rf /usr/bin/docker*</span></div></div><div><div><div>8</div></div><div><span>echo '重新加载配置文件'</span></div></div><div><div><div>9</div></div><div><span>systemctl daemon-reload</span></div></div><div><div><div>10</div></div><div><span>echo '卸载成功'</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>3.4 安装docker<a href="#34-安装docker"><span>#</span></a></h4><p>此时docker-18.06.3-ce.tgz同目录下，还有上边创建的docker.service，install.sh，uninstall.sh这3个文件：</p><p>分别给install.sh和uninstall.sh赋予可执行权限。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>chmod +x install.sh</span></div></div><div><div><div>2</div></div><div><span>chmod +x uninstall.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>开始安装</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>sh install.sh docker-18.06.3-ce.tgz</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>验证安装</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker -v</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h3>四、docker-compose 离线安装<a href="#四docker-compose-离线安装"><span>#</span></a></h3><section><h4>1. 下载压缩包<a href="#1-下载压缩包-1"><span>#</span></a></h4><p>官方下载地址：<a href="https://github.com/docker/compose/releases" target="_blank">https://github.com/docker/compose/releases</a></p><p>根据实际部署系统版本选择，例如 docker-compose-linux-x86_64，这里下载下来就是一个可执行文件。</p></section><section><h4>2. 将下载文件移动到docker命令所在目录下<a href="#2-将下载文件移动到docker命令所在目录下"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 查看 docker 命令位置，这里为 /usr/bin</span></div></div><div><div><div>2</div></div><div><span>which docker</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 移动并重命名</span></div></div><div><div><div>5</div></div><div><span>mv docker-compose-Linux-x86_64 /usr/bin/docker-compose</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>3. 赋予执行权限<a href="#3-赋予执行权限"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>chmod +x /usr/bin/docker-compose</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>4. 安装验证<a href="#4-安装验证"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker-compose -v</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/f5278043/</id>
      <title type="text">MediaMaster：家庭影音一条龙，使用零门槛</title>
      <published>2026-03-11T18:31:13.000Z</published>
      <updated>2026-03-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/f5278043/"/>
      <summary type="text">本说到家庭影音，很多人第一反应是PT站和自动化工具，但PT门槛高、资源难求、上行限制多，容易被误伤。现在有了全新选择——MediaMaster v2！它是一款支持多站点的NAS影视自动化订阅系统，优化自v1版本，内置优质源站，助新手轻松上手。</summary>
      <content type="html"><![CDATA[<hr />
<section><h2>📖 详细介绍<a href="#-详细介绍"><span>#</span></a></h2><p>🎬 <strong>MediaMaster V2</strong>[1] 是一个开箱即用的影视自动化订阅管理系统。它基于 Python 构建，支持X86_64、ARM64架构，支持多站点资源订阅、自动化下载、媒体库管理，让你可以轻松管理和享受个人媒体内容。</p><hr /></section>
<section><h2>✨ 核心亮点<a href="#-核心亮点"><span>#</span></a></h2><ul>
<li>
<p>• 🎯 <strong>多站点支持</strong>：集成多个资源站，部分站点无需PT账号即可使用。</p>
</li>
<li>
<p>• 🤖 <strong>自动化订阅管理</strong>：通过 Docker 联动实现影视剧集的自动搜索与下载。</p>
</li>
<li>
<p>• 💾 <strong>下载器兼容性强</strong>：支持迅雷、qBittorrent、Transmission 等主流下载器。</p>
</li>
<li>
<p>• 🔗 <strong>软/硬链接转移</strong>：下载内容可自动链接至媒体库，便于整理和播放。</p>
</li>
<li>
<p>• 🎬 <strong>豆瓣想看同步</strong>：可绑定多个豆瓣账号，自动订阅“想看”影片。</p>
</li>
<li>
<p>• 🌱 <strong>新手友好</strong>：0门槛部署，适合NAS用户快速上。</p>
</li>
</ul><hr /></section>
<section><h2>🐳部署指南<a href="#部署指南"><span>#</span></a></h2><section><h3>🎯 Docker Compose<a href="#-docker-compose"><span>#</span></a></h3><p><code>docker-compose.yml 文件</code></p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services:</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>mediamaster:</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>image: docker.1ms.run/smysong/mediamaster-v2:latest</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>container_name: Mediamaster</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>network_mode: host</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>environment:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- UID=1000</span></div></div><div><div><div>8</div></div><div><span><span>      </span></span><span>- GID=1001</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>- GIDLIST=1001修改</span></div></div><div><div><div>10</div></div><div><span><span>      </span></span><span>- TZ=Asia/Shanghai</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>- PORT=9009# 可选配置：自定义设置容器内应用端口，不提供则使用默认8888端口运行</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>volumes:</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span>- /vol1/1000/Media:/Media#媒体库目录，可根据实际进行修改</span></div></div><div><div><div>14</div></div><div><span><span>      </span></span><span>- /vol1/1000/Downloads:/Downloads#下载目录，可根据实际进行修改</span></div></div><div><div><div>15</div></div><div><span><span>      </span></span><span>- ./mediamaster:/config#可根据实际进行修改</span></div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>restart:always</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span># transmission 不需要可删除。</span></div></div><div><div><div>19</div></div><div><span>transmission:</span></div></div><div><div><div>20</div></div><div><span><span>    </span></span><span>image: docker.1ms.run/linuxserver/transmission:latest</span></div></div><div><div><div>21</div></div><div><span><span>    </span></span><span>container_name: Transmission</span></div></div><div><div><div>22</div></div><div><span><span>    </span></span><span>network_mode: host</span></div></div><div><div><div>23</div></div><div><span><span>    </span></span><span>environment:</span></div></div><div><div><div>24</div></div><div><span><span>      </span></span><span>- PUID=1000</span></div></div><div><div><div>25</div></div><div><span><span>      </span></span><span>- PGID=1001</span></div></div><div><div><div>26</div></div><div><span><span>      </span></span><span>- TZ=Asia/Shanghai</span></div></div><div><div><div>27</div></div><div><span><span>    </span></span><span>volumes:</span></div></div><div><div><div>28</div></div><div><span><span>      </span></span><span>- ./transmission:/config#可根据实际进行修改</span></div></div><div><div><div>29</div></div><div><span><span>      </span></span><span>- /vol1/1000/Downloads:/downloads#可根据实际进行修改</span></div></div><div><div><div>30</div></div><div><span><span>    </span></span><span>restart:always</span></div></div><div><div><div>31</div></div><div>
</div></div><div><div><div>32</div></div><div><span># qbittorrent 不需要可删除</span></div></div><div><div><div>33</div></div><div><span>qbittorrent:</span></div></div><div><div><div>34</div></div><div><span><span>    </span></span><span>image: docker.1ms.run/linuxserver/qbittorrent:latest</span></div></div><div><div><div>35</div></div><div><span><span>    </span></span><span>container_name: Qbittorrent</span></div></div><div><div><div>36</div></div><div><span><span>    </span></span><span>network_mode: host</span></div></div><div><div><div>37</div></div><div><span><span>    </span></span><span>environment:</span></div></div><div><div><div>38</div></div><div><span><span>      </span></span><span>- PUID=1000</span></div></div><div><div><div>39</div></div><div><span><span>      </span></span><span>- PGID=1001</span></div></div><div><div><div>40</div></div><div><span><span>      </span></span><span>- WEBUI_PORT=7008#可根据实际进行修改</span></div></div><div><div><div>41</div></div><div><span><span>      </span></span><span>- TORRENTING_PORT=6881#可根据实际进行修改</span></div></div><div><div><div>42</div></div><div><span><span>      </span></span><span>- TZ=Asia/Shanghai</span></div></div><div><div><div>43</div></div><div><span><span>    </span></span><span>volumes:</span></div></div><div><div><div>44</div></div><div><span><span>      </span></span><span>- ./qbittorrent:/config#可根据实际进行修改</span></div></div><div><div><div>45</div></div><div><span><span>      </span></span><span>- /vol1/1000/Downloads:/downloads#可根据实际进行修改</span></div></div><div><div><div>46</div></div><div><span><span>    </span></span><span>restart:always</span></div></div><div><div><div>47</div></div><div>
</div></div><div><div><div>48</div></div><div><span># 迅雷 不需要可删除</span></div></div><div><div><div>49</div></div><div><span>xunlei:</span></div></div><div><div><div>50</div></div><div><span><span>    </span></span><span>image: cnk3x/xunlei:latest</span></div></div><div><div><div>51</div></div><div><span><span>    </span></span><span>privileged: true</span></div></div><div><div><div>52</div></div><div><span><span>    </span></span><span>container_name: xunlei</span></div></div><div><div><div>53</div></div><div><span><span>    </span></span><span>hostname: Fn_Nas</span></div></div><div><div><div>54</div></div><div><span><span>    </span></span><span>network_mode: host</span></div></div><div><div><div>55</div></div><div><span><span>    </span></span><span>volumes:</span></div></div><div><div><div>56</div></div><div><span><span>      </span></span><span>- ./xunlei:/xunlei/data#可根据实际进行修改</span></div></div><div><div><div>57</div></div><div><span><span>      </span></span><span>- /vol1/1000/Downloads:/xunlei/downloads#可根据实际进行修改</span></div></div><div><div><div>58</div></div><div><span><span>    </span></span><span>restart: unless-stopped</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>如果是 <code>单独部署</code> 或 <code>包含下载器-Bridge模式部署</code>，请参考 快速部署[2]</p><hr /><ol>
<li>
<p>1. 在飞牛主页面找到 <code>Docker</code> 打开后，切换菜单 <code>Compose</code> -&gt; <code>新增项目</code></p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/78673bac4b4340198df0649586a45da1640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D0" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
</li>
<li>
<p>2. 填写项目名称与路径，将 <code>docker-compose.yml</code> 内容粘贴到来源框</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/ba1f67e2014743ae9486534c932e5982640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D1" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
</li>
<li>
<p>3. 返回 <code>Docker</code>管理页面，在 <code>容器</code>菜单，就可以看到运行情况</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/85b3139d847a4df4a257ada8a3a699d6640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D2" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
</li>
</ol><hr /></section></section>
<section><h2>📖使用<a href="#使用"><span>#</span></a></h2><ol>
<li>
<p>1. 使用浏览器访问 <code>http://你的NAS地址:9009</code></p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/eb71705e388e49e3a01d5e418acefef1640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D3" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
<p>默认用户名：<code>admin</code> 默认密码：<code>password</code></p>
</li>
<li>
<p>2. 首页</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/b6b46b7c39634a039b91e2d271022109640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D4" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
</li>
<li>
<p>3. 系统设置
点击页面左侧<code>系统设置</code>，进行消息通知，媒体元数据等设置。</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/73e563c5943f49ab84f21498090cb944640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D5" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/58b6bddba4d24151bf37239bf979bc8c640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D6" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
<p>豆瓣订阅用户ID获取参考使用帮助[3]；TMDB API密钥默认内置了。如果自己有，尽量使用自己的密钥。</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/6ff364378f84401d9ade30d445c69d32640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D7" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
<p>迅雷下载需要进行配置，请参考迅雷下载功能如何使用？[4]</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/0d5b6bf9b891480186f411f60cd6131a640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D8" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
<p>私有（付费注册）站点配置说明： 私有站点支持：高清剧集网[5]、高清影视之家[6]</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/8663c47d23514b0fadacb44f827fa917640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D9" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
<p>公开（免费注册）站点配置说明： 公开站点支持：不太灵影视[7]、观影[8]、BT影视[9]</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/dc7bbde8c3fe49f8892c6802aecae8a1640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D10" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
<p>站点索引开关和定时任务根据自己喜好进行设置。</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/323c79a6880f4bf690395d3cb3fe2f8f640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D11" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
<p>最后记得点击页面右上角<code>保存配置</code> 进行保存。</p>
</li>
<li>
<p>4. 热门推荐
切换左侧的热门推荐，这里是 The Movie DataBase 里推荐的当前热门影视剧信息。</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/21e7b13d17424a98a41c7869cb9534fe640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D12" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
</li>
<li>
<p>5. 正在订阅
管理 正在订阅的电视剧/电影</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/442da3e37b594a97b83e3f83713dfd3c640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D13" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
</li>
<li>
<p>6. 资源搜索
可以搜索并下载你追的电视剧/电影</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/0197549d3c4f44b9be11898a82277098640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D14" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/fb79a3ff9564423cb9f481f89811b867640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D15" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
</li>
<li>
<p>7. 下载管理
可以查看下载的电视剧/电影</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/books@main/covers/2025/11/d0bec03cde0842ffb92f5eba706c49ec640%3Fwx_fmt%3Dpng%26watermark%3D1%23imgIndex%3D16" alt="图片" title="null" /><figcaption>图片</figcaption></figure><p></p>
</li>
</ol></section>
<section><h2>🎉 总结<a href="#-总结"><span>#</span></a></h2><p><strong>MediaMaster</strong> 基础功能已基本完善，在资源推荐、搜索、下载、刮削等方面表现不错。适合不熟PT、又懒得用TG找网盘资源的用户，真正实现一站式家庭影音体验。不过目前免费站点资源仍较匮乏，若后期支持自定义源，将更具扩展性与实用性。</p><section><h4>引用链接<a href="#引用链接"><span>#</span></a></h4><p><code>[1]</code> MediaMaster V2:<em><a href="https://github.com/smysong/mediamaster-v2" target="_blank">https://github.com/smysong/mediamaster-v2</a></em>
<code>[2]</code>快速部署:<em><a href="http://wiki.songmy.top:8080/web/#/686311457/102215684" target="_blank">http://wiki.songmy.top:8080/web/#/686311457/102215684</a></em>
<code>[3]</code>使用帮助:<em><a href="http://wiki.songmy.top:8080/web/#/686311457/102215711" target="_blank">http://wiki.songmy.top:8080/web/#/686311457/102215711</a></em>
<code>[4]</code>迅雷下载:<em><a href="http://wiki.songmy.top:8080/web/#/686311457/102215687" target="_blank">http://wiki.songmy.top:8080/web/#/686311457/102215687</a></em>
<code>[5]</code>高清剧集网:<em><a href="https://www.bthdtv.com/" target="_blank">https://www.bthdtv.com/</a></em>
<code>[6]</code>高清影视之家:<em><a href="https://www.hdbthd.com/" target="_blank">https://www.hdbthd.com/</a></em>
<code>[7]</code>不太灵影视:<em><a href="https://www.butailing.com/" target="_blank">https://www.butailing.com/</a></em>
<code>[8]</code>观影:<em><a href="https://www.gyg.si/" target="_blank">https://www.gyg.si/</a></em>
<code>[9]</code>BT影视:<em><a href="https://www.btbtl.com/" target="_blank">https://www.btbtl.com/</a></em></p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/2b7b9ef8/</id>
      <title type="text">发现宝藏音乐播放器！MusicFree 让你告别广告和会员，想听什么听什么</title>
      <published>2026-02-23T12:32:13.000Z</published>
      <updated>2026-02-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/2b7b9ef8/"/>
      <summary type="text">你们有没有过这样的经历？打开音乐 app，满屏的广告，想听首歌还要开会员，不然只能试听 30 秒；想换个播放器，结果又要重新收藏歌单，麻烦得要命。最近我发现了一个叫 **MusicFree** 的音乐播放器，简直是音乐爱好者的福音！今天必须强烈安利给你们！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！我发现了一个超牛的音乐播放器！<a href="#朋友们我发现了一个超牛的音乐播放器"><span>#</span></a></h2><p>你们有没有过这样的经历？</p><p>打开音乐 app，满屏的广告，想听首歌还要开会员，不然只能试听 30 秒；想换个播放器，结果又要重新收藏歌单，麻烦得要命。</p><p>最近我发现了一个叫 <strong>MusicFree</strong> 的音乐播放器，简直是音乐爱好者的福音！今天必须强烈安利给你们！</p></section>
<section><h2>什么是 MusicFree？<a href="#什么是-musicfree"><span>#</span></a></h2><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/2d70957b296f430793a96c668efd251c20260402104729324.png" alt="" /></p><p>MusicFree 是一个插件化、定制化、无广告的免费音乐播放器，有移动端和桌面端两个版本：</p><ul>
<li><strong>移动端</strong>：支持 Android 和 Harmony OS</li>
<li><strong>桌面端</strong>：支持 Windows、macOS、Linux</li>
</ul></section>
<section><h2>为什么我这么喜欢 MusicFree？<a href="#为什么我这么喜欢-musicfree"><span>#</span></a></h2><section><h3>1️⃣ 完全免费，无广告<a href="#1️⃣-完全免费无广告"><span>#</span></a></h3><p>最重要的是，MusicFree 完全免费，没有任何广告！不像某些音乐 app，打开就是广告，听两首歌又弹广告，烦都烦死了。</p></section><section><h3>2️⃣ 插件化设计，想听什么听什么<a href="#2️⃣-插件化设计想听什么听什么"><span>#</span></a></h3><p>MusicFree 采用插件化设计，通过安装不同的插件，你可以收听来自不同平台的音乐，比如网易云、QQ音乐、酷狗等，再也不用为了听不同平台的歌而切换 app 了！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/1d23af688f2f4075b59ef95b7b91a11920260402104825485.png" alt="" /></p></section><section><h3>3️⃣ 定制化程度高<a href="#3️⃣-定制化程度高"><span>#</span></a></h3><p>MusicFree 支持自定义主题、背景，你可以根据自己的喜好打造属于自己的音乐播放器，超级个性化！</p></section><section><h3>4️⃣ 多平台支持<a href="#4️⃣-多平台支持"><span>#</span></a></h3><p>不管你是用手机还是电脑，都能使用 MusicFree，而且数据可以同步，超级方便！</p></section><section><h3>5️⃣ 功能丰富<a href="#5️⃣-功能丰富"><span>#</span></a></h3><p>MusicFree 支持搜索音乐、专辑、艺术家，播放音乐，查看专辑和艺术家详情，导入单曲和播放列表，获取歌词等功能，满足你对音乐播放器的所有需求。</p></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>前几天我下载了 MusicFree 桌面版，使用体验真的惊艳到我了：</p><ol>
<li>界面简洁美观，没有乱七八糟的广告</li>
<li>通过插件，我可以搜索到各个平台的音乐，想听什么就听什么</li>
<li>支持自定义主题，我设置了一个我喜欢的深色主题，看起来超级舒服</li>
<li>歌词显示功能很贴心，还支持搜索歌词</li>
<li>播放列表管理也很方便，我可以轻松导入和管理我的歌单</li>
</ol></section>
<section><h2>如何开始使用？<a href="#如何开始使用"><span>#</span></a></h2><section><h3>下载安装<a href="#下载安装"><span>#</span></a></h3><ul>
<li><strong>移动端</strong>：去 GitHub 搜索 “MusicFree”，下载对应版本安装</li>
<li><strong>桌面端</strong>：去 GitHub 搜索 “MusicFreeDesktop”，下载对应系统的安装包安装</li>
</ul></section><section><h3>配置插件源<a href="#配置插件源"><span>#</span></a></h3><p>使用 MusicFree 的关键是配置插件源，这样你才能获取到各种音乐平台的插件。</p><p><strong>注意</strong>：不想找插件源的话，可以私信我发送【musicfree】获取哦！</p><p>配置步骤：</p><ol>
<li>打开 MusicFree</li>
<li>进入设置页面</li>
<li>找到插件源设置</li>
<li>输入我私信给你的插件源 URL</li>
<li>点击确定，等待插件加载完成</li>
</ol></section><section><h3>开始使用<a href="#开始使用"><span>#</span></a></h3><p>配置好插件源后，你就可以：</p><ol>
<li>搜索你喜欢的音乐</li>
<li>创建和管理播放列表</li>
<li>自定义播放器外观</li>
<li>享受无广告的音乐体验</li>
</ol></section></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>音乐爱好者</strong>：不想被广告打扰，想听什么就听什么</li>
<li><strong>学生党</strong>：预算有限，不想为音乐会员付费</li>
<li><strong>上班族</strong>：通勤路上想听音乐，不想被广告打断</li>
<li><strong>任何人</strong>：只要你喜欢听歌，想拥有一个干净、自由的音乐播放器</li>
</ul></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>MusicFree 真的是一个宝藏音乐播放器，它插件化的设计让你可以收听来自不同平台的音乐，定制化的功能让你可以打造属于自己的播放器，最重要的是，它完全免费，没有广告！</p><p>如果你也受够了市面上那些充满广告和会员限制的音乐 app，一定要试试 MusicFree，相信你会和我一样爱上它！</p></section>
<section><h2>如何获取插件源？<a href="#如何获取插件源"><span>#</span></a></h2><p>想要使用 MusicFree 的全部功能，你需要配置插件源。插件源的 URL 我会私信发给关注我的微信公众号的朋友。</p><p><strong>获取步骤</strong>：</p><ol>
<li>关注我的微信公众号</li>
<li>发送 “MusicFree” 到公众号</li>
<li>我会私信给你插件源的 URL</li>
</ol></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><ul>
<li><strong>移动端</strong>：<a href="https://github.com/maotoumao/MusicFree" target="_blank">https://github.com/maotoumao/MusicFree</a></li>
<li><strong>桌面端</strong>：<a href="https://github.com/maotoumao/MusicFreeDesktop" target="_blank">https://github.com/maotoumao/MusicFreeDesktop</a></li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时用什么音乐播放器？有没有遇到和我一样的困扰？欢迎在评论区分享你的故事！</p><p>如果觉得这篇文章有用，别忘了点赞、在看并分享给身边喜欢听歌的朋友们～</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="http://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2046857375&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
<li><a href="http://mp.weixin.qq.com/s/vs0eBElh1Tq9AbbVd126WA?token=2046857375&amp;lang=zh_CN" target="_blank">LX Sync Server 部署指南：轻松搭建自己的洛雪音乐服务</a></li>
<li><a href="http://mp.weixin.qq.com/s/ZhQVxaFDw1q3ut0lbht3AQ?token=2046857375&amp;lang=zh_CN" target="_blank">太爽了！这个免费工具让你的小说变成有声书，再也不用盯着屏幕看了</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/35f5edc5/</id>
      <title type="text">需要简历不用愁！OpResume 免登录在线简历生成器，数据本地存储更安全</title>
      <published>2026-02-23T12:32:13.000Z</published>
      <updated>2026-02-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/35f5edc5/"/>
      <summary type="text">今天我要给大家推荐一个超好用的在线简历生成器——**OpResume**，它免登录、高颜值，而且数据仅存储在本地，不用担心隐私泄露的问题！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！找工作、申请学校需要简历怎么办？<a href="#朋友们找工作申请学校需要简历怎么办"><span>#</span></a></h2><p>最近有读者在后台问我：“小王，有没有好用的简历生成工具推荐？“，确实，简历是我们找工作、申请学校时必不可少的材料，一份好的简历能让你在众多竞争者中脱颖而出。</p><p>今天我要给大家推荐一个超好用的在线简历生成器——<strong>OpResume</strong>，它免登录、高颜值，而且数据仅存储在本地，不用担心隐私泄露的问题！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/a02bb8f5f1f4469d838d66e62aa3559920260409172353707.png" alt="" /></p></section>
<section><h2>什么是 OpResume？<a href="#什么是-opresume"><span>#</span></a></h2><p>OpResume 是一个免登录、高颜值的在线简历生成器，它的特点是数据仅本地存储，无泄漏风险，随时可以导出简历。</p></section>
<section><h2>为什么推荐 OpResume？<a href="#为什么推荐-opresume"><span>#</span></a></h2><section><h3>1️⃣ 免登录，即用即走<a href="#1️⃣-免登录即用即走"><span>#</span></a></h3><p>OpResume 不需要注册登录，打开网页就能使用，非常方便。你不需要填写任何个人信息，也不用担心账号安全问题。</p></section><section><h3>2️⃣ 数据本地存储，隐私安全<a href="#2️⃣-数据本地存储隐私安全"><span>#</span></a></h3><p>所有数据都存储在你的浏览器本地，不会上传到任何服务器，完全不用担心个人信息泄露的风险。</p></section><section><h3>3️⃣ 高颜值模板<a href="#3️⃣-高颜值模板"><span>#</span></a></h3><p>OpResume 提供了多种高颜值的简历模板，你可以根据自己的需求选择适合的模板，让你的简历看起来更加专业、美观。</p></section><section><h3>4️⃣ 操作简单，上手快<a href="#4️⃣-操作简单上手快"><span>#</span></a></h3><p>OpResume 的界面简洁直观，操作非常简单，即使是第一次使用，也能很快上手。</p></section><section><h3>5️⃣ 随时导出，格式多样<a href="#5️⃣-随时导出格式多样"><span>#</span></a></h3><p>你可以随时导出简历，支持多种格式，方便你在不同场合使用。</p></section></section>
<section><h2>如何使用 OpResume？<a href="#如何使用-opresume"><span>#</span></a></h2><section><h3>步骤1：访问在线地址<a href="#步骤1访问在线地址"><span>#</span></a></h3><p>打开浏览器，访问 OpResume 的在线地址：<a href="https://opresume.pages.dev/" target="_blank">https://opresume.pages.dev/</a></p></section><section><h3>步骤2：选择模板<a href="#步骤2选择模板"><span>#</span></a></h3><p>在首页选择一个你喜欢的简历模板。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/a9f1a0c15ba2490b86675a0070b4394520260409172442759.png" alt="" /></p></section><section><h3>步骤3：填写信息<a href="#步骤3填写信息"><span>#</span></a></h3><p>根据模板的提示，填写你的个人信息、教育背景、工作经历、项目经验等内容。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/3d22344d342c4098a5eda171e585e55720260409172520882.png" alt="" /></p></section><section><h3>步骤4：预览简历<a href="#步骤4预览简历"><span>#</span></a></h3><p>填写完成后，你可以实时预览简历的效果，根据需要进行调整。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/d7b45034483c4d5b8011b7dbbb02ca2720260409172725872.png" alt="" /></p></section><section><h3>步骤5：导出简历<a href="#步骤5导出简历"><span>#</span></a></h3><p>满意后，点击导出按钮，选择你需要的格式，下载简历。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/d94ebe66a70b4f6cb5c6ad2b71634f6620260409172742759.png" alt="" /></p></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>前几天我试用了 OpResume，体验真的非常好：</p><ol>
<li><strong>免登录</strong>：打开网页就能使用，不用填写任何个人信息</li>
<li><strong>界面美观</strong>：模板设计非常现代，看起来很专业</li>
<li><strong>操作简单</strong>：填写信息的过程非常流畅，没有复杂的操作</li>
<li><strong>实时预览</strong>：可以实时看到简历的效果，方便调整</li>
<li><strong>导出方便</strong>：支持多种格式导出，满足不同需求</li>
</ol><p>最重要的是，所有数据都存储在本地，不用担心隐私泄露的问题，这一点真的很贴心！</p></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>求职者</strong>：需要制作简历找工作</li>
<li><strong>学生</strong>：申请学校、实习需要简历</li>
<li><strong>职场人士</strong>：更新简历，寻求更好的职业机会</li>
<li><strong>任何人</strong>：需要制作专业简历的人</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 OpResume 感兴趣，可以访问它的 GitHub 仓库：<a href="https://github.com/oopooa/opresume" target="_blank">https://github.com/oopooa/opresume</a></p></section>
<section><h2>在线地址<a href="#在线地址"><span>#</span></a></h2><p>你可以直接访问 OpResume 的在线地址开始使用：<a href="https://opresume.pages.dev/" target="_blank">https://opresume.pages.dev/</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时是如何制作简历的？使用 OpResume 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=102365809&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/kG5HvrifueIWsHaWWdTbrQ?token=102365809&amp;lang=zh_CN" target="_blank">发现宝藏聚合软件！益达 APP 让你告别多 app 切换，一个软件看遍小说漫画影视</a></li>
<li><a href="http://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2046857375&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/6649970a/</id>
      <title type="text">挖到宝了！这款免费影视神器，聚合全网资源还能多端同步，错过亏大了！</title>
      <published>2026-02-23T12:32:13.000Z</published>
      <updated>2026-02-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/6649970a/"/>
      <summary type="text">你是不是也遇到过这些问题？想看的剧分散在 N 个平台，充值会员看到手软；换个设备追剧，进度总是要重新找；网页端广告弹窗比剧情还精彩... 今天给大家安利一款开源宝藏工具 ——MoonTV，一个能把这些烦恼一次性解决的影视聚合播放器。亲测好用到飞起，必须分享给你们！</summary>
      <content type="html"><![CDATA[<p>你是不是也遇到过这些问题？想看的剧分散在 N 个平台，充值会员看到手软；换个设备追剧，进度总是要重新找；网页端广告弹窗比剧情还精彩…</p>
<p>今天给大家安利一款开源宝藏工具 ——<strong>MoonTV</strong>，一个能把这些烦恼一次性解决的影视聚合播放器。亲测好用到飞起，必须分享给你们！</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/07/cd3b7bec70704b20a284b6b2b8991516image-20250726090117801.png" alt="image-20250726090117801" /><figcaption>image-20250726090117801</figcaption></figure><p></p>
<section><h2>✨ 它到底有多能打？<a href="#-它到底有多能打"><span>#</span></a></h2><p>作为一款基于 Next.js 构建的跨平台工具，MoonTV 的功能简直是为追剧党量身定做：</p><p>✅ <strong>全网资源一键搜</strong>：内置数十个免费影视站点，不用再逐个平台切换，一次搜索就能 get 所有结果</p><p>✅ <strong>追剧进度不丢失</strong>：不管在手机、电脑还是平板上看，收藏和播放记录自动同步，再也不用记住看到第几集</p><p>✅ <strong>无广告纯净体验</strong>：实验性的智能去广告功能，自动跳过视频切片广告，追剧更沉浸</p><p>✅ <strong>能装到桌面 / 手机</strong>：支持 PWA 安装，像原生 App 一样使用，离线也能缓存内容</p><p>✅ <strong>完全免费开源</strong>：代码透明可查，没有隐藏收费，还能自己部署到服务器</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/07/8870ee3dbb134a04872c368dd4963ed3image-20250726094152924.png" alt="image-20250726094152924" /><figcaption>image-20250726094152924</figcaption></figure><p></p></section>
<section><h2>🚀 小白也能轻松上手<a href="#-小白也能轻松上手"><span>#</span></a></h2><p>最让人惊喜的是，它的部署门槛低到离谱，几种方式任你选：</p><p>👉 Docker 部署（懒人首选）</p><p>这种方式操作简单，30 秒就能搞定部署，适合对技术不太熟悉的小白。</p><ol>
<li>
<p>首先确保你的电脑或服务器已经安装了 Docker，如果没有，可以去 Docker 官网下载并安装对应版本的 Docker Desktop。</p>
</li>
<li>
<p>打开终端或命令提示符，输入以下命令：docker run -d -p 3000&lt;3000&gt; —name moontv senshinya/moontv</p>
</li>
<li>
<p>等待命令执行完成，然后在浏览器中输入<a href="http://localhost:3000/" target="_blank">http://localhost&lt;3000&gt;</a>，就可以访问 MoonTV 了。</p>
</li>
</ol><p>👉 部署到 Vercel（免费方案）</p><p>Vercel 提供了免费的部署服务，适合不想自己搭建服务器的用户。</p><ol>
<li>
<p>首先你需要有一个 GitHub 账号，并且将 MoonTV 仓库 Fork 到自己的账号下。</p>
</li>
<li>
<p>访问 Vercel 官网，使用 GitHub 账号登录。</p>
</li>
<li>
<p>在 Vercel dashboard 中，点击 “New Project”，然后选择你 Fork 的 MoonTV 仓库。</p>
</li>
<li>
<p>点击 “Deploy” 按钮，Vercel 会自动进行部署，等待部署完成后，会生成一个访问链接，通过该链接即可访问你的 MoonTV。</p>
</li>
</ol><p>👉 部署到 Cloudflare（免费方案）</p><p>Cloudflare 的 Pages 服务也是免费的，部署步骤如下。</p><ol>
<li>
<p>同样需要先将 MoonTV 仓库 Fork 到自己的 GitHub 账号。</p>
</li>
<li>
<p>登录 Cloudflare 账号，进入 Pages 服务页面。</p>
</li>
<li>
<p>点击 “Create a project”，选择 “Connect to Git”，然后选择你 Fork 的 MoonTV 仓库。</p>
</li>
<li>
<p>在配置页面，框架预设选择 “Next.js”，然后点击 “Deploy site”。</p>
</li>
<li>
<p>等待部署完成，Cloudflare 会生成一个访问域名，通过该域名就能使用 MoonTV 了。</p>
</li>
</ol><p>部署后还能自定义站点名称、公告，甚至添加自己常用的资源站，完全按你的喜好来定制。而且搭配 Redis 还能实现多设备同步，支持多账户管理，家庭共用也方便。</p><p>部署后还能自定义站点名称、公告，甚至添加自己常用的资源站，完全按你的喜好来定制。</p></section>
<section><h2>🛡️ 安全提示要记牢<a href="#️-安全提示要记牢"><span>#</span></a></h2><p>虽然好用，但也要提醒大家：</p><ol>
<li>部署时一定要设置密码，避免被陌生人滥用</li>
<li>仅供个人学习使用，不要公开分享你的站点</li>
<li>遵守当地法律法规，合理使用网络资源</li>
</ol></section>
<section><h2>🌟 最后说两句<a href="#-最后说两句"><span>#</span></a></h2><p>现在市面上的影视工具要么广告泛滥，要么收费高昂，MoonTV 这种开源免费还好用的实属难得。</p><p>如果你也是个追剧爱好者，或者想搭一个私人影视库，这个项目绝对值得试试。项目地址我放下面了，记得给开发者点个星哦～</p><p>👉 <a href="https://github.com/senshinya/MoonTV" target="_blank">MoonTV 项目地址</a></p><p>（注：请支持正版影视内容，合理使用工具，遵守相关规定）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/6954e087/</id>
      <title type="text">开源 LibreTV：一款开源免费的在线视频搜索神器，一键部署私人观影平台</title>
      <published>2026-02-23T12:32:13.000Z</published>
      <updated>2026-02-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/6954e087/"/>
      <summary type="text">最近发现了一个超赞的开源项目——LibreTV，这是一款轻量级、免费的在线视频搜索与观看平台。无需注册登录，打开就能用，还支持多设备访问。今天就来给大家详细介绍下这个项目，以及如何快速部署属于自己的私人观影实例。</summary>
      <content type="html"><![CDATA[<p>最近发现了一个超赞的开源项目——LibreTV，这是一款轻量级、免费的在线视频搜索与观看平台。无需注册登录，打开就能用，还支持多设备访问。今天就来给大家详细介绍下这个项目，以及如何快速部署属于自己的私人观影实例。</p>
<section><h2>🌟 LibreTV 是什么？<a href="#-libretv-是什么"><span>#</span></a></h2><p>LibreTV 是一个基于 Web 技术的视频搜索与播放平台，它聚合了多个视频源，让你能轻松找到想看的内容。项目基于 bestK/tv 重构增强，保留了核心功能并优化了用户体验。</p><p>最吸引人的是，它完全开源免费，没有广告干扰，还支持自行部署，打造专属的无广告观影环境。</p>
  点击查看项目截图
  <img src="https://github.com/user-attachments/assets/df485345-e83b-4564-adf7-0680be92d3c7" alt="LibreTV 项目截图" />
</section>
<section><h2>🚀 技术栈解析<a href="#-技术栈解析"><span>#</span></a></h2><p>作为技术爱好者，不得不提一下它的技术栈：</p><ul>
<li>前端：HTML5 + CSS3 + JavaScript (ES6+)、Tailwind CSS</li>
<li>视频播放：HLS.js 处理流媒体、DPlayer 作为播放器核心</li>
<li>后端：支持 Cloudflare/Vercel/Netlify 等 Serverless 环境</li>
<li>存储：使用 localStorage 保存播放记录</li>
</ul><p>这种技术组合让它既能保证良好的用户体验，又能灵活部署在各种平台上。</p></section>
<section><h2>🔧 多种部署方式任选<a href="#-多种部署方式任选"><span>#</span></a></h2><p>LibreTV 支持多种部署方式，无论你是技术小白还是资深开发者，都能找到适合自己的方案。</p><section><h3>1. 一键部署（推荐新手）<a href="#1-一键部署推荐新手"><span>#</span></a></h3><p>几个主流平台都支持一键部署，点击按钮即可：</p><ul>
<li><a href="https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FLibreSpark%2FLibreTV" target="_blank"><figure><img src="https://vercel.com/button" alt="Deploy with Vercel" /><figcaption>Deploy with Vercel</figcaption></figure></a></li>
<li><a href="https://app.netlify.com/start/deploy?repository=https://github.com/LibreSpark/LibreTV" target="_blank"><figure><img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify" /><figcaption>Deploy to Netlify</figcaption></figure></a></li>
<li><a href="https://render.com/deploy?repo=https://github.com/LibreSpark/LibreTV" target="_blank"><figure><img src="https://render.com/images/deploy-to-render-button.svg" alt="Deploy to Render" /><figcaption>Deploy to Render</figcaption></figure></a></li>
</ul></section><section><h3>2. Docker 部署（推荐有服务器用户）<a href="#2-docker-部署推荐有服务器用户"><span>#</span></a></h3><p>如果你有自己的服务器，Docker 部署是个好选择：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>--name</span><span> </span><span>libretv</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>--restart</span><span> </span><span>unless-stopped</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>-p</span><span> </span><span>8899:8080</span><span> </span><span>\</span></div></div><div><div><div>5</div></div><div><span>  </span><span>-e</span><span> </span><span>PASSWORD=你的密码</span><span> </span><span>\</span></div></div><div><div><div>6</div></div><div><span>  </span><span>-e</span><span> </span><span>ADMINPASSWORD=管理员密码</span><span> </span><span>\</span></div></div><div><div><div>7</div></div><div><span>  </span><span>bestzwei/libretv:latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>启动后访问 <code>http://服务器IP:8899</code> 即可。</p><p>或者使用 Docker Compose：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>libretv</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image</span><span>: </span><span>bestzwei/libretv:latest</span></div></div><div><div><div>4</div></div><div><span>    </span><span>container_name</span><span>: </span><span>libretv</span></div></div><div><div><div>5</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>6</div></div><div><span><span>      </span></span><span>- </span><span>"8899:8080"</span></div></div><div><div><div>7</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>8</div></div><div><span><span>      </span></span><span>- </span><span>PASSWORD=你的密码</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>- </span><span>ADMINPASSWORD=管理员密码</span></div></div><div><div><div>10</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>启动命令：<code>docker compose up -d</code></p></section><section><h3>3. 本地开发环境（适合开发者）<a href="#3-本地开发环境适合开发者"><span>#</span></a></h3><p>如果你想研究源码或参与开发，可以搭建本地环境：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 克隆仓库</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/LibreSpark/LibreTV.git</span></div></div><div><div><div>3</div></div><div><span>cd</span><span> </span><span>LibreTV</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># 安装依赖</span></div></div><div><div><div>6</div></div><div><span>npm</span><span> </span><span>install</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span># 配置环境变量（可选）</span></div></div><div><div><div>9</div></div><div><span>cp</span><span> </span><span>.env.example</span><span> </span><span>.env</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span># 启动开发服务器</span></div></div><div><div><div>12</div></div><div><span>npm</span><span> </span><span>run</span><span> </span><span>dev</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>访问 <code>http://localhost:8080</code> 即可使用。</p></section></section>
<section><h2>🔒 安全设置建议<a href="#-安全设置建议"><span>#</span></a></h2><p>为了避免不必要的麻烦，强烈建议进行以下安全设置：</p><ol>
<li><strong>设置密码保护</strong>：在部署时添加 <code>PASSWORD</code> 环境变量，设置访问密码</li>
<li><strong>限制访问范围</strong>：尽量只在个人或小范围使用，不要公开分享</li>
<li><strong>遵守法律法规</strong>：确保你的使用行为符合当地法律要求</li>
</ol><p>各平台设置环境变量的位置：</p><ul>
<li>Cloudflare Pages：项目设置 &gt; 环境变量</li>
<li>Vercel：项目 Settings &gt; Environment Variables</li>
<li>Netlify：项目 Site settings &gt; Build &amp; deploy &gt; Environment</li>
</ul></section>
<section><h2>🎁 为什么选择 LibreTV？<a href="#-为什么选择-libretv"><span>#</span></a></h2><ul>
<li><strong>开源免费</strong>：完全开源，无任何隐藏收费</li>
<li><strong>无需注册</strong>：打开就能用，保护隐私</li>
<li><strong>多源聚合</strong>：聚合多个视频源，内容更丰富</li>
<li><strong>轻量高效</strong>：界面简洁，加载快速</li>
<li><strong>自定义强</strong>：支持自行部署和个性化配置</li>
</ul></section>
<section><h2>📝 最后声明<a href="#-最后声明"><span>#</span></a></h2><p>LibreTV 仅作为视频搜索工具，不存储、上传或分发任何视频内容。所有视频均来自第三方 API 接口提供的搜索结果。使用时请遵守当地法律法规，支持正版内容。</p><p>如果你觉得这个项目不错，不妨去 GitHub 给个 Star 支持一下：<a href="https://github.com/LibreSpark/LibreTV" target="_blank">https://github.com/LibreSpark/LibreTV</a></p><p>希望这篇介绍对你有帮助，祝大家观影愉快！</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/90a28841/</id>
      <title type="text">搜集安卓端、TV 端、苹果端、Windows 端、Mac 端各种版本的影视盒子下载地址</title>
      <published>2026-02-23T12:32:13.000Z</published>
      <updated>2026-02-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/90a28841/"/>
      <summary type="text">本文汇总了多平台影视盒子下载资源，涵盖安卓端（手机、平板）、TV端（电视、电视盒子）、苹果端（iPhone、iPad）、Windows端及Mac端等设备，同时包括Linux、鸿蒙等其他设备支持。文档按设备类型分类，列出各软件专区（如影视仓、OK影视、UZ影视等）的不同版本及对应下载链接，方便用户按需获取各类影视观看工具。</summary>
      <content type="html"><![CDATA[<section><h3>1. 安卓端（含手机、平板）<a href="#1-安卓端含手机平板"><span>#</span></a></h3>

<table><thead><tr><th>软件专区</th><th>版本类型</th><th>下载链接</th></tr></thead><tbody><tr><td>影视仓空壳专区</td><td>安卓端</td><td><a href="https://streamshare.wireway.ch/download/dhpo6wqq" target="_blank">https://streamshare.wireway.ch/download/dhpo6wqq</a></td></tr><tr><td>OK 影视空壳专区 okjack</td><td>安卓端 - v7a</td><td><a href="https://gh-proxy.com/https://github.com/FongMi/Release/blob/okjack/apk/release/mobile-armeabi_v7a.apk" target="_blank">https://gh-proxy.com/https://github.com/FongMi/Release/blob/okjack/apk/release/mobile-armeabi_v7a.apk</a></td></tr><tr><td>OK 影视空壳专区 okjack</td><td>安卓端 - v8a</td><td><a href="https://gh-proxy.com/https://github.com/FongMi/Release/blob/okjack/apk/release/mobile-arm64_v8a.apk" target="_blank">https://gh-proxy.com/https://github.com/FongMi/Release/blob/okjack/apk/release/mobile-arm64_v8a.apk</a></td></tr><tr><td>OK 影视空壳专区 Fongmi</td><td>安卓端 - v7a</td><td><a href="https://gh-proxy.com/https://github.com/FongMi/Release/blob/fongmi/apk/release/mobile-armeabi_v7a.apk" target="_blank">https://gh-proxy.com/https://github.com/FongMi/Release/blob/fongmi/apk/release/mobile-armeabi_v7a.apk</a></td></tr><tr><td>OK 影视空壳专区 Fongmi</td><td>安卓端 - v8a</td><td><a href="https://gh-proxy.com/https://github.com/FongMi/Release/blob/fongmi/apk/release/mobile-arm64_v8a.apk" target="_blank">https://gh-proxy.com/https://github.com/FongMi/Release/blob/fongmi/apk/release/mobile-arm64_v8a.apk</a></td></tr><tr><td>OK 影视 PRO 空壳专区</td><td>安卓端</td><td><a href="https://streamshare.wireway.ch/download/c4l80qsz" target="_blank">https://streamshare.wireway.ch/download/c4l80qsz</a></td></tr><tr><td>UZ 影视空壳专区</td><td>安卓端</td><td><a href="https://streamshare.wireway.ch/download/1iewmue8" target="_blank">https://streamshare.wireway.ch/download/1iewmue8</a></td></tr><tr><td>蛋播星球专区 (内置源)</td><td>安卓端</td><td><a href="https://streamshare.wireway.ch/download/kyvbchy8" target="_blank">https://streamshare.wireway.ch/download/kyvbchy8</a></td></tr><tr><td>ClashMeta 专区</td><td>安卓端 v7a</td><td><a href="https://gh-proxy.com/https://github.com/MetaCubeX/ClashMetaForAndroid/releases/download/v2.11.15/cmfa-2.11.15-meta-armeabi-v7a-release.apk" target="_blank">https://gh-proxy.com/https://github.com/MetaCubeX/ClashMetaForAndroid/releases/download/v2.11.15/cmfa-2.11.15-meta-armeabi-v7a-release.apk</a></td></tr><tr><td>ClashMeta 专区</td><td>安卓端 v8a</td><td><a href="https://gh-proxy.com/https://github.com/MetaCubeX/ClashMetaForAndroid/releases/download/v2.11.15/cmfa-2.11.15-meta-arm64-v8a-release.apk" target="_blank">https://gh-proxy.com/https://github.com/MetaCubeX/ClashMetaForAndroid/releases/download/v2.11.15/cmfa-2.11.15-meta-arm64-v8a-release.apk</a></td></tr><tr><td>ClashMi 专区</td><td>安卓端</td><td><a href="https://dot.clashmi.app/client.html?tag=android-stable" target="_blank">https://dot.clashmi.app/client.html?tag=android-stable</a></td></tr><tr><td>Karing 专区</td><td>安卓端</td><td><a href="https://dot.karing.app/client.html?tag=android-stable" target="_blank">https://dot.karing.app/client.html?tag=android-stable</a></td></tr></tbody></table><hr /></section>
<section><h3>2. TV 端（含电视、电视盒子）<a href="#2-tv-端含电视电视盒子"><span>#</span></a></h3>

<table><thead><tr><th>软件专区</th><th>版本类型</th><th>下载链接</th></tr></thead><tbody><tr><td>影视仓空壳专区</td><td>TV 端</td><td><a href="https://streamshare.wireway.ch/download/sbv5fvw4" target="_blank">https://streamshare.wireway.ch/download/sbv5fvw4</a></td></tr><tr><td>OK 影视空壳专区 okjack</td><td>TV 端 - v7a</td><td><a href="https://gh-proxy.com/https://github.com/FongMi/Release/blob/okjack/apk/release/leanback-armeabi_v7a.apk" target="_blank">https://gh-proxy.com/https://github.com/FongMi/Release/blob/okjack/apk/release/leanback-armeabi_v7a.apk</a></td></tr><tr><td>OK 影视空壳专区 okjack</td><td>TV 端 - v8a</td><td><a href="https://gh-proxy.com/https://github.com/FongMi/Release/blob/okjack/apk/release/leanback-arm64_v8a.apk" target="_blank">https://gh-proxy.com/https://github.com/FongMi/Release/blob/okjack/apk/release/leanback-arm64_v8a.apk</a></td></tr><tr><td>OK 影视空壳专区 okjack</td><td>海信专用</td><td><a href="https://gh-proxy.com/https://github.com/FongMi/Release/blob/okjack/apk/release/%E6%B5%B7%E4%BF%A1%E4%B8%93%E7%89%88.apk" target="_blank">https://gh-proxy.com/https://github.com/FongMi/Release/blob/okjack/apk/release/ 海信专版.apk</a></td></tr><tr><td>OK 影视空壳专区 okjack</td><td>X5 离线</td><td><a href="https://gh-proxy.com/https://github.com/FongMi/Release/blob/okjack/apk/release/%E7%94%B5%E8%A7%86%E7%89%88-X5%E7%A6%BB%E7%BA%BF.apk" target="_blank">https://gh-proxy.com/https://github.com/FongMi/Release/blob/okjack/apk/release/ 电视版 - X5 离线.apk</a></td></tr><tr><td>OK 影视空壳专区 Fongmi</td><td>TV 端 - v7a</td><td><a href="https://gh-proxy.com/https://github.com/FongMi/Release/blob/fongmi/apk/release/leanback-armeabi_v7a.apk" target="_blank">https://gh-proxy.com/https://github.com/FongMi/Release/blob/fongmi/apk/release/leanback-armeabi_v7a.apk</a></td></tr><tr><td>OK 影视空壳专区 Fongmi</td><td>TV 端 - v8a</td><td><a href="https://gh-proxy.com/github.com/FongMi/Release/blob/fongmi/apk/release/leanback-arm64_v8a.apk" target="_blank">https://gh-proxy.com/github.com/FongMi/Release/blob/fongmi/apk/release/leanback-arm64_v8a.apk</a></td></tr><tr><td>OK 影视 PRO 空壳专区</td><td>TV 端</td><td><a href="https://streamshare.wireway.ch/download/ru3relsn" target="_blank">https://streamshare.wireway.ch/download/ru3relsn</a></td></tr><tr><td>酷 9 原版空壳专区</td><td>TV 端</td><td><a href="https://streamshare.wireway.ch/download/ybyzclnf" target="_blank">https://streamshare.wireway.ch/download/ybyzclnf</a></td></tr><tr><td>酷 9 原版空壳专区</td><td>TV 端 lite</td><td><a href="https://streamshare.wireway.ch/download/olty7z6s" target="_blank">https://streamshare.wireway.ch/download/olty7z6s</a></td></tr><tr><td>酷 9 魔改空壳专区</td><td>半透明版 / 布局版等</td><td>（注：均适配 TV，以具体链接为准，示例：<a href="https://streamshare.wireway.ch/download/7w8mfwym" target="_blank">半透明版</a>）</td></tr><tr><td>DIYP 影音空壳专区</td><td>TV 经典版</td><td><a href="https://streamshare.wireway.ch/download/g6xmkr37" target="_blank">https://streamshare.wireway.ch/download/g6xmkr37</a></td></tr><tr><td>DIYP 影音空壳专区</td><td>TV 最终版</td><td><a href="https://streamshare.wireway.ch/download/13lz0t0w" target="_blank">https://streamshare.wireway.ch/download/13lz0t0w</a></td></tr><tr><td>派大星空壳专区</td><td>TV 端 1.0.5</td><td><a href="https://streamshare.wireway.ch/download/8vr0a8lo" target="_blank">https://streamshare.wireway.ch/download/8vr0a8lo</a></td></tr><tr><td>派大星空壳专区</td><td>TV 端 1.0.6</td><td><a href="https://streamshare.wireway.ch/download/to3j9w01" target="_blank">https://streamshare.wireway.ch/download/to3j9w01</a></td></tr><tr><td>UZ 影视空壳专区</td><td>电视端</td><td><a href="https://streamshare.wireway.ch/download/y5af8psn" target="_blank">https://streamshare.wireway.ch/download/y5af8psn</a></td></tr><tr><td>ClashMeta 专区</td><td>电视端</td><td><a href="https://gh-proxy.com/https://github.com/MetaCubeX/ClashMetaForAndroid/releases/download/v2.11.15/cmfa-2.11.15-meta-universal-release.apk" target="_blank">https://gh-proxy.com/https://github.com/MetaCubeX/ClashMetaForAndroid/releases/download/v2.11.15/cmfa-2.11.15-meta-universal-release.apk</a></td></tr><tr><td>ClashMi 专区</td><td>电视端</td><td><a href="https://dot.clashmi.app/client.html?tag=android-armv7a-stable" target="_blank">https://dot.clashmi.app/client.html?tag=android-armv7a-stable</a></td></tr><tr><td>Karing 专区</td><td>电视端</td><td><a href="https://dot.karing.app/client.html?tag=android-armv7a-stable" target="_blank">https://dot.karing.app/client.html?tag=android-armv7a-stable</a></td></tr></tbody></table><hr /></section>
<section><h3>3. 苹果端（含 iPhone、iPad）<a href="#3-苹果端含-iphoneipad"><span>#</span></a></h3>

<table><thead><tr><th>软件专区</th><th>版本类型</th><th>下载链接</th></tr></thead><tbody><tr><td>UZ 影视空壳专区</td><td>苹果端</td><td><a href="https://streamshare.wireway.ch/download/zg9z7hq9" target="_blank">https://streamshare.wireway.ch/download/zg9z7hq9</a></td></tr><tr><td>蛋播星球专区 (内置源)</td><td>苹果端</td><td><a href="https://testflight.apple.com/join/U1uy34cq" target="_blank">https://testflight.apple.com/join/U1uy34cq</a></td></tr><tr><td>自娱播放器空壳专区</td><td>苹果专属</td><td><a href="https://apps.apple.com/cn/app/%E8%87%AA%E5%A8%B1%E6%92%AD%E6%94%BE%E5%99%A8/id6747301490" target="_blank">https://apps.apple.com/cn/app/%E8%87%AA%E5%A8%B1%E6%92%AD%E6%94%BE%E5%99%A8/id6747301490</a></td></tr><tr><td>魔力云播空壳专区</td><td>苹果专属</td><td><a href="https://testflight.apple.com/join/ywzcMKS3" target="_blank">https://testflight.apple.com/join/ywzcMKS3</a></td></tr><tr><td>MiraPlay 空壳专区</td><td>苹果专属</td><td><a href="https://testflight.apple.com/join/4N2pkqa3" target="_blank">https://testflight.apple.com/join/4N2pkqa3</a></td></tr><tr><td>ClashMi 专区</td><td>苹果端</td><td><a href="https://testflight.apple.com/join/bjHXktB3" target="_blank">https://testflight.apple.com/join/bjHXktB3</a></td></tr><tr><td>Karing 专区</td><td>苹果端</td><td><a href="https://testflight.apple.com/join/RLU59OsJ" target="_blank">https://testflight.apple.com/join/RLU59OsJ</a></td></tr></tbody></table><hr /></section>
<section><h3>4. Windows 端（含 PC、笔记本）<a href="#4-windows-端含-pc笔记本"><span>#</span></a></h3>

<table><thead><tr><th>软件专区</th><th>版本类型</th><th>下载链接</th></tr></thead><tbody><tr><td>OK 影视 PRO 空壳专区</td><td>模拟器专版</td><td><a href="https://streamshare.wireway.ch/download/xrg9wxlh" target="_blank">https://streamshare.wireway.ch/download/xrg9wxlh</a></td></tr><tr><td>UZ 影视空壳专区</td><td>Win 端</td><td><a href="https://streamshare.wireway.ch/download/x5xa2cvl" target="_blank">https://streamshare.wireway.ch/download/x5xa2cvl</a></td></tr><tr><td>蛋播星球专区 (内置源)</td><td>Win 端</td><td><a href="https://streamshare.wireway.ch/download/4016c1lw" target="_blank">https://streamshare.wireway.ch/download/4016c1lw</a></td></tr><tr><td>ClashMi 专区</td><td>Win 端</td><td><a href="https://dot.clashmi.app/client.html?tag=windows-installer-stable" target="_blank">https://dot.clashmi.app/client.html?tag=windows-installer-stable</a></td></tr><tr><td>Karing 专区</td><td>Win 端</td><td><a href="https://dot.karing.app/client.html?tag=windows-installer-stable" target="_blank">https://dot.karing.app/client.html?tag=windows-installer-stable</a></td></tr><tr><td>Mihomo-party 专区</td><td>Win10/11-32 位</td><td><a href="https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-windows-1.7.7-ia32-setup.exe" target="_blank">https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-windows-1.7.7-ia32-setup.exe</a></td></tr><tr><td>Mihomo-party 专区</td><td>Win10/11-64 位</td><td><a href="https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-windows-1.7.7-x64-setup.exe" target="_blank">https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-windows-1.7.7-x64-setup.exe</a></td></tr><tr><td>Mihomo-party 专区</td><td>Win7/8-32 位</td><td><a href="https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-win7-1.7.7-ia32-setup.exe" target="_blank">https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-win7-1.7.7-ia32-setup.exe</a></td></tr><tr><td>Mihomo-party 专区</td><td>Win7/8-64 位</td><td><a href="https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-win7-1.7.7-x64-setup.exe" target="_blank">https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-win7-1.7.7-x64-setup.exe</a></td></tr></tbody></table><hr /></section>
<section><h3>5. Mac 端（含 Intel、Apple Silicon 芯片）<a href="#5-mac-端含-intelapple-silicon-芯片"><span>#</span></a></h3>

<table><thead><tr><th>软件专区</th><th>版本类型</th><th>下载链接</th></tr></thead><tbody><tr><td>UZ 影视空壳专区</td><td>Mac 端</td><td><a href="https://streamshare.wireway.ch/download/5upxguqe" target="_blank">https://streamshare.wireway.ch/download/5upxguqe</a></td></tr><tr><td>蛋播星球专区 (内置源)</td><td>Mac-M 芯片</td><td><a href="https://streamshare.wireway.ch/download/4s93ir77" target="_blank">https://streamshare.wireway.ch/download/4s93ir77</a></td></tr><tr><td>ClashMi 专区</td><td>Mac 端</td><td><a href="https://dot.clashmi.app/client.html?tag=macos-beta" target="_blank">https://dot.clashmi.app/client.html?tag=macos-beta</a></td></tr><tr><td>Mihomo-party 专区</td><td>Mac-lntel-11+</td><td><a href="https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-macos-1.7.7-x64.pkg" target="_blank">https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-macos-1.7.7-x64.pkg</a></td></tr><tr><td>Mihomo-party 专区</td><td>Mac-AppleSilicon-11+</td><td><a href="https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-macos-1.7.7-arm64.pkg" target="_blank">https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-macos-1.7.7-arm64.pkg</a></td></tr><tr><td>Mihomo-party 专区</td><td>Mac-lntel-10.15+</td><td><a href="https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-catalina-1.7.7-x64.pkg" target="_blank">https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-catalina-1.7.7-x64.pkg</a></td></tr><tr><td>Mihomo-party 专区</td><td>Mac-AppleSilicon-10.15+</td><td><a href="https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-catalina-1.7.7-arm64.pkg" target="_blank">https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-catalina-1.7.7-arm64.pkg</a></td></tr></tbody></table><hr /></section>
<section><h3>6. 其他设备（Linux、鸿蒙、X86 专用）<a href="#6-其他设备linux鸿蒙x86-专用"><span>#</span></a></h3>

<table><thead><tr><th>设备类型</th><th>软件专区</th><th>版本类型</th><th>下载链接</th></tr></thead><tbody><tr><td>Linux</td><td>Mihomo-party 专区</td><td>Linux-DEB-64 位</td><td><a href="https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-linux-1.7.7-amd64.deb" target="_blank">https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-linux-1.7.7-amd64.deb</a></td></tr><tr><td>Linux</td><td>Mihomo-party 专区</td><td>Linux-ARM64</td><td><a href="https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-linux-1.7.7-arm64.deb" target="_blank">https://gh-proxy.com/https://github.com/mihomo-party-org/mihomo-party/releases/download/v1.7.7/mihomo-party-linux-1.7.7-arm64.deb</a></td></tr><tr><td>鸿蒙</td><td>Karing 专区</td><td>鸿蒙端</td><td><a href="https://gh-proxy.com/https://github.com/KaringX/karing/releases/download/v1.0.23-275/karing_1.0.23.275_android_arm64.apk" target="_blank">https://gh-proxy.com/https://github.com/KaringX/karing/releases/download/v1.0.23-275/karing_1.0.23.275_android_arm64.apk</a></td></tr><tr><td>X86 专用</td><td>UZ 影视空壳专区</td><td>X86 专用</td><td><a href="https://streamshare.wireway.ch/download/rle4gdl8" target="_blank">https://streamshare.wireway.ch/download/rle4gdl8</a></td></tr><tr><td>X86 专用</td><td>ClashMeta 专区</td><td>X86</td><td><a href="https://gh-proxy.com/https://github.com/MetaCubeX/ClashMetaForAndroid/releases/download/v2.11.15/cmfa-2.11.15-meta-x86-release.apk" target="_blank">https://gh-proxy.com/https://github.com/MetaCubeX/ClashMetaForAndroid/releases/download/v2.11.15/cmfa-2.11.15-meta-x86-release.apk</a></td></tr></tbody></table></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/fe9849a0/</id>
      <title type="text">iOS用户福音！Cymusic 音乐播放器使用教程，一步到位让你免费听遍全网音乐</title>
      <published>2026-02-23T12:32:13.000Z</published>
      <updated>2026-02-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/fe9849a0/"/>
      <summary type="text">Cymusic 是一款专为 iOS 设备打造的音乐播放器，它支持多音乐源、歌曲搜索、歌单导入等功能，让你在 iOS 设备上也能免费听遍全网音乐！</summary>
      <content type="html"><![CDATA[<section><h2>回应读者：iOS 移动端音乐播放器安排上了！<a href="#回应读者ios-移动端音乐播放器安排上了"><span>#</span></a></h2><p>前几天有读者在后台问小王：“有没有推荐的 iOS 移动端音乐播放器呀？“，小王一直在找合适的推荐，终于找到了一个超棒的 iOS 音乐播放器——<strong>Cymusic</strong>！</p><p>今天小王就给大家带来一份详细的 Cymusic 使用教程，一步到位让你免费听遍全网音乐！</p></section>
<section><h2>什么是 Cymusic？<a href="#什么是-cymusic"><span>#</span></a></h2><p>Cymusic 是一款专为 iOS 设备打造的音乐播放器，它支持多音乐源、歌曲搜索、歌单导入等功能，让你在 iOS 设备上也能免费听遍全网音乐！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/c656445ca85145cd8ebad0407a2b46070001.png" alt="" /></p></section>
<section><h2>准备工作<a href="#准备工作"><span>#</span></a></h2><p>在开始使用 Cymusic 之前，你需要准备以下东西：</p><ol>
<li>一台 iOS 设备（iPhone 或 iPad）</li>
<li>稳定的网络连接</li>
<li>Cymusic 应用（下载地址私信小王获取）</li>
<li>音源文件（同样私信小王获取）</li>
</ol></section>
<section><h2>安装 Cymusic<a href="#安装-cymusic"><span>#</span></a></h2><section><h3>方法一：使用巨魔安装（推荐）<a href="#方法一使用巨魔安装推荐"><span>#</span></a></h3><ol>
<li>首先在你的 iOS 设备上安装巨魔（TrollStore）</li>
<li>打开巨魔，点击”+“按钮</li>
<li>选择从小王这里获取的 Cymusic IPA 文件</li>
<li>等待安装完成</li>
</ol></section><section><h3>方法二：使用证书自签安装<a href="#方法二使用证书自签安装"><span>#</span></a></h3><ol>
<li>在电脑上下载 Cydia Impactor 或其他自签工具</li>
<li>将 iOS 设备连接到电脑</li>
<li>打开自签工具，选择 Cymusic IPA 文件</li>
<li>输入你的 Apple ID 和密码</li>
<li>等待安装完成</li>
</ol></section></section>
<section><h2>导入音源<a href="#导入音源"><span>#</span></a></h2><p>安装完成后，你需要导入音源文件才能使用 Cymusic：</p><ol>
<li>首先将从小王这里获取的音源文件下载到你的 iOS 设备中</li>
<li>打开 Cymusic 应用</li>
<li>点击右上角的三条杠图标</li>
<li>选择”导入音源”</li>
<li>选择你下载的音源文件</li>
<li>等待导入完成</li>
</ol></section>
<section><h2>使用教程<a href="#使用教程"><span>#</span></a></h2><section><h3>搜索歌曲<a href="#搜索歌曲"><span>#</span></a></h3><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/1cb9298a0fdf4573a48ed7a863066a800002.png" alt="" /></p><ol>
<li>打开 Cymusic 应用</li>
<li>在搜索栏中输入你想要搜索的歌曲名称或歌手名称</li>
<li>点击搜索按钮</li>
<li>从搜索结果中选择你想要的歌曲</li>
<li>点击播放按钮开始播放</li>
</ol></section><section><h3>导入歌单<a href="#导入歌单"><span>#</span></a></h3><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/e2420d9c1b4247e1b5cfd901ce207c9d0003.png" alt="" /></p><ol>
<li>打开 Cymusic 应用</li>
<li>点击右上角的三条杠图标</li>
<li>选择”导入歌单”</li>
<li>在输入栏中粘贴歌单链接</li>
<li>点击”导入”按钮</li>
<li>等待导入完成</li>
</ol></section><section><h3>调整设置<a href="#调整设置"><span>#</span></a></h3><ol>
<li>打开 Cymusic 应用</li>
<li>点击右上角的三条杠图标</li>
<li>选择”设置”</li>
<li>在这里你可以调整播放设置、下载设置等</li>
</ol></section></section>
<section><h2>功能特点<a href="#功能特点"><span>#</span></a></h2><p>Cymusic 具有以下功能特点：</p><ul>
<li><strong>多音乐源</strong>：支持多个音乐平台的音源</li>
<li><strong>歌曲搜索</strong>：可以搜索歌曲和歌手</li>
<li><strong>歌单导入</strong>：支持导入外部歌单</li>
<li><strong>歌曲下载</strong>：可以下载歌曲到本地</li>
<li><strong>界面美观</strong>：简洁美观的用户界面</li>
<li><strong>免费使用</strong>：完全免费，无广告</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 Cymusic 感兴趣，可以访问它的 GitHub 仓库：<a href="https://github.com/gyc-12/Cymusic" target="_blank">https://github.com/gyc-12/Cymusic</a></p></section>
<section><h2>如何获取下载地址？<a href="#如何获取下载地址"><span>#</span></a></h2><p>想要获取 Cymusic 的下载地址和音源文件，请按照以下步骤操作：</p><ol>
<li>关注小王的微信公众号</li>
<li>发送 “Cymusic” 到公众号</li>
<li>小王会私信给你下载地址和音源文件</li>
</ol></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时在 iOS 设备上用什么音乐播放器？使用 Cymusic 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，小王会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="http://mp.weixin.qq.com/s/vOxJd-TJlnK8zO1s-e9EVg?token=2046857375&amp;lang=zh_CN" target="_blank">发现宝藏音乐播放器！MusicFree 让你告别广告和会员</a></li>
<li><a href="http://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2046857375&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
<li><a href="http://mp.weixin.qq.com/s/ETpzOpVEgAwlUEJWAvnwWw?token=2046857375&amp;lang=zh_CN" target="_blank">音乐下载新选择！COCO音乐下载站让你轻松获取无损音乐</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/68f42c42/</id>
      <title type="text">【工具】三步实现【DeepSeek】本地部署,构建自己的AI智能体</title>
      <published>2026-01-23T12:32:13.000Z</published>
      <updated>2026-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/68f42c42/"/>
      <summary type="text">近年来，国产大模型DeepSeek备受关注，但随着用户访问量激增，频繁出现响应缓慢甚至系统宕机的现象，给使用者带来了一些不便。幸运的是，DeepSeek作为开源模型，允许开发者通过本地部署来解决这一问题。将模型部署到本地后，用户无需依赖网络即可随时进行推理操作，不仅提升了使用体验，还大幅降低了对外部服务的依赖。</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>近年来，国产大模型DeepSeek备受关注，但随着用户访问量激增，频繁出现响应缓慢甚至系统宕机的现象，给使用者带来了一些不便。
幸运的是，DeepSeek作为开源模型，允许开发者通过本地部署来解决这一问题。将模型部署到本地后，用户无需依赖网络即可随时进行推理操作，不仅提升了使用体验，还大幅降低了对外部服务的依赖。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/02/image-20250218143823515.png" alt="image-20250218143823515" /><figcaption>image-20250218143823515</figcaption></figure><p></p></section>
<section><h2>安装 Ollama<a href="#安装-ollama"><span>#</span></a></h2><p>要在本地运行 DeepSeek，我们需要使用 Ollama——一个开源的本地大模型运行工具</p><p>首先，访问 <a href="https://ollama.com/download/" target="_blank">Ollama官网</a> 下载该工具。官网提供了针对不同操作系统的安装包，用户只需选择适合自己电脑的版本即可。在本例中，我们选择下载适用于 Windows 操作系统的版本。</p><p>*** 注意： 官网的下载地址为github网站的地址，因为一些原因，部分地区无法访问，大家可以使用<a href="https://steampp.net/" target="_blank">Watt Toolkit</a> 进行网络加速，或者使用好心人部署的<a href="https://github.akams.cn/" target="_blank">文件加速网站</a>进行下载 **</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/02/image-20250218144607214.png" alt="image-20250218144607214" /><figcaption>image-20250218144607214</figcaption></figure><p></p><p>Ollama 安装包下载后双击install，安装速度还是比较快的**（注：直接安装到C盘,无法更改位置，下载的模型也在C盘）**</p><p>安装完成 Ollama 后，打开电脑的 CMD（命令提示符）。只需在电脑下方的搜索框中输入“cmd”并按回车，即可打开命令提示符窗口。输入**【ollama help】**，出现下图，则代表已经安装成功了</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/02/image-20250218144838005.png" alt="image-20250218144838005" /><figcaption>image-20250218144838005</figcaption></figure><p></p></section>
<section><h2>下载部署 Deepseek 模型<a href="#下载部署-deepseek-模型"><span>#</span></a></h2></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/78993085/</id>
      <title type="text">解决GitHub访问慢的神器！fetch-github-hosts 让你秒开GitHub，再也不用等加载了</title>
      <published>2026-01-23T12:32:13.000Z</published>
      <updated>2026-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/78993085/"/>
      <summary type="text">前阵子我给大家分享了很多优秀的 GitHub 开源项目，比如 MusicFree、COCO 音乐下载站、Melody Hub、Cymusic 等，这些都是非常棒的工具。但是，有读者在后台反映，GitHub 在国内访问速度太慢了，有时候甚至根本打不开，导致无法下载这些优秀的开源项目。</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！GitHub访问慢的问题终于有解决方案了！<a href="#朋友们github访问慢的问题终于有解决方案了"><span>#</span></a></h2><p>前阵子我给大家分享了很多优秀的 GitHub 开源项目，比如 MusicFree、COCO 音乐下载站、Melody Hub、Cymusic 等，这些都是非常棒的工具。但是，有读者在后台反映，GitHub 在国内访问速度太慢了，有时候甚至根本打不开，导致无法下载这些优秀的开源项目。</p><p>今天我要给大家介绍一个专门解决 GitHub 访问问题的神器——<strong>fetch-github-hosts</strong>，它能帮你快速访问 GitHub，再也不用忍受缓慢的加载速度了！</p></section>
<section><h2>什么是 fetch-github-hosts？<a href="#什么是-fetch-github-hosts"><span>#</span></a></h2><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/42f447a0bdee40ef8237621163c2605f20260407173857500.png" alt="" /></p><p>fetch-github-hosts 是一个用于同步 GitHub hosts 的工具，主要为解决研究及学习人员访问 GitHub 过慢或其他问题而提供。它通过部署服务器来获取 github.com 的 hosts，而不是通过第三方 IP 地址接口来进行获取，更加稳定可靠。</p></section>
<section><h2>为什么需要 fetch-github-hosts？<a href="#为什么需要-fetch-github-hosts"><span>#</span></a></h2><p>如果你经常访问 GitHub，你可能会遇到以下问题：</p><ul>
<li>访问 GitHub 速度缓慢，页面加载需要很久</li>
<li>有时候甚至无法打开 GitHub 网站</li>
<li>克隆或下载 GitHub 项目速度很慢</li>
<li>无法正常登录 GitHub 账号</li>
</ul><p>这些问题都是由于 GitHub 在国内的访问限制导致的。fetch-github-hosts 通过更新 hosts 文件，让你的电脑直接访问 GitHub 的服务器，从而绕过这些限制，提高访问速度。</p></section>
<section><h2>功能特点<a href="#功能特点"><span>#</span></a></h2><p>fetch-github-hosts 具有以下功能特点：</p><ul>
<li><strong>多平台支持</strong>：支持 Windows、macOS、Linux 等多种操作系统</li>
<li><strong>多种界面</strong>：支持图形化界面和命令行界面</li>
<li><strong>内置两种模式</strong>：客户端模式和服务端模式</li>
<li><strong>自动更新</strong>：可以设置自动更新 hosts 文件</li>
<li><strong>简单易用</strong>：操作简单，即使是技术小白也能轻松使用</li>
</ul></section>
<section><h2>如何使用 fetch-github-hosts？<a href="#如何使用-fetch-github-hosts"><span>#</span></a></h2><section><h3>Windows 系统<a href="#windows-系统"><span>#</span></a></h3><section><h4>方法一：使用图形化界面<a href="#方法一使用图形化界面"><span>#</span></a></h4><ol>
<li>下载并安装 fetch-github-hosts（访问不了github的可以私信我获取）</li>
<li>以管理员身份运行应用程序
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/25bd1d3bcc904436829dc77fef4d18f120260407174405524.png" alt="" /></li>
<li>点击”更新 hosts”按钮
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/97a636ef0be84d54b93964f35c4a652020260407174502250.png" alt="" /></li>
<li>等待更新完成（会显示更新成功的提示）
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/346e9d84a5a144a1a29f2ce5c0cedf2b20260407174554205.png" alt="" /></li>
<li>刷新浏览器，重新访问 GitHub</li>
</ol></section><section><h4>方法二：使用命令行<a href="#方法二使用命令行"><span>#</span></a></h4><ol>
<li>下载并解压 fetch-github-hosts（访问不了github的可以私信我获取）</li>
<li>以管理员身份打开命令提示符</li>
<li>进入解压目录，例如：<code>cd D:\fetch-github-hosts</code></li>
<li>启动客户端</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Windows</span></div></div><div><div><div>2</div></div><div><span>fetch-github-hosts.exe</span><span> </span><span>-m</span><span> </span><span>client</span></div></div><div><div><div>3</div></div><div><span># 自定义获取间隔（10分钟）</span></div></div><div><div><div>4</div></div><div><span>sudo</span><span> </span><span>./fetch-github-hosts</span><span> </span><span>-m</span><span> </span><span>client</span><span> </span><span>-i</span><span> </span><span>10</span></div></div><div><div><div>5</div></div><div><span># 自定义获取链接</span></div></div><div><div><div>6</div></div><div><span>sudo</span><span> </span><span>./fetch-github-hosts</span><span> </span><span>-m</span><span> </span><span>client</span><span> </span><span>-u</span><span> </span><span>http://127.0.0.1:9898/hosts.json</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>启动服务端</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Windows</span></div></div><div><div><div>2</div></div><div><span>fetch-github-hosts.exe</span><span> </span><span>-m</span><span> </span><span>server</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 自定义端口</span></div></div><div><div><div>5</div></div><div><span>./fetch-github-hosts</span><span> </span><span>-m</span><span> </span><span>server</span><span> </span><span>-p</span><span> </span><span>6666</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 自定义 HTML 模板文件</span></div></div><div><div><div>8</div></div><div><span>./fetch-github-hosts</span><span> </span><span>-m</span><span> </span><span>server</span><span> </span><span>-t</span><span> </span><span>/path/to/template.html</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>刷新 DNS 缓存</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Windows</span></div></div><div><div><div>2</div></div><div><span>ipconfig</span><span> </span><span>/flushdns</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>等待更新完成（会显示更新成功的提示）</li>
<li>刷新浏览器，重新访问 GitHub</li>
</ol></section></section><section><h3>macOS 系统<a href="#macos-系统"><span>#</span></a></h3><section><h4>使用命令行界面<a href="#使用命令行界面"><span>#</span></a></h4><ol>
<li>下载并解压 fetch-github-hosts（访问不了github的可以私信我获取）</li>
<li>以管理员身份打开命令提示符</li>
<li>进入解压目录，例如：<code>cd D:\fetch-github-hosts</code></li>
<li>启动客户端</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Linux/macOS</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>./fetch-github-hosts</span><span> </span><span>-m</span><span> </span><span>client</span></div></div><div><div><div>3</div></div><div><span># 自定义获取间隔（10分钟）</span></div></div><div><div><div>4</div></div><div><span>sudo</span><span> </span><span>./fetch-github-hosts</span><span> </span><span>-m</span><span> </span><span>client</span><span> </span><span>-i</span><span> </span><span>10</span></div></div><div><div><div>5</div></div><div><span># 自定义获取链接</span></div></div><div><div><div>6</div></div><div><span>sudo</span><span> </span><span>./fetch-github-hosts</span><span> </span><span>-m</span><span> </span><span>client</span><span> </span><span>-u</span><span> </span><span>http://127.0.0.1:9898/hosts.json</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>启动服务端</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Linux/macOS</span></div></div><div><div><div>2</div></div><div><span># Linux/macOS</span></div></div><div><div><div>3</div></div><div><span>./fetch-github-hosts</span><span> </span><span>-m</span><span> </span><span>server</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># 自定义端口</span></div></div><div><div><div>6</div></div><div><span>./fetch-github-hosts</span><span> </span><span>-m</span><span> </span><span>server</span><span> </span><span>-p</span><span> </span><span>6666</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span># 自定义 HTML 模板文件</span></div></div><div><div><div>9</div></div><div><span>./fetch-github-hosts</span><span> </span><span>-m</span><span> </span><span>server</span><span> </span><span>-t</span><span> </span><span>/path/to/template.html</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>刷新 DNS 缓存</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># macOS</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>dscacheutil</span><span> </span><span>-flushcache</span><span> &amp;&amp; </span><span>sudo</span><span> </span><span>killall</span><span> </span><span>-HUP</span><span> </span><span>mDNSResponder</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>等待更新完成（会显示更新成功的提示）</li>
<li>刷新浏览器，重新访问 GitHub</li>
</ol></section></section><section><h3>注意事项<a href="#注意事项"><span>#</span></a></h3><ul>
<li>首次使用时，可能需要关闭防火墙或安全软件，以免阻止修改 hosts 文件</li>
<li>如果更新后仍然访问速度较慢，可以尝试重启浏览器或电脑</li>
<li>建议定期更新 hosts 文件，因为 GitHub 的 IP 地址可能会变化</li>
<li>如果遇到问题，可以尝试以管理员/root 权限运行程序</li>
</ul></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>前几天我使用了 fetch-github-hosts，效果真的非常明显：</p><ol>
<li>之前访问 GitHub 首页需要 10 多秒，现在只需要 1-2 秒</li>
<li>克隆 GitHub 项目的速度从之前的几 KB/s 提升到了几 MB/s</li>
<li>再也没有遇到无法打开 GitHub 的情况</li>
</ol><p>现在我可以轻松访问之前分享的那些优秀开源项目，下载速度也快了很多！</p></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>开发者</strong>：需要经常访问 GitHub 查看代码、克隆项目</li>
<li><strong>学生</strong>：需要在 GitHub 上学习开源项目</li>
<li><strong>技术爱好者</strong>：喜欢探索各种开源工具</li>
<li><strong>任何人</strong>：需要访问 GitHub 的人</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 fetch-github-hosts 感兴趣，可以访问它的 GitHub 仓库：<a href="https://github.com/Licoy/fetch-github-hosts" target="_blank">https://github.com/Licoy/fetch-github-hosts</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时访问 GitHub 时遇到过什么问题？使用 fetch-github-hosts 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/kG5HvrifueIWsHaWWdTbrQ?token=102365809&amp;lang=zh_CN" target="_blank">发现宝藏聚合软件！益达 APP 让你告别多 app 切换，一个软件看遍小说漫画影视</a></li>
<li><a href="http://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2046857375&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
<li><a href="https://mp.weixin.qq.com/s/y-fodnFP16CjI2TXCxKZpg?token=102365809&amp;lang=zh_CN" target="_blank">iOS用户福音！Cymusic 音乐播放器使用教程，一步到位让你免费听遍全网音乐</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/e2c177e8/</id>
      <title type="text">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</title>
      <published>2026-01-23T12:32:13.000Z</published>
      <updated>2026-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/e2c177e8/"/>
      <summary type="text">最近我被音乐软件搞烦了——想听周杰伦的歌要开某易云，想听林俊杰的歌要开某 Q 音乐，想听一些冷门歌曲又要换别的 app，手机里装了五六个音乐软件，占空间不说，切换来切换去真的麻烦死了！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！我发现了一个超好用的音乐软件！<a href="#朋友们我发现了一个超好用的音乐软件"><span>#</span></a></h2><p>最近我被音乐软件搞烦了——想听周杰伦的歌要开某易云，想听林俊杰的歌要开某 Q 音乐，想听一些冷门歌曲又要换别的 app，手机里装了五六个音乐软件，占空间不说，切换来切换去真的麻烦死了！</p><p>直到我发现了这款<strong>LX Music（洛雪音乐）</strong>，简直打开了新世界的大门！今天必须给你们安利一波！</p></section>
<section><h2>什么是 LX Music？<a href="#什么是-lx-music"><span>#</span></a></h2><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/968d9690dfff4c32afbe3056fd993d75icon.png" alt="" />
简单来说，LX Music 是一个免费的音乐播放器，最牛的地方是它能<strong>同时搜索多个音乐平台的歌曲</strong>，不用再切换 app 就能听到所有平台的音乐！而且电脑和手机都能用，超方便～</p></section>
<section><h2>为什么我推荐 LX Music？<a href="#为什么我推荐-lx-music"><span>#</span></a></h2><section><h3>1️⃣ 一个软件听遍所有平台<a href="#1️⃣-一个软件听遍所有平台"><span>#</span></a></h3><p>以前我为了听歌，手机里装了某易云、某 Q 音乐、某酷音乐…现在好了，有了 LX Music，我只需要打开一个 app，就能搜索到各个平台的歌曲，再也不用来回切换了！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/816539b335fe45d3bf703dc35ff531cf20260324111309083.png" alt="" /></p></section><section><h3>2️⃣ 完全免费，无广告<a href="#2️⃣-完全免费无广告"><span>#</span></a></h3><p>最重要的是，这个软件完全免费，没有任何广告！不像某些音乐软件，听两首歌就弹广告，烦都烦死了。</p></section><section><h3>3️⃣ 电脑手机都能用<a href="#3️⃣-电脑手机都能用"><span>#</span></a></h3><p>它有桌面版和移动版，不管你是用电脑还是手机，都能无缝切换，而且还支持同步歌单，在电脑上创建的歌单，打开手机 app 就能继续听，超方便！</p></section><section><h3>4️⃣ 操作简单，小白友好<a href="#4️⃣-操作简单小白友好"><span>#</span></a></h3><p>虽然官方说“不以新手友好为目标”，但我用下来觉得操作其实挺简单的，就是普通音乐播放器的界面，上手很快。</p></section><section><h3>5️⃣ 支持下载歌曲<a href="#5️⃣-支持下载歌曲"><span>#</span></a></h3><p>遇到喜欢的歌曲，还能直接下载到本地，没网的时候也能听，太贴心了！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/e4dcf1b606ea410aba08991ac4b4f45a20260324111403353.png" alt="" /></p></section></section>
<section><h2>怎么使用 LX Music？<a href="#怎么使用-lx-music"><span>#</span></a></h2><section><h3>下载安装<a href="#下载安装"><span>#</span></a></h3><ul>
<li><strong>电脑版</strong>：去 GitHub 搜索“lx-music-desktop”，找到 Releases 页面下载对应系统的安装包，安装就行</li>
<li><strong>手机版</strong>：搜索“lx-music-mobile”，下载 APK 文件安装到手机</li>
</ul></section><section><h3>首次使用小技巧<a href="#首次使用小技巧"><span>#</span></a></h3><ol>
<li>打开软件后，先在设置里调整一下自己喜欢的界面风格</li>
<li>直接在搜索框里输入歌曲名，就能看到来自不同平台的结果</li>
<li>点击歌曲就能播放，还能添加到歌单</li>
<li>如果想同步歌单，可以在设置里配置同步服务</li>
</ol></section></section>
<section><h2>我用 LX Music 的真实体验<a href="#我用-lx-music-的真实体验"><span>#</span></a></h2><p>自从用了 LX Music，我的手机桌面清爽了很多，再也没有一堆音乐 app 了。早上通勤的时候，我会打开手机版听喜欢的歌；晚上回家用电脑工作时，打开桌面版继续听，歌单都是同步的，超级方便！</p><p>前几天我想找一首比较冷门的日文歌，在其他平台都搜不到，结果在 LX Music 里一下就找到了，真的惊喜！</p></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>音乐爱好者</strong>：不想装多个音乐 app，想一站式听歌的朋友</li>
<li><strong>学生党</strong>：预算有限，不想为音乐会员付费的同学</li>
<li><strong>上班族</strong>：通勤路上想听音乐，不想切换 app 的打工人</li>
<li><strong>任何人</strong>：只要你喜欢听歌，想更方便地享受音乐，都可以试试！</li>
</ul></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ol>
<li>软件是开源的，完全免费，大家可以放心使用</li>
<li>记得支持正版音乐，尊重版权哦</li>
<li>下载的歌曲建议在 24 小时内删除，避免侵权</li>
</ol></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>LX Music 真的是我最近发现的宝藏软件，解决了我听歌的大麻烦。如果你也像我一样，被多个音乐 app 搞得头疼，一定要试试它！</p><p>不用花一分钱，就能享受一站式的音乐体验，何乐而不为呢？</p></section>
<section><h2>下载地址<a href="#下载地址"><span>#</span></a></h2><ul>
<li><strong>电脑版</strong>：<a href="https://github.com/lyswhut/lx-music-desktop" target="_blank">https://github.com/lyswhut/lx-music-desktop</a></li>
<li><strong>手机版</strong>：<a href="https://github.com/lyswhut/lx-music-mobile" target="_blank">https://github.com/lyswhut/lx-music-mobile</a></li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时用什么音乐软件？有没有遇到和我一样的困扰？欢迎在评论区分享你的音乐故事！</p><p>如果觉得这篇文章有用，别忘了点赞、在看并分享给身边喜欢听歌的朋友们～</p><p>如果下载失败或打开时空白的没有音源，可以私信小王，发送『音乐』，给你提供安装包和音源文件。</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="%E9%93%BE%E6%8E%A5">这些免费音乐软件，让你听歌不花一分钱</a></li>
<li><a href="%E9%93%BE%E6%8E%A5">手机必备实用工具推荐</a></li>
<li><a href="%E9%93%BE%E6%8E%A5">如何打造个人专属音乐库</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/f0070e98/</id>
      <title type="text">发现免费在线PS替代品！Photopea让你不用安装软件也能专业修图</title>
      <published>2026-01-23T12:32:13.000Z</published>
      <updated>2026-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/f0070e98/"/>
      <summary type="text">最近我想修几张照片，但是电脑里没有装 Photoshop，下载安装又麻烦，而且正版还挺贵的。就在我纠结的时候，朋友给我推荐了一个在线图片编辑器——**Photopea**，简直是救星！今天必须分享给你们！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！我发现了一个超厉害的在线图片编辑工具！<a href="#朋友们我发现了一个超厉害的在线图片编辑工具"><span>#</span></a></h2><p>最近我想修几张照片，但是电脑里没有装 Photoshop，下载安装又麻烦，而且正版还挺贵的。就在我纠结的时候，朋友给我推荐了一个在线图片编辑器——<strong>Photopea</strong>，简直是救星！今天必须分享给你们！</p></section>
<section><h2>什么是 Photopea？<a href="#什么是-photopea"><span>#</span></a></h2><p>简单来说，Photopea 是一个<strong>完全免费的在线图片编辑器</strong>，它的功能和界面都和 Photoshop 非常相似，但是不需要下载安装，直接在浏览器里打开就能用，而且完全免费！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/5e19fda5f748412aab30dde883ce5cfc20260326173131361.png" alt="" /></p></section>
<section><h2>为什么我推荐 Photopea？<a href="#为什么我推荐-photopea"><span>#</span></a></h2><section><h3>1️⃣ 完全免费，无需安装<a href="#1️⃣-完全免费无需安装"><span>#</span></a></h3><p>最重要的是，Photopea 完全免费，不用花一分钱就能使用专业的图片编辑功能。而且不需要下载安装任何软件，打开浏览器访问 <a href="https://www.photopea.com/" target="_blank">https://www.photopea.com/</a> 就能开始编辑图片，超级方便！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/2663177b8cf949e7be06a3c15e223a1720260326173209174.png" alt="" /></p></section><section><h3>2️⃣ 功能强大，堪比 PS<a href="#2️⃣-功能强大堪比-ps"><span>#</span></a></h3><p>虽然是在线工具，但 Photopea 的功能一点也不逊色于 Photoshop：
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/a644699f86bb4af9a29eac57a42d7df920260326173238009.png" alt="" /></p><ul>
<li><strong>基础编辑</strong>：裁剪、调整大小、旋转、翻转等</li>
<li><strong>高级功能</strong>：图层、蒙版、混合模式、滤镜等</li>
<li><strong>颜色调整</strong>：亮度、对比度、色阶、曲线、色彩平衡等</li>
<li><strong>工具齐全</strong>：选择工具、画笔工具、文本工具、形状工具等</li>
</ul></section><section><h3>3️⃣ 支持多种文件格式<a href="#3️⃣-支持多种文件格式"><span>#</span></a></h3><p>Photopea 支持打开和编辑多种文件格式，包括：</p><ul>
<li><strong>PSD</strong>：完全支持 Photoshop 的 PSD 格式，能打开和保存</li>
<li><strong>常见图片格式</strong>：PNG、JPG、GIF、BMP、WEBP、SVG 等</li>
<li><strong>专业格式</strong>：PDF、AI、AVIF、DDS、HEIC、TIFF、EPS 等</li>
<li><strong>RAW 格式</strong>：支持 DNG、CR2、CR3、NEF、ARW 等相机 RAW 文件</li>
</ul></section><section><h3>4️⃣ RAW 文件支持<a href="#4️⃣-raw-文件支持"><span>#</span></a></h3><p>如果你是摄影爱好者，Photopea 还支持直接打开和编辑相机 RAW 文件，调整曝光、色彩平衡、对比度、高光和阴影等参数，就像专业的 RAW 编辑器一样！</p></section><section><h3>5️⃣ 界面友好，上手简单<a href="#5️⃣-界面友好上手简单"><span>#</span></a></h3><p>Photopea 的界面和 Photoshop 非常相似，如果你用过 PS，几乎可以无缝切换。即使你是第一次使用，界面也很直观，容易上手。</p></section></section>
<section><h2>我用 Photopea 的真实体验<a href="#我用-photopea-的真实体验"><span>#</span></a></h2><p>前几天我用 Photopea 修了一组旅行照片，体验真的很棒：</p><ol>
<li>打开网站，直接拖拽照片进去就能开始编辑</li>
<li>用裁剪工具调整构图，用曲线工具调整曝光</li>
<li>添加文字、滤镜，调整色彩平衡</li>
<li>最后保存为 JPG 格式，效果和用 PS 修的差不多</li>
</ol><p>整个过程流畅，没有卡顿，而且完全免费，太香了！</p></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>学生党</strong>：预算有限，不想花钱买 PS，又需要做图的同学</li>
<li><strong>职场人士</strong>：偶尔需要修图，不想安装大型软件的打工人</li>
<li><strong>摄影爱好者</strong>：需要简单编辑照片，调整 RAW 文件的朋友</li>
<li><strong>设计新手</strong>：想学习图片编辑，又不想投入太多成本的初学者</li>
<li><strong>任何人</strong>：只要你需要编辑图片，又不想麻烦安装软件，都可以试试！</li>
</ul></section>
<section><h2>如何使用 Photopea？<a href="#如何使用-photopea"><span>#</span></a></h2><p>使用 Photopea 非常简单：</p><ol>
<li>打开浏览器，访问 <a href="https://www.photopea.com/" target="_blank">https://www.photopea.com/</a></li>
<li>点击”打开”按钮上传图片，或者直接拖拽图片到页面</li>
<li>使用左侧工具栏的各种工具进行编辑</li>
<li>编辑完成后，点击”文件”→“导出为”，选择格式保存</li>
</ol></section>
<section><h2>Docker 部署教程<a href="#docker-部署教程"><span>#</span></a></h2><p>如果你想在自己的服务器或 NAS 上部署 Photopea，方便随时随地使用，还可以通过 Docker 来部署。以下是详细步骤：</p><section><h3>1️⃣ 准备工作<a href="#1️⃣-准备工作"><span>#</span></a></h3><p>首先，确保你的设备上已经安装了 Docker。如果还没有安装，可以参考 Docker 官方文档进行安装。</p></section><section><h3>2️⃣ 拉取并运行 Photopea 容器<a href="#2️⃣-拉取并运行-photopea-容器"><span>#</span></a></h3><p>打开终端或命令行工具，执行以下命令：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span> </span><span>photopea</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>image</span><span>: </span><span>ramuses/photopea:latest</span></div></div><div><div><div>4</div></div><div><span>  </span><span>container_name</span><span>: </span><span>photopea</span></div></div><div><div><div>5</div></div><div><span>  </span><span>ports</span><span>:</span></div></div><div><div><div>6</div></div><div><span><span>   </span></span><span>- </span><span>8887:8887</span></div></div><div><div><div>7</div></div><div><span>  </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>3️⃣ 访问 Photopea<a href="#3️⃣-访问-photopea"><span>#</span></a></h3><p>部署完成后，打开浏览器，访问 <code>http://你的服务器IP:8887</code> 即可使用本地部署的 Photopea。</p></section><section><h3>4️⃣ 注意事项<a href="#4️⃣-注意事项"><span>#</span></a></h3><ul>
<li>如果你修改了端口映射，记得使用你设置的端口访问</li>
<li>确保你的服务器防火墙允许该端口的访问</li>
<li>本地部署的 Photopea 功能与在线版本相同，但数据存储在本地，更加安全</li>
</ul></section></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>Photopea 真的是一个宝藏在线图片编辑器，完全免费，功能强大，无需安装，支持多种文件格式，甚至能处理 RAW 文件。无论是直接使用在线版本，还是通过 Docker 部署到本地，都能为你提供专业级的图片编辑体验。</p><p>如果你需要编辑图片，又不想安装大型软件，或者预算有限，Photopea 绝对是你的不二选择！</p><p>不用花一分钱，就能享受到专业级的图片编辑体验，何乐而不为呢？</p></section>
<section><h2>访问地址<a href="#访问地址"><span>#</span></a></h2><ul>
<li><strong>在线版本</strong>：<a href="https://www.photopea.com/" target="_blank">https://www.photopea.com/</a></li>
<li><strong>本地部署</strong>：<a href="http://%E4%BD%A0%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%99%A8IP:8887%EF%BC%88Docker" target="_blank">http://你的服务器IP:8887（Docker</a> 部署后）</li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时用什么工具编辑图片？有没有遇到过需要修图但没有软件的情况？欢迎在评论区分享你的经历！</p><p>如果觉得这篇文章有用，别忘了点赞、在看并分享给身边需要修图的朋友们～</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=992197223&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
<li><a href="https://mp.weixin.qq.com/s/v6cAj0rbaqkjGxOmDE4FNA?token=992197223&amp;lang=zh_CN" target="_blank">FlyCut Caption：AI 辅助视频剪辑神器，让剪视频不再痛苦！</a></li>
<li><a href="https://mp.weixin.qq.com/s/8eXVNKWvk129YcJSaDrsMQ?token=992197223&amp;lang=zh_CN" target="_blank">不用买Mac！Docker里跑macOS，云电脑新玩法</a></li>
</ul><p>（注：文章部分信息来源于 Photopea 官网）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/3b78b10b/</id>
      <title type="text">Project N.O.M.A.D.：离线生存电脑，知识永不离线</title>
      <published>2025-12-23T12:32:13.000Z</published>
      <updated>2025-12-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/3b78b10b/"/>
      <summary type="text">想象一下，当你远离城市，深入荒野，或者遇到网络中断的紧急情况时，如何获取关键信息和工具？今天要给你们介绍一个超级酷的项目——**Project N.O.M.A.D.**，一个自包含的离线生存电脑，让知识和工具永远伴随着你！</summary>
      <content type="html"><![CDATA[<section><h2>嗨，户外爱好者和生存主义者们！<a href="#嗨户外爱好者和生存主义者们"><span>#</span></a></h2><p>想象一下，当你远离城市，深入荒野，或者遇到网络中断的紧急情况时，如何获取关键信息和工具？今天要给你们介绍一个超级酷的项目——<strong>Project N.O.M.A.D.</strong>，一个自包含的离线生存电脑，让知识和工具永远伴随着你！</p></section>
<section><h2>什么是 Project N.O.M.A.D.?<a href="#什么是-project-nomad"><span>#</span></a></h2><p>Project N.O.M.A.D.（Node for Offline Media, Archives, and Data）是一个自包含的、离线优先的知识和教育服务器，它打包了关键工具、知识和 AI，让你在任何时间、任何地点都能获得信息和支持。</p><p>简单来说，它是一个便携式的数字生存工具箱，即使在没有互联网的情况下，也能为你提供丰富的知识和实用工具。</p></section>
<section><h2>核心功能介绍<a href="#核心功能介绍"><span>#</span></a></h2><section><h3>1️⃣ AI 聊天与知识库<a href="#1️⃣-ai-聊天与知识库"><span>#</span></a></h3><p><strong>本地 AI 聊天</strong>：由 Ollama 驱动的本地 AI 聊天，支持文档上传和语义搜索（通过 Qdrant 实现 RAG）。即使离线，也能获取智能问答服务。</p></section><section><h3>2️⃣ 信息库<a href="#2️⃣-信息库"><span>#</span></a></h3><p><strong>离线维基百科</strong>：通过 Kiwix 提供离线维基百科、医学参考资料、生存指南和电子书。无需网络，随时查阅各种知识。</p></section><section><h3>3️⃣ 教育平台<a href="#3️⃣-教育平台"><span>#</span></a></h3><p><strong>Khan Academy 课程</strong>：通过 Kolibri 提供 Khan Academy 课程，支持进度跟踪和多用户支持。即使在野外，也能继续学习。</p></section><section><h3>4️⃣ 离线地图<a href="#4️⃣-离线地图"><span>#</span></a></h3><p><strong>可下载区域地图</strong>：通过 ProtoMaps 提供可下载的区域地图，支持搜索和导航。在没有网络的情况下，也不会迷路。</p></section><section><h3>5️⃣ 数据工具<a href="#5️⃣-数据工具"><span>#</span></a></h3><p><strong>CyberChef</strong>：提供加密、编码、哈希和数据分析工具。保护你的数据安全，处理各种数据问题。</p></section><section><h3>6️⃣ 笔记功能<a href="#6️⃣-笔记功能"><span>#</span></a></h3><p><strong>FlatNotes</strong>：本地笔记功能，支持 Markdown 格式。记录重要信息，整理思路。</p></section><section><h3>7️⃣ 系统基准测试<a href="#7️⃣-系统基准测试"><span>#</span></a></h3><p><strong>内置基准测试</strong>：硬件评分，支持 Builder Tags 和社区排行榜。了解你的设备性能。</p></section><section><h3>8️⃣ 简易设置向导<a href="#8️⃣-简易设置向导"><span>#</span></a></h3><p><strong>引导式首次配置</strong>：带有精选内容集合的引导式首次配置。轻松上手，快速设置。</p></section></section>
<section><h2>技术原理<a href="#技术原理"><span>#</span></a></h2><p>N.O.M.A.D. 是一个管理 UI（“Command Center”）和 API，通过 Docker 编排一组容器化工具和资源。它处理所有内容的安装、配置和更新，让你无需手动操作。</p></section>
<section><h2>安装方法<a href="#安装方法"><span>#</span></a></h2><section><h3>快速安装（仅 Debian 系统）<a href="#快速安装仅-debian-系统"><span>#</span></a></h3><p>在终端中运行以下命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>apt-get</span><span> </span><span>update</span><span> &amp;&amp; </span><span>sudo</span><span> </span><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>curl</span><span> &amp;&amp; </span><span>curl</span><span> </span><span>-fsSL</span><span> </span><span>https://raw.githubusercontent.com/Crosstalk-Solutions/project-nomad/refs/heads/main/install/install_nomad.sh</span><span> </span><span>-o</span><span> </span><span>install_nomad.sh</span><span> &amp;&amp; </span><span>sudo</span><span> </span><span>bash</span><span> </span><span>install_nomad.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>安装完成后，打开浏览器并导航到 <a href="http://localhost:8080%EF%BC%88%E6%88%96" target="_blank">http://localhost:8080（或</a> <a href="http://%E8%AE%BE%E5%A4%87IP:8080%EF%BC%89%E5%BC%80%E5%A7%8B%E6%8E%A2%E7%B4%A2%EF%BC%81" target="_blank">http://设备IP:8080）开始探索！</a></p></section><section><h3>高级安装<a href="#高级安装"><span>#</span></a></h3><p>对于更高级的用户，可以复制 Docker Compose 模板到 docker-compose.yml 文件中，根据自己的喜好进行定制，然后运行 <code>docker compose up -d</code> 启动 Command Center 及其依赖项。</p></section></section>
<section><h2>硬件要求<a href="#硬件要求"><span>#</span></a></h2><section><h3>最低配置<a href="#最低配置"><span>#</span></a></h3><ul>
<li><strong>处理器</strong>：2 GHz 双核处理器或更好</li>
<li><strong>内存</strong>：4GB 系统内存</li>
<li><strong>存储</strong>：至少 5 GB 可用磁盘空间</li>
<li><strong>操作系统</strong>：基于 Debian 的系统（推荐 Ubuntu）</li>
<li><strong>网络</strong>：稳定的互联网连接（仅在安装期间需要）</li>
</ul></section><section><h3>推荐配置（运行 LLM 和其他 AI 工具）<a href="#推荐配置运行-llm-和其他-ai-工具"><span>#</span></a></h3><ul>
<li><strong>处理器</strong>：AMD Ryzen 7 或 Intel Core i7 或更好</li>
<li><strong>内存</strong>：32 GB 系统内存</li>
<li><strong>显卡</strong>：NVIDIA RTX 3060 或 AMD 同等产品或更好（更多 VRAM = 运行更大的模型）</li>
<li><strong>存储</strong>：至少 250 GB 可用磁盘空间（最好是 SSD）</li>
<li><strong>操作系统</strong>：基于 Debian 的系统（推荐 Ubuntu）</li>
<li><strong>网络</strong>：稳定的互联网连接（仅在安装期间需要）</li>
</ul></section></section>
<section><h2>关于互联网使用和隐私<a href="#关于互联网使用和隐私"><span>#</span></a></h2><p>Project N.O.M.A.D. 设计用于离线使用。互联网连接仅在初始安装期间（下载依赖项）和你（用户）决定以后下载其他工具和资源时需要。否则，N.O.M.A.D. 不需要互联网连接，并且<strong>零内置遥测</strong>，保护你的隐私。</p></section>
<section><h2>应用场景<a href="#应用场景"><span>#</span></a></h2><section><h3>1️⃣ 户外活动<a href="#1️⃣-户外活动"><span>#</span></a></h3><ul>
<li><strong>徒步旅行</strong>：离线地图导航，野外生存知识查阅</li>
<li><strong>露营</strong>：获取天气信息，急救知识，烹饪指南</li>
<li><strong>探险</strong>：地理信息，应急联系方式</li>
</ul></section><section><h3>2️⃣ 紧急情况<a href="#2️⃣-紧急情况"><span>#</span></a></h3><ul>
<li><strong>自然灾害</strong>：应急指南，救援信息，医疗知识</li>
<li><strong>网络中断</strong>：保持信息访问，通信工具</li>
<li><strong>偏远地区</strong>：获取教育资源，技术文档</li>
</ul></section><section><h3>3️⃣ 教育与学习<a href="#3️⃣-教育与学习"><span>#</span></a></h3><ul>
<li><strong>偏远地区教育</strong>：离线 Khan Academy 课程</li>
<li><strong>自学</strong>：丰富的知识库，AI 辅助学习</li>
<li><strong>技能培训</strong>：生存技能，技术教程</li>
</ul></section><section><h3>4️⃣ 数字安全<a href="#4️⃣-数字安全"><span>#</span></a></h3><ul>
<li><strong>离线数据处理</strong>：本地加密，数据安全</li>
<li><strong>隐私保护</strong>：零遥测，数据不离开设备</li>
</ul></section></section>
<section><h2>为什么选择 Project N.O.M.A.D.?<a href="#为什么选择-project-nomad"><span>#</span></a></h2><ol>
<li><strong>完全离线</strong>：不依赖互联网，随时随地可用</li>
<li><strong>功能丰富</strong>：集成了多种实用工具和资源</li>
<li><strong>易于安装</strong>：一键安装脚本，快速部署</li>
<li><strong>高度可定制</strong>：可根据需要添加或删除工具</li>
<li><strong>隐私保护</strong>：零内置遥测，数据本地存储</li>
<li><strong>持续更新</strong>：定期添加新功能和资源</li>
</ol></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>Project N.O.M.A.D. 是一个革命性的离线生存电脑项目，它将关键知识和工具打包在一起，让你在任何情况下都能保持信息获取能力。无论是户外探险、紧急情况还是偏远地区工作，它都能成为你的数字生存伙伴。</p><p>如果你是一个户外活动爱好者、生存主义者，或者只是想为紧急情况做准备，Project N.O.M.A.D. 绝对值得尝试！</p></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><ul>
<li>GitHub 仓库：<a href="https://github.com/Crosstalk-Solutions/project-nomad" target="_blank">https://github.com/Crosstalk-Solutions/project-nomad</a></li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你觉得 Project N.O.M.A.D. 最适合哪些场景？你会在什么情况下使用它？欢迎在评论区分享你的想法！</p><p>如果你觉得这篇文章有用，别忘了点赞、在看并分享给喜欢户外活动的朋友们～</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="%E9%93%BE%E6%8E%A5">户外生存必备技能</a></li>
<li><a href="%E9%93%BE%E6%8E%A5">离线工具推荐</a></li>
<li><a href="%E9%93%BE%E6%8E%A5">紧急情况应对指南</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/40bd2acb/</id>
      <title type="text">【工具】修改wsl安装包实际安装位置</title>
      <published>2025-12-23T12:32:13.000Z</published>
      <updated>2025-12-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/40bd2acb/"/>
      <summary type="text">如果你将Ubuntu的文件解压并安装到D盘，但WSL本身仍在C盘，则安装的Ubuntu子系统仍会使用WSL的默认存储路径。在 WSL (Windows Subsystem for Linux) 中，默认情况下安装的 Ubuntu 子系统及其文件存储位置是固定的，但你可以更改 WSL 的安装地址，尤其是对于 WSL 2。下面是如何更改安装地址的步骤。</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>​	如果你将<code>Ubuntu</code>的文件解压并安装到D盘，但WSL本身仍在C盘，则安装的Ubuntu子系统仍会使用WSL的默认存储路径。在 <code>WSL (Windows Subsystem for Linux) </code>中，默认情况下安装的 Ubuntu 子系统及其文件存储位置是固定的，但你可以更改 WSL 的安装地址，尤其是对于 WSL 2。下面是如何更改安装地址的步骤。</p></section>
<section><h2><strong>一、查看安装路径：</strong><a href="#一查看安装路径"><span>#</span></a></h2><p>这一步完全可以不用操作，因为一般情况下WSL 的 Linux系统文件存储在 Windows 文件系统的特定位置。默认情况下，WSL 2 使用一个虚拟硬盘（VHD）来存储文件，而 WSL 1 则将文件存储在 Windows 文件系统中。</p><section><h3>1. wsl2的安装目录<a href="#1-wsl2的安装目录"><span>#</span></a></h3><p>WSL 2: WSL 2 使用一个虚拟硬盘（VHD），存储在 Windows 用户目录下，路径类似于：<code>C:\Users\&lt;YourUsername&gt;\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_&lt;version&gt;\LocalState\ext4.vhdx</code></p></section><section><h3>2. wsl1的安装目录<a href="#2-wsl1的安装目录"><span>#</span></a></h3><p>WSL 1: WSL 1 的文件存储在 Windows 文件系统的目录下，路径类似于：<code>C:\Users\&lt;YourUsername&gt;\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_&lt;version&gt;\LocalState\rootfs</code></p></section></section>
<section><h2>二、操作步骤<a href="#二操作步骤"><span>#</span></a></h2><section><h3>1.查看wsl版本<a href="#1查看wsl版本"><span>#</span></a></h3><p>你可以运行以下命令来查看你使用的是 WSL 1 还是 WSL 2：（打开powershell以管理员身份运行）</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>wsl -l -v</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>列出所有已安装的 WSL 发行版及其版本信息：（VERSION显示2，说明是wsl2）</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/03/image-20250324142307183.png" alt="image-20250324142307183" /><figcaption>image-20250324142307183</figcaption></figure><p></p></section><section><h3>2.更改wsl2的安装位置<a href="#2更改wsl2的安装位置"><span>#</span></a></h3><p>为了将 WSL 2 的安装位置从 C 盘移动到 D 盘，你可以按照以下步骤操作：</p><section><h4>1. 创建目标目录<a href="#1-创建目标目录"><span>#</span></a></h4><p>打开 PowerShell，并运行（以管理员身份运行）以下命令来创建一个目录</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>base</span><span> </span><span>mkdir</span><span> </span><span>D:</span><span>\W</span><span>SL</span><span>\b</span><span>ackup</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>2. 确认路径权限<a href="#2-确认路径权限"><span>#</span></a></h4><p>确保你有权限在 D 盘上创建和写入文件。通过尝试在目标路径创建一个测试文件来确认权限：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>echo</span><span> </span><span>"test"</span><span> &gt; </span><span>D:</span><span>\W</span><span>SL</span><span>\b</span><span>ackup</span><span>\t</span><span>est.txt</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>3. 导出当前的 WSL 发行版<a href="#3-导出当前的-wsl-发行版"><span>#</span></a></h4><p>运行以下命令来导出当前的 Ubuntu 发行版：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wsl</span><span> </span><span>--export</span><span> </span><span>openEuler-23.09</span><span> </span><span>E:</span><span>\W</span><span>SL</span><span>\b</span><span>ackup</span><span>\o</span><span>penEuler.tar</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这会将当前的 Ubuntu 发行版导出为一个 tar 文件。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/03/image-20250324142945817.png" alt="" /></p></section><section><h4>4. 注销当前的 WSL 发行版<a href="#4-注销当前的-wsl-发行版"><span>#</span></a></h4><p>运行以下命令来注销当前的 Ubuntu 发行版：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wsl</span><span> </span><span>--unregister</span><span> </span><span>openEuler-23.09</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/03/image-20250324143025509.png" alt="image-20250324143025509" /><figcaption>image-20250324143025509</figcaption></figure><p></p></section><section><h4>5. 导入 WSL 发行版到新的位置<a href="#5-导入-wsl-发行版到新的位置"><span>#</span></a></h4><p>运行以下命令将导出的 Ubuntu 发行版导入到 D 盘的新位置：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wsl</span><span> </span><span>--import</span><span> </span><span>openEuler-23.09</span><span> </span><span>E:</span><span>\W</span><span>SL</span><span>\o</span><span>penEuler</span><span> </span><span>E:</span><span>\W</span><span>SL</span><span>\b</span><span>ackup</span><span>\o</span><span>penEuler.tar</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这会将 Ubuntu 发行版重新安装到 D 盘的 D:\WSL\Ubuntu 目录中。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/03/image-20250324143037588.png" alt="image-20250324143037588" /><figcaption>image-20250324143037588</figcaption></figure><p></p></section><section><h4>6. 验证安装<a href="#6-验证安装"><span>#</span></a></h4><p>导入完成后，运行以下命令来验证安装是否成功：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wsl</span><span> </span><span>-l</span><span> </span><span>-v</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>你应该会看到类似于之前的输出</p></section><section><h4>7.  启动 WSL<a href="#7--启动-wsl"><span>#</span></a></h4><p>最后，启动 WSL：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span> </span><span>wsl</span><span> </span><span>-d</span><span> </span><span>openEuler-23.09</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>8. 修改默认启动的系统<a href="#8-修改默认启动的系统"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># wsl --set-default &lt;DistributionName&gt;</span></div></div><div><div><div>2</div></div><div><span># 将&lt;DistributionName&gt;替换为你想设置为默认的发行版的名称。例如，如果你想要将Ubuntu设置为默认，你可以使用：</span></div></div><div><div><div>3</div></div><div><span>wsl</span><span> </span><span>--set-default</span><span> </span><span>openEuler-23.09</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/4130e003/</id>
      <title type="text">LX Sync Server 部署指南：轻松搭建自己的洛雪音乐服务</title>
      <published>2025-12-23T12:32:13.000Z</published>
      <updated>2025-12-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/4130e003/"/>
      <summary type="text">LX Sync Server 是 LX Music 的数据同步与 Web 播放中枢服务，它可以帮你搭建一个私有化的音乐云服务，实现多设备间的音乐数据同步，还能提供在线播放功能。</summary>
      <content type="html"><![CDATA[<section><h2>什么是 LX Sync Server？<a href="#什么是-lx-sync-server"><span>#</span></a></h2><p>LX Sync Server 是 LX Music 的数据同步与 Web 播放中枢服务，它可以帮你搭建一个私有化的音乐云服务，实现多设备间的音乐数据同步，还能提供在线播放功能。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/6a57f90cf7f746d1b26aeff1dc6f4d0d20260331090904436.png" alt="" /></p></section>
<section><h2>核心特性<a href="#核心特性"><span>#</span></a></h2><p>LX Sync Server 具有以下强大功能：</p><section><h3>1. 仪表盘<a href="#1-仪表盘"><span>#</span></a></h3><p>提供直观的 Web 界面，实时掌握服务状态与连接数，让你对服务器运行情况一目了然。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/5a4a341f5f0a47f09d1ddee96458972320260331090924490.png" alt="" /></p></section><section><h3>2. 用户管理<a href="#2-用户管理"><span>#</span></a></h3><p>支持通过界面快捷添加、删除用户，修改同步密钥，轻松管理多设备连接权限。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/fe5a1b9b9cdb4b6cbe07dd7ff137c19e20260331090938441.png" alt="" /></p></section><section><h3>3. 数据深度管理<a href="#3-数据深度管理"><span>#</span></a></h3><ul>
<li>在线查看所有用户的歌单和歌曲列表</li>
<li>支持搜索与排序，方便快速定位歌曲</li>
<li>支持批量清理冗余数据或删除歌单
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/320177de4ca04a8591725580da631c7b20260331090957803.png" alt="" /></li>
</ul></section><section><h3>4. WebDAV 云端实时同步<a href="#4-webdav-云端实时同步"><span>#</span></a></h3><ul>
<li>支持坚果云、Nextcloud、Alist 等标准 WebDAV 网盘</li>
<li>支持定时自动将服务器全量数据备份至云端</li>
<li>支持在服务器重置后从云端一键拉回所有数据
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/6bf2ca031bed486e9c5ea24f63b4b22020260331091546561.png" alt="" /></li>
</ul></section><section><h3>5. Web 播放播放器<a href="#5-web-播放播放器"><span>#</span></a></h3><ul>
<li>支持在线播放音乐</li>
<li>支持自定义播放列表</li>
<li>支持播放进度条、音量控制、播放模式切换等功能</li>
<li>界面和功能与 LX Music 客户端一致，操作简单，不过也是一个空壳儿，需要添加音源文件，小伙伴们需要自己添加（私信小王『音乐』，有惊喜哦）。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/a76cef7f99b74e4d99e566ac04cc8c5220260331091202972.png" alt="" /></li>
</ul><p>今天我就来教大家如何用 Docker 快速部署 LX Sync Server，即使你是技术小白，也能轻松搞定，搭建属于自己的音乐服务！</p></section></section>
<section><h2>准备工作<a href="#准备工作"><span>#</span></a></h2><p>在开始部署之前，你需要确保你的设备满足以下条件：</p><ol>
<li>安装了 Docker（如果还没安装，可以搜索一下 Docker 安装教程，很简单的）</li>
<li>确保 9527 端口没有被其他服务占用</li>
<li>有足够的存储空间来存放音乐数据</li>
</ol></section>
<section><h2>部署方法<a href="#部署方法"><span>#</span></a></h2><section><h3>方法一：使用 Docker 命令直接部署<a href="#方法一使用-docker-命令直接部署"><span>#</span></a></h3><p>这是最简单的方法，只需要一条命令就能搞定：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>-p</span><span> </span><span>9527:9527</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>-v</span><span> $(</span><span>pwd</span><span>)</span><span>/data:/server/data</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>-v</span><span> $(</span><span>pwd</span><span>)</span><span>/logs:/server/logs</span><span> </span><span>\</span></div></div><div><div><div>5</div></div><div><span>  </span><span>--name</span><span> </span><span>lx-sync-server</span><span> </span><span>\</span></div></div><div><div><div>6</div></div><div><span>  </span><span>--restart</span><span> </span><span>unless-stopped</span><span> </span><span>\</span></div></div><div><div><div>7</div></div><div><span>  </span><span>ghcr.io/xcq0607/lxserver:latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>命令解释</strong>：</p><ul>
<li><code>-d</code>：后台运行容器</li>
<li><code>-p 9527:9527</code>：将容器的 9527 端口映射到主机的 9527 端口</li>
<li><code>-v $(pwd)/data:/server/data</code>：将容器内的数据目录映射到主机当前目录下的 data 文件夹</li>
<li><code>-v $(pwd)/logs:/server/logs</code>：将容器内的日志目录映射到主机当前目录下的 logs 文件夹</li>
<li><code>--name lx-sync-server</code>：给容器起个名字</li>
<li><code>--restart unless-stopped</code>：容器退出时自动重启</li>
<li><code>ghcr.io/xcq0607/lxserver:latest</code>：使用最新版本的镜像</li>
</ul></section><section><h3>方法二：使用 Docker Compose 部署（推荐）<a href="#方法二使用-docker-compose-部署推荐"><span>#</span></a></h3><p>如果你觉得上面的命令太长，或者想要更方便地管理容器，可以使用 Docker Compose。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/2216a147cfc84a1c860d53df3102bf6820260331090420580.png" alt="" /></p><ol>
<li>新建一个<code>lxsyncserver</code>文件夹，在文件夹中创建一个名为 <code>docker-compose.yml</code> 的文件
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/a858155abb3b4cb88d7188f3f10423eb20260331090706850.png" alt="" /></li>
<li>将以下内容复制到文件中：</li>
</ol><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>version</span><span>: </span><span>'3.8'</span></div></div><div><div><div>2</div></div><div><span>services</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>lxserver</span><span>:</span></div></div><div><div><div>4</div></div><div><span>    </span><span>image</span><span>: </span><span>ghcr.io/xcq0607/lxserver:latest</span></div></div><div><div><div>5</div></div><div><span>    </span><span>container_name</span><span>: </span><span>lx-sync-server</span></div></div><div><div><div>6</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>7</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>8</div></div><div><span><span>      </span></span><span>- </span><span>"9527:9527"</span></div></div><div><div><div>9</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>10</div></div><div><span><span>      </span></span><span>- </span><span>./data:/server/data</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>- </span><span>./logs:/server/logs</span></div></div><div><div><div>12</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span>- </span><span>PORT=9527</span></div></div><div><div><div>14</div></div><div><span><span>      </span></span><span>- </span><span>FRONTEND_PASSWORD=123456</span></div></div><div><div><div>15</div></div><div><span><span>      </span></span><span>- </span><span>DISABLE_TELEMETRY=false</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><ol>
<li>在文件所在目录运行以下命令：</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker-compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>环境变量说明</strong>：</p><ul>
<li><code>PORT</code>：服务端口，默认 9527</li>
<li><code>FRONTEND_PASSWORD</code>：前端访问密码，默认 123456</li>
<li><code>DISABLE_TELEMETRY</code>：是否禁用遥测，默认 false</li>
</ul></section></section>
<section><h2>重要说明：关于挂载卷<a href="#重要说明关于挂载卷"><span>#</span></a></h2><p>在部署时，有两个挂载卷非常重要：</p><ol>
<li>
<p><strong>数据卷</strong>：<code>-v ./data:/server/data</code></p>
<ul>
<li>这个卷存储了所有的应用数据，包括用户信息、认证文件和音乐缓存</li>
<li>一定要配置，否则容器重启后数据会丢失</li>
</ul>
</li>
<li>
<p><strong>日志卷</strong>：<code>-v ./logs:/server/logs</code></p>
<ul>
<li>这个卷存储了服务的日志文件</li>
<li>方便查看服务运行状态和排查问题</li>
</ul>
</li>
</ol></section>
<section><h2>验证部署是否成功<a href="#验证部署是否成功"><span>#</span></a></h2><p>部署完成后，打开浏览器访问 <code>http://你的服务器IP:9527</code>，你应该能看到 LX Sync Server 的登录页面。</p><p>默认用户名是 <code>admin</code>，密码是 <code>FRONTEND_PASSWORD</code>（默认 123456），登录后你就可以开始使用了。</p></section>
<section><h2>访问 Web 播放界面<a href="#访问-web-播放界面"><span>#</span></a></h2><p>除了管理界面，LX Sync Server 还提供了一个 Web 播放界面，你可以通过 <code>http://你的服务器IP:9527/music</code> 访问。</p></section>
<section><h2>导入音源文件<a href="#导入音源文件"><span>#</span></a></h2><p>点击左边任务栏—设置—系统，我们要在这里添加音乐源，用过lxmusic的朋友都知道，目前这只是一个壳，加入了音乐源才有灵魂。
这里要输入管理员密码，输入后才能添加。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/23dcf9eb81e4455dab714cb8020bfc5620260331091844461.png" alt="" />
输入密码后选择你的音源添加就行。【没有音源的朋友可以直接公众号后台回复音乐获取,超多高质量音源】,添加好后就是这样。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/9561f163bcef41e5959094f9d061bc0020260331091923055.png" alt="" /></p></section>
<section><h2>管理后台操作指南<a href="#管理后台操作指南"><span>#</span></a></h2><p>部署完成后，你可以按照以下步骤使用管理后台：</p><ol>
<li>
<p><strong>登录管理后台</strong>：访问 <code>http://你的服务器IP:9527</code>，默认用户名是 <code>admin</code>，密码是 <code>FRONTEND_PASSWORD</code>（默认 123456），请第一时间更改密码哦！！！</p>
</li>
<li>
<p><strong>初始化配置</strong>：首次登录请立即进入“系统配置”修改默认密码，确保服务器安全</p>
</li>
<li>
<p><strong>添加用户</strong>：在“用户管理”页面创建同步账号，生成的密码即为 LX Music 移动端/桌面端连接时使用的密钥</p>
</li>
<li>
<p><strong>配置备份策略</strong>：建议在“WebDAV 同步”中配置云端备份，双重保障数据安全</p>
</li>
<li>
<p><strong>管理数据</strong>：使用“数据管理”功能查看和管理所有用户的歌单和歌曲</p>
</li>
<li>
<p><strong>查看快照</strong>：在“快照管理”中查看自动生成的备份，必要时可以回滚数据</p>
</li>
<li>
<p><strong>查看日志</strong>：通过“系统日志”功能查看服务器运行状态，排查问题</p>
</li>
</ol></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>通过 Docker 部署 LX Sync Server 非常简单，只需要几个步骤就能完成。部署完成后，你就拥有了一个私有化的音乐同步服务，可以在多设备间同步音乐数据，还能在线播放音乐。</p><p>如果你是 LX Music 的用户，或者想要搭建一个自己的音乐云服务，不妨试试 LX Sync Server，相信它会给你带来不错的体验！</p></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><ul>
<li><strong>GitHub 仓库</strong>：<a href="https://github.com/XCQ0607/lxserver" target="_blank">https://github.com/XCQ0607/lxserver</a></li>
<li><strong>官方文档</strong>：<a href="https://xcq0607.github.io/lxserver/guide/getting-started.html" target="_blank">https://xcq0607.github.io/lxserver/guide/getting-started.html</a></li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你有没有使用过类似的音乐同步服务？部署 LX Sync Server 时遇到了什么问题？欢迎在评论区分享你的经验！</p><p>如果觉得这篇文章有用，别忘了点赞、在看并分享给身边的朋友～</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/5655a99e/</id>
      <title type="text">如何把大文件（100M以上）上传到github</title>
      <published>2025-12-23T12:32:13.000Z</published>
      <updated>2025-12-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/5655a99e/"/>
      <summary type="text">GitHub 对文件大小有严格限制，普通存储库中单个文件不能超过 100MB，整个存储库建议小于 1GB，强烈建议小于 5GB。那么，当单个文件超100MB且需要上传到github上时，我们应该怎么处理呢</summary>
      <content type="html"><![CDATA[<p>GitHub 对文件大小有严格限制，普通存储库中单个文件不能超过 <strong>100MB</strong>，整个存储库建议小于 <strong>1GB</strong>，强烈建议小于 <strong>5GB</strong>。以下是处理大文件的常见方法和步骤：</p>
<section><h2>使用 Git LFS 管理大文件<a href="#使用-git-lfs-管理大文件"><span>#</span></a></h2><p><strong>Git LFS (Large File Storage)</strong> 是 Git 的扩展工具，用于管理超出 GitHub 限制的大文件。它通过将大文件存储在仓库外部，仅在仓库中保留引用，从而提高性能和效率。</p><section><h3>配置 Git LFS<a href="#配置-git-lfs"><span>#</span></a></h3><ul>
<li>安装 Git LFS：</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>lfs</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>跟踪大文件类型：</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>lfs</span><span> </span><span>track</span><span> </span><span>"*.ext"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>提交 <em>.gitattributes</em> 文件：</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>add</span><span> </span><span>.gitattributes</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>git</span><span> </span><span>commit</span><span> </span><span>-m</span><span> </span><span>"Track large files with Git LFS"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>添加并提交大文件：</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>add</span><span> </span><span>large_file.ext</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>git</span><span> </span><span>commit</span><span> </span><span>-m</span><span> </span><span>"Add large file using Git LFS"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>推送到远程仓库：</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>push</span><span> </span><span>origin</span><span> </span><span>main</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>拉取含大文件的仓库<a href="#拉取含大文件的仓库"><span>#</span></a></h3><p>如果克隆的仓库中没有大文件本体，而是指针文件，可以运行以下命令下载完整文件：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>lfs</span><span> </span><span>pull</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>转换历史数据到 LFS<a href="#转换历史数据到-lfs"><span>#</span></a></h3><p>对于已经提交到仓库中的大文件，可以使用以下命令迁移到 LFS：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>lfs</span><span> </span><span>migrate</span><span> </span><span>import</span><span> </span><span>--include=</span><span>"*.ext"</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>git</span><span> </span><span>push</span><span> </span><span>--force</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>完成后，清理 <em>.git</em> 文件夹：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>reflog</span><span> </span><span>expire</span><span> </span><span>--expire-unreachable=now</span><span> </span><span>--all</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>git</span><span> </span><span>gc</span><span> </span><span>--prune=now</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>使用 GitHub Releases 分发大文件<a href="#使用-github-releases-分发大文件"><span>#</span></a></h3><p>如果文件超过 Git LFS 的限制（如单文件超过 2GB），可以通过 <strong>GitHub Releases</strong> 分发大文件。创建发行版时，可以上传大文件并生成下载链接。</p><div><div><div></div><div>Important</div></div><div><p><strong>注意事项</strong></p><ul>
<li><strong>Git 不是备份工具</strong>。对于超大文件或数据库，建议使用云存储服务（如 Amazon S3、Google Cloud Storage）。</li>
<li><strong>避免外部依赖项膨胀仓库</strong>。使用包管理器（如 npm、Maven）管理依赖项。</li>
<li><strong>定期优化仓库大小</strong>。使用工具如 <em>git-sizer</em> 分析和管理存储库。</li>
</ul></div></div><p>通过以上方法，可以有效管理和分发大文件，避免 GitHub 文件大小限制带来的问题。</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/58b48df0/</id>
      <title type="text">【音乐】使用 Cloudflare Tunnel 为nas中的洛雪同步服务开启免费、安全、高速的内网穿透</title>
      <published>2025-12-23T12:32:13.000Z</published>
      <updated>2025-12-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/58b48df0/"/>
      <summary type="text">本教程将引导你如何在飞牛（Feiniu）NAS 系统上，通过 Docker 和 Cloudflare Tunnel（也称为 cloudflared）功能，实现免费、安全且无需公网 IP 的内网穿透。这样你就可以在任何地方通过自己的域名访问家中的 NAS 了。</summary>
      <content type="html"><![CDATA[<p>​    本教程将引导你如何在飞牛（Feiniu）NAS 系统上，通过 Docker 和 Cloudflare Tunnel（也称为 cloudflared）功能，实现免费、安全且无需公网 IP 的内网穿透。这样你就可以在任何地方通过自己的域名访问家中的 NAS 了。</p>
<blockquote><p>准备工作:</p></blockquote>
<ul>
<li>一台正在运行的飞牛 NAS。</li>
<li>一个你自己的域名（例如 yourdomain.com）。</li>
<li>将你的域名托管在 Cloudflare 上。</li>
<li>一个 Cloudflare 账号。</li>
</ul>
<section><h2>第一步：在飞牛 NAS 中准备 Docker 环境<a href="#第一步在飞牛-nas-中准备-docker-环境"><span>#</span></a></h2><p>首先，我们需要在 NAS 上下载 Cloudflare Tunnel 的官方 Docker 镜像。</p><ul>
<li>登录你的飞牛 NAS 管理后台。</li>
<li>在桌面找到并点击 <strong>Docker</strong> 图标，进入 Docker 管理器。</li>
<li>在 Docker 管理器左侧菜单中，点击 <strong>镜像仓库</strong>。</li>
<li>在右上角的搜索框中输入 <strong>cloudflared</strong> 并搜索。</li>
<li>在搜索结果中，找到官方镜像 <code>cloudflare/cloudflared</code>（通常下载量最大），然后点击右侧的下载图标。</li>
<li>在弹出的“选择标签”窗口中，保持默认的 <code>latest</code>，然后点击 确定。系统将开始下载镜像。</li>
</ul></section>
<section><h2>第二步：在 Cloudflare 中创建隧道 (Tunnel)<a href="#第二步在-cloudflare-中创建隧道-tunnel"><span>#</span></a></h2><p>现在，我们需要登录 Cloudflare 官网来创建一个隧道并获取连接凭证。</p><ul>
<li>登录你的 <strong><a href="https://dash.cloudflare.com/" target="_blank">Cloudflare Dashboard</a></strong>。</li>
<li>在左侧菜单中，找到并点击 <strong><a href="https://one.dash.cloudflare.com/" target="_blank">Zero Trust</a></strong>。</li>
<li>首次设置 (如果需要)
<ul>
<li>如果你是第一次使用 Zero Trust，系统会要求你设置一个<strong>团队名称</strong>。这个名称将成为你访问后台的子域名，可以自定义。</li>
<li>在选择计划页面，选择左侧的 <strong>Free (免费)</strong> 套餐。</li>
<li>系统可能会要求你添加付款方式，这里有一个技巧可以跳过：直接修改浏览器地址栏的 URL，<strong>删除 .com/ 之后的所有内容</strong>，然后按回车键重新访问。这样就可以绕过付款验证步骤。</li>
</ul>
</li>
<li>成功进入 Zero Trust 仪表盘后，在左侧菜单中点击 <code>网络 (Access) </code>-&gt; <code>隧道 (Tunnels)</code>。</li>
<li>点击 <strong>创建隧道 (Create a tunnel)</strong> 按钮。</li>
<li>在选择连接器类型时，选择 <strong>Cloudflared</strong>，然后点击 <code>下一步 (Next)</code>。</li>
<li>为你的隧道命名，例如 <code>nas</code>，然后点击 <code>保存隧道 (Save tunnel)</code>。</li>
<li>在“选择您的环境”页面，选择 Docker。页面下方会生成一段 docker run 命令，点击复制图标将这段完整的命令复制下来。这段命令包含了连接隧道的唯一 <strong>token</strong>，非常关键。</li>
</ul></section>
<section><h2>第三步：在飞牛NAS上部署洛雪同步程序<a href="#第三步在飞牛nas上部署洛雪同步程序"><span>#</span></a></h2><ul>
<li>
<p>在 Docker 管理器左侧菜单中，点击 <strong>镜像仓库</strong>。</p>
</li>
<li>
<p>在右上角的搜索框中输入 <strong>lyswhut/lx-music-sync-server</strong> 并搜索，这个镜像为作者的镜像源，也可以自己使用源码构建镜像</p>
</li>
<li>
<p>在搜索结果中，找到官方镜像 <code>cloudflare/cloudflared</code>（通常下载量最大），然后点击右侧的下载图标。</p>
</li>
<li>
<p>在弹出的“选择标签”窗口中，保持默认的 <code>latest</code>，然后点击 确定。系统将开始下载镜像。</p>
</li>
<li>
<p>下载完成后，执行以下命令运行容器</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>--name</span><span> </span><span>lxmusicsyncserver</span><span> </span><span>--restart=always</span><span> </span><span>-p</span><span> </span><span>19527:9527</span><span> </span><span>-v</span><span> </span><span>/vol2/docker/containers/lxmusicsyncserver/logs:/server/logs</span><span> </span><span>-v</span><span> </span><span>/vol2/docker/containers/lxmusicsyncserver/data:/server/data</span><span> </span><span>-e</span><span> </span><span>TZ=Asia/Shanghai</span><span> </span><span>-e</span><span> </span><span>LX_USER_user1=password1</span><span>   </span><span>-e</span><span> </span><span>BIND_IP=</span><span>0.0.0.0</span><span> </span><span>-e</span><span> </span><span>PORT=</span><span>9527</span><span>  </span><span>lyswhut/lx-music-sync-server</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ul>
<li>

<table><thead><tr><th>变量名称</th><th>说明</th></tr></thead><tbody><tr><td><code>PORT</code></td><td>绑定的端口号，默认为 <code>9527</code>。</td></tr><tr><td><code>BIND_IP</code></td><td>绑定的 IP 地址，默认为 <code>127.0.0.1</code>，使用 <code>0.0.0.0</code> 将接受所有 IPv4 请求，使用 <code>::</code> 将接受所有 IP 请求。</td></tr><tr><td><code>PROXY_HEADER</code></td><td>代理转发的请求头 原始 IP，如果设置，则自动启用。</td></tr><tr><td><code>CONFIG_PATH</code></td><td>配置文件路径，默认使用项目目录下的 <code>config.js</code>。</td></tr><tr><td><code>LOG_PATH</code></td><td>服务日志保存路径，默认保存在服务目录下的 <code>logs</code> 文件夹内。</td></tr><tr><td><code>DATA_PATH</code></td><td>同步数据保存路径，默认保存在服务目录下的 <code>data</code> 文件夹内。</td></tr><tr><td><code>MAX_SNAPSHOT_NUM</code></td><td>公共最大备份快照数。</td></tr><tr><td><code>SERVER_NAME</code></td><td>同步服务名称。</td></tr><tr><td><code>LIST_ADD_MUSIC_LOCATION_TYPE</code></td><td>公共添加歌曲到我的列表时的方式，可用值为 <code>top</code> 和 <code>bottom</code>。</td></tr><tr><td><code>LX_USER_</code></td><td>以 <code>LX_USER_</code> 开头的环境变量将被识别为用户配置，可用的配置语法为：<br />1. <code>LX_USER_user1='xxx'</code>；<br />2. <code>LX_USER_user1='{"password":"xxx"}'</code>。<br />其中 <code>LX_USER_</code> 会被去掉，剩下的 <code>user1</code> 为用户名，<code>xxx</code> 为用户密码（<strong>连接码</strong>）。<br />配置方式 1 为简写模式，只指定用户名及密码（链接码），其他配置使用公共配置。<br />配置方式 2 为 JSON 字符串格式，配置内容参考 <code>config.js</code>，由于该方式在变量名指定了用户名，所以 JSON 里的用户名是可选的。</td></tr></tbody></table>
</li>
</ul>
</li>
</ul></section>
<section><h2>第四步：在飞牛 NAS 上运行隧道并配置路由<a href="#第四步在飞牛-nas-上运行隧道并配置路由"><span>#</span></a></h2><ul>
<li>
<p>使用 SSH 客户端（如 Windows PowerShell, FinalShell 等）连接到你的飞牛 NAS。</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 请替换成你自己的端口、用户名和IP</span></div></div><div><div><div>2</div></div><div><span>ssh</span><span> </span><span>-p</span><span> </span><span>22</span><span> </span><span>xxx@192.168.1.92</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>登录后，输入 <code>sudo su </code>并再次输入密码，切换到 <code>root</code> 管理员用户。</p>
</li>
<li>
<p>粘贴并执行上一步从 <code>Cloudflare</code> 复制的 <code>docker run</code> 命令。这会首次运行容器并与 Cloudflare 建立连接。看到日志输出后，可以先不用管它。</p>
</li>
<li>
<p>回到飞牛 NAS 的 Docker 管理界面，在 <code>容器</code> 列表中找到刚刚创建的 <code>cloudflared</code> 容器（通常是随机名称），点击右侧的电源图标，将其停止。</p>
</li>
<li>
<p>回到 Cloudflare 的隧道配置页面，点击右下角的 <code>下一步 (Next)</code>。</p>
</li>
<li>
<p><strong>配置公共主机名 (Public Hostname)</strong>，这是将你的域名指向 NAS 的关键步骤。</p>
<ul>
<li><strong>子域名 (Subdomain)</strong>: 输入你想要的前缀，例如 nas。</li>
<li><strong>域 (Domain)</strong>: 从下拉列表中选择你在 Cloudflare 托管的域名。</li>
<li><strong>服务 (Service)</strong>:
<ul>
<li>类型 (Type): <code>HTTP</code></li>
<li>URL: 输入 <code>http://[你的NAS内网IP]:[端口]</code>，例如 <code>http://192.168.1.92:9527</code>。</li>
</ul>
</li>
</ul>
</li>
<li>
<p>点击右下角的 <strong>完成设置 (Save tunnel)</strong>。</p>
</li>
</ul></section>
<section><h2>第五步：启动容器并验证访问<a href="#第五步启动容器并验证访问"><span>#</span></a></h2><ul>
<li>回到飞牛 NAS 的 Docker 管理界面，在 容器 列表中，重新启动之前停止的那个 cloudflared 容器。</li>
<li>打开一个新的浏览器标签页，输入你刚刚配置的完整域名（例如 <a href="https://nas.nas.top%EF%BC%89%E3%80%82" target="_blank">https://nas.nas.top）。</a></li>
<li>你应该能看到飞牛 NAS 的登录界面，并且浏览器地址栏显示的是安全锁（HTTPS 连接），证明内网穿透已经成功！</li>
<li>你还可以尝试在手机上使用移动数据网络访问该域名，同样可以成功登录，证明你可以从任何地方访问你的 NAS。</li>
</ul><p>至此，你的 NAS 内网穿透已全部配置完成！</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/6e688d73/</id>
      <title type="text">斩获1.3K star！！超好用的图片处理项目，隐私优先、浏览器端、开源免费，太6了！</title>
      <published>2025-12-23T12:32:13.000Z</published>
      <updated>2025-12-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/6e688d73/"/>
      <summary type="text">图片优化一直是许多开发者和普通用户的痛点。市面上不少在线工具虽然方便，但隐私问题让人担忧，你的照片可能被偷偷上传到云端，谁知道会被用来干嘛？今天给大家安利一个超酷的开源项目 - Mazanoke，一款在浏览器中运行的本地图片优化工具，简单易用，还能离线工作，隐私拉满！</summary>
      <content type="html"><![CDATA[<section><h2>项目简介<a href="#项目简介"><span>#</span></a></h2><p><code>Mazanoke</code>是一款开源的图片优化工具，它可以在用户的浏览器中运行，无需上传图片至服务器，从而确保了图片的私密性。支持多种图片格式的压缩和转换，比如 JPG、PNG、WebP，甚至还支持 HEIC 和 AVIF 这样的新兴格式。不仅如此，它还能作为渐进式 Web 应用（PWA）安装到桌面或手机上，离线也能用，简直是“随身图片处理厂”！</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/06/7e5b979ea7724459b12a9e149cd57428featured-desktop-solo-dark.webp" alt="111" /><figcaption>111</figcaption></figure><p></p><p>Mazanoke 的界面简洁友好，无论是技术小白还是资深开发者，都能快速上手。你可以调整图片质量、设置目标文件大小、限制最大尺寸，甚至批量处理一堆图片。更贴心的是，它支持从剪贴板直接粘贴图片，省去繁琐的上传步骤。</p><p>目前在Github上收获了1.3K star，非常受开发者的欢迎！</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/06/5a8754352f9b415a9b8b2d4a2b92e990image-20250604092518891.webp" alt="image-20250604092518891" /><figcaption>image-20250604092518891</figcaption></figure><p></p></section>
<section><h2>性能特色<a href="#性能特色"><span>#</span></a></h2><ul>
<li>灵活优化参数：支持手动调节画质压缩率或指定目标文件大小，系统自动匹配最优压缩方案；可限制图片最大宽高并保持比例缩放，避免画面变形。</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/06/7623f5b616214f09a5582c994689c8d5capture-desktop-solo-settings-dark.webp" alt="" /></p><ul>
<li>
<p>全格式转换支持：覆盖 JPG/PNG/WebP 主流格式互转，特别支持 HEIC/AVIF/GIF/SVG 转换为通用格式，轻松适配多设备场景。</p>
</li>
<li>
<p>三重隐私防护：完全离线运行 + 本地处理无痕迹，自动剥离 EXIF 元数据（含位置、设备信息），杜绝数据上传风险与行为追踪。</p>
</li>
<li>
<p>极简交互体验：支持拖拽 / 剪贴板粘贴快速上传，参数调整实时预览；可一键安装为桌面应用，离线使用更便捷。</p>
</li>
<li>
<p>开源自托管优势：遵循 GNU 协议开源，支持 Docker 一键部署私有实例，数据完全自主可控，适配企业与隐私敏感场景。</p>
</li>
</ul></section>
<section><h2>快速安装使用<a href="#快速安装使用"><span>#</span></a></h2><p>Mazanoke的安装和使用非常简单，用户可以通过以下几种方式快速上手：</p><p>1、直接访问官方，网址如下，即可立即体验。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://mazanoke.com</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/06/c98511715c994f76a341f90248a63e41image-20250604092749368.webp" alt="image-20250604092749368" /><figcaption>image-20250604092749368</figcaption></figure><p></p><p>点击右上角的“Install”按钮，就能将 Mazanoke 安装为 PWA，桌面和手机都能用。安装后，它会自动缓存，离线也能正常工作。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/06/56c009fa0eea48c081a6f897ebcde8faimage-20250604093727716.webp" alt="image-20250604093727716" /><figcaption>image-20250604093727716</figcaption></figure><p></p><p>2、自托管部署。如果你想完全掌控，推荐自托管！步骤如下：</p><ul>
<li>
<p>克隆仓库：<code>git clone https://github.com/civilblur/mazanoke.git</code></p>
</li>
<li>
<p>进入目录，打开 <code>index.html</code> 文件，浏览器会直接运行应用。</p>
</li>
</ul><p>要是想通过 Docker 部署，可以直接用以下命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>-p</span><span> </span><span>3474:80</span><span> </span><span>ghcr.io/civilblur/mazanoke:latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后访问 <code>http://localhost:3474</code> 即可。</p><p>MAZANOKE 的界面非常简洁明了。在主界面中，你可以通过拖拽或点击上传图片，然后在下方的设置面板中调整图片的质量、大小和格式等参数。下载按钮清晰可见，方便你保存优化后的图片。</p><ul>
<li>深色模式</li>
</ul><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/06/1c7912de4d3f4a029dfe3319cd42b950image-20250604093836936.webp" alt="image-20250604093836936" /><figcaption>image-20250604093836936</figcaption></figure><p></p><ul>
<li>浅色模式</li>
</ul><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/06/85fcdd9f43c24a26839ba000e372fd4cimage-20250604093911266.webp" alt="image-20250604093911266" /><figcaption>image-20250604093911266</figcaption></figure><p></p><p>设置</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/06/35d804230eac4f7fbdc1f899da1d6c6eimage-20250604093946831.webp" alt="image-20250604093946831" /><figcaption>image-20250604093946831</figcaption></figure><p></p><p>图片下载</p><p>它的操作简单直观，即使是初次使用的用户也能迅速上手。而且，由于所有处理都在本地完成，你无需担心隐私泄露的问题，可以放心地处理个人照片。</p></section>
<section><h2>小结<a href="#小结"><span>#</span></a></h2><p><code>Mazanoke</code>是一款非常出色的图片优化工具，它以其独特的“本地优先”设计理念，为用户提供了一个既方便又安全的图片处理解决方案。无论是普通用户还是专业人士，都可以通过Mazanoke轻松处理图片，满足各种需求。</p><p>更多细节功能，感兴趣的可以到项目地址查看：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://github.com/civilblur/mazanoke</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/9ac8b740/</id>
      <title type="text">微软内部都在用的激活神器！30 秒永久激活 WindowsOffice，小白一看就会</title>
      <published>2025-12-23T12:32:13.000Z</published>
      <updated>2025-12-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/9ac8b740/"/>
      <summary type="text">还在为 Windows 和 Office 的激活问题烦恼吗？今天就为大家分享一个微软工程师私下都在用的开源激活方法，无需复杂操作，不用安装软件，30 秒就能搞定永久激活！</summary>
      <content type="html"><![CDATA[<p>✅ 为什么这个工具值得信赖？</p>
<p>开源透明：这是一个 GitHub 开源项目，代码公开可查，确保无病毒无广告，让你使用得放心。</p>
<p>原理合法：它利用的是微软官方激活机制（HWID/KMS），并非破解版，不会涉及版权风险。</p>
<p>全面支持：全面支持 Windows 10/11 全版本以及 Office 2016 - 2021 全系列，适用性极强。</p>
<p>安全放心：该项目获得了 138,000+ Stars 认证，受到全球开发者的共同监督，质量有保障。</p>
<p>🚀 超简单操作步骤（跟着做就行）</p>
<p>在任务栏搜寻Power，选择 “Windows PowerShell,以管理员身份运行” 。</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/448b3af022354bb19dbf7d2e812a3996image-20251020134402503.png" alt="image-20251020134402503" /><figcaption>image-20251020134402503</figcaption></figure><p></p>
<p>一键下载脚本：复制下面这行代码，粘贴到打开的窗口中：</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>irm</span><span> </span><span>https://get.activated.win</span><span> | </span><span>iex</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>然后按 Enter 执行。</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/0f46c3bd2a1d4adc855bf2678379c654image-20251020134520485.png" alt="image-20251020134520485" /><figcaption>image-20251020134520485</figcaption></figure><p></p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/47265338e17147d38fc1cb123fa3338dimage-20251020134556816.png" alt="image-20251020134556816" /><figcaption>image-20251020134556816</figcaption></figure><p></p>
<p><strong>选项详解：</strong></p>
<p>1、Windows永久激活</p>
<p>2、Office永久激活</p>
<p>3、Windows激活至2038年</p>
<p>4、Windows/Office 180天循环激活</p>
<p>5、查看激活状态</p>
<p>0、退出</p>
<p>6、7、8、9 这几个选项不常用，可以不用理会。</p>
<p>选1永久激活Windows ,如下画面：</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/63317fc285554d038650b51bfbd79d5aimage-20251020134629919.png" alt="image-20251020134629919" /><figcaption>image-20251020134629919</figcaption></figure><p></p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/22e739a1c87a471fb2e5315090bef0e3image-20251020134657485.png" alt="image-20251020134657485" /><figcaption>image-20251020134657485</figcaption></figure><p></p>
<p></p><figure><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/oWfqgV06GPic3xtBiadY9s7Ec6JlClx5g9LOJ3CaAEResY9AJV9R9xCZvJl0QCNsZtWSWgurKopzI9sc8VGSmYMg/640?from=appmsg&amp;watermark=1#imgIndex=9" alt="image.png" /><figcaption>image.png</figcaption></figure><p></p>
<p><strong>💡 温馨提示</strong></p>
<p>如遇安全软件拦截，请选择 “允许运行”，以确保脚本能够正常执行。</p>
<p>确保网络连接稳定，以免影响激活过程。</p>
<p>建议激活前重启电脑，关闭其他程序，以避免不必要的干扰。</p>
<p>特别说明：本方法仅推荐用于测试和学习环境，长期使用请支持正版软件哦！</p>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/9f8fa4c8/</id>
      <title type="text">GitHub 15000+ Star！这个工具让 AI 轻松使用任意软件</title>
      <published>2025-12-23T12:32:13.000Z</published>
      <updated>2025-12-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/9f8fa4c8/"/>
      <summary type="text">最近 GitHub 上又出现了一个爆火的开源项目，短短几天就获得了 8.7k+ Star，甚至后来暴涨到 15000+ Star！它就是由香港大学数据科学实验室(HKUDS)开发的 **CLI-Anything**。</summary>
      <content type="html"><![CDATA[<section><h2>嗨，科技爱好者们！<a href="#嗨科技爱好者们"><span>#</span></a></h2><p>最近 GitHub 上又出现了一个爆火的开源项目，短短几天就获得了 8.7k+ Star，甚至后来暴涨到 15000+ Star！它就是由香港大学数据科学实验室(HKUDS)开发的 <strong>CLI-Anything</strong>。</p><p>这个项目的理念非常简单但强大：<strong>一条命令，让任意软件直接变成 AI 能用的命令行工具</strong>！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/7f3413fb2112474a9b3fb49d2f4ffbd420260323175618725.png" alt="" /></p></section>
<section><h2>什么是 CLI-Anything？<a href="#什么是-cli-anything"><span>#</span></a></h2><p>CLI-Anything 是一个开源项目，其核心目标是构建原生代理软件生态。简单来说，它可以将任何现有的软件通过命令行接口（CLI）暴露给 AI 智能体，让 AI 能够直接操作这些软件。</p><p>正如项目的宣传语所说：“今天的软件为人而生，明天的用户是 Agent”。CLI-Anything 正是为了迎接这个未来而诞生的。</p></section>
<section><h2>核心功能与特点<a href="#核心功能与特点"><span>#</span></a></h2><section><h3>1️⃣ 一键转换，简单易用<a href="#1️⃣-一键转换简单易用"><span>#</span></a></h3><p>CLI-Anything 提供了简单的命令行工具，让你可以轻松地为任何软件创建命令行接口。只需一条命令，就能将图形界面软件转换为 AI 可操作的工具。</p></section><section><h3>2️⃣ 广泛兼容<a href="#2️⃣-广泛兼容"><span>#</span></a></h3><p>无论是什么类型的软件，无论运行在什么平台，CLI-Anything 都能为其创建命令行接口。这意味着 AI 可以操作的软件范围被大大扩展。</p></section><section><h3>3️⃣ 标准化接口<a href="#3️⃣-标准化接口"><span>#</span></a></h3><p>CLI-Anything 为所有软件提供了标准化的命令行接口，使得 AI 能够以统一的方式与不同软件交互，降低了 AI 学习和使用软件的成本。</p></section><section><h3>4️⃣ 安全可靠<a href="#4️⃣-安全可靠"><span>#</span></a></h3><p>CLI-Anything 设计了安全的权限管理机制，确保 AI 只能执行被授权的操作，避免了潜在的安全风险。</p></section></section>
<section><h2>技术原理<a href="#技术原理"><span>#</span></a></h2><p>CLI-Anything 的工作原理主要包括以下几个步骤：</p><ol>
<li><strong>分析软件</strong>：识别软件的功能和接口</li>
<li><strong>创建代理</strong>：为软件创建命令行代理</li>
<li><strong>暴露接口</strong>：将软件功能通过命令行暴露给 AI</li>
<li><strong>接收指令</strong>：接收 AI 发送的命令</li>
<li><strong>执行操作</strong>：执行相应的软件操作并返回结果</li>
</ol><p>通过这种方式，AI 可以像人类一样使用各种软件，而不需要为每个软件开发专门的接口。</p></section>
<section><h2>应用场景<a href="#应用场景"><span>#</span></a></h2><section><h3>1️⃣ AI 辅助办公<a href="#1️⃣-ai-辅助办公"><span>#</span></a></h3><p>让 AI 直接操作办公软件，如 Word、Excel、PowerPoint 等，自动完成文档处理、数据分析等任务。</p></section><section><h3>2️⃣ 智能自动化<a href="#2️⃣-智能自动化"><span>#</span></a></h3><p>通过 AI 控制各种工具软件，实现工作流程的自动化，提高工作效率。</p></section><section><h3>3️⃣ 跨软件协作<a href="#3️⃣-跨软件协作"><span>#</span></a></h3><p>让 AI 协调多个软件之间的工作，实现更复杂的任务处理。</p></section><section><h3>4️⃣ 软件测试与开发<a href="#4️⃣-软件测试与开发"><span>#</span></a></h3><p>利用 AI 对软件进行自动化测试，发现潜在问题。</p></section></section>
<section><h2>与其他项目的融合<a href="#与其他项目的融合"><span>#</span></a></h2><p>CLI-Anything 与另一款爆火的开源项目 OpenClaw（308k+ Star）的融合，更是打造了一个强大的 AI 原生软件生态。通过这种融合，AI 可以更加强大、灵活地操作各种软件。</p></section>
<section><h2>快速开始<a href="#快速开始"><span>#</span></a></h2><section><h3>安装<a href="#安装"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 克隆项目</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/HKUDS/CLI-Anything.git</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 进入项目目录</span></div></div><div><div><div>5</div></div><div><span>cd</span><span> </span><span>CLI-Anything</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 安装依赖</span></div></div><div><div><div>8</div></div><div><span># 根据项目文档执行安装命令</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>基本使用<a href="#基本使用"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 为软件创建命令行接口</span></div></div><div><div><div>2</div></div><div><span>cli-anything</span><span> </span><span>add</span><span> </span><span>--name</span><span> </span><span>"软件名称"</span><span> </span><span>--path</span><span> </span><span>"软件路径"</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 查看已添加的软件</span></div></div><div><div><div>5</div></div><div><span>cli-anything</span><span> </span><span>list</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 执行软件操作</span></div></div><div><div><div>8</div></div><div><span>cli-anything</span><span> </span><span>run</span><span> </span><span>"软件名称"</span><span> </span><span>--command</span><span> </span><span>"操作命令"</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>项目愿景<a href="#项目愿景"><span>#</span></a></h2><p>CLI-Anything 的愿景是构建一个原生代理软件生态，让所有软件都能被 AI 轻松操作。这不仅将改变我们与软件的交互方式，也将为 AI 应用开辟新的可能性。</p><p>随着 AI 技术的不断发展，CLI-Anything 这样的工具将变得越来越重要，它为 AI 与现有软件之间架起了一座桥梁，让 AI 能够充分利用人类已经开发的各种软件资源。</p></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>CLI-Anything 是一个非常有创新性的项目，它通过简单而优雅的方式，解决了 AI 与现有软件交互的问题。它的出现，不仅为 AI 应用提供了更多可能性，也为软件行业的发展指明了新的方向。</p><p>如果你对 AI 技术和软件自动化感兴趣，不妨尝试一下 CLI-Anything，相信它会给你带来惊喜！</p></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><ul>
<li>GitHub 仓库：<a href="https://github.com/HKUDS/CLI-Anything" target="_blank">https://github.com/HKUDS/CLI-Anything</a></li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你觉得 CLI-Anything 最有潜力的应用场景是什么？欢迎在评论区分享你的想法！</p><p>如果你觉得这篇文章有用，别忘了点赞、在看并分享给身边的科技爱好者们～</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="%E9%93%BE%E6%8E%A5">OpenClaw：革命性的开源个人 AI 助手平台</a></li>
<li><a href="%E9%93%BE%E6%8E%A5">AI 智能体开发全攻略</a></li>
<li><a href="%E9%93%BE%E6%8E%A5">命令行工具使用技巧</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和网络资料）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/bfd5870b/</id>
      <title type="text">太牛了！这个免费工具让文件传输比微信还快，再也不用怕大文件发不了了</title>
      <published>2025-12-23T12:32:13.000Z</published>
      <updated>2025-12-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/bfd5870b/"/>
      <summary type="text">想给朋友传个大文件，微信说超过100MB发不了；用QQ传，速度慢得像蜗牛；用网盘，还要上传下载，麻烦死了。前几天我要给同事传一个2GB的设计文件，试了好几种方法都不行，急得我直跺脚。就在这个时候，朋友给我推荐了一个叫 **文件快传** 的工具，说是用P2P技术，传文件超级快，而且没有大小限制。我抱着试试看的心态用了一下，结果直接惊到了！</summary>
      <content type="html"><![CDATA[<section><h2>家人们，我发现了一个传文件的神器！<a href="#家人们我发现了一个传文件的神器"><span>#</span></a></h2><p>你们有没有过这样的经历？</p><p>想给朋友传个大文件，微信说超过100MB发不了；用QQ传，速度慢得像蜗牛；用网盘，还要上传下载，麻烦死了。</p><p>前几天我要给同事传一个2GB的设计文件，试了好几种方法都不行，急得我直跺脚。就在这个时候，朋友给我推荐了一个叫 <strong>文件快传</strong> 的工具，说是用P2P技术，传文件超级快，而且没有大小限制。我抱着试试看的心态用了一下，结果直接惊到了！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/6a49c6c58e884755aec91aa1349c523f20260330141004796.png" alt="" /></p></section>
<section><h2>这个工具到底有多神奇？<a href="#这个工具到底有多神奇"><span>#</span></a></h2><section><h3>1️⃣ 传文件超快，比微信快10倍<a href="#1️⃣-传文件超快比微信快10倍"><span>#</span></a></h3><p>你们知道吗？这个工具用的是WebRTC P2P直连技术，文件直接在两台设备之间传输，不用经过服务器，所以速度超级快。我传那个2GB的设计文件，只用了不到5分钟，比微信快多了！</p></section><section><h3>2️⃣ 没有文件大小限制，想传多大传多大<a href="#2️⃣-没有文件大小限制想传多大传多大"><span>#</span></a></h3><p>不管你要传100MB的视频，还是10GB的电影，都能轻松搞定，再也不用因为文件太大而发愁了。</p></section><section><h3>3️⃣ 安全又隐私，数据不经过服务器<a href="#3️⃣-安全又隐私数据不经过服务器"><span>#</span></a></h3><p>最让我放心的是，这个工具的数据传输是端到端加密的，而且不经过服务器，也就是说，除了你和接收方，没有人能看到你的文件内容，超级安全！</p></section><section><h3>4️⃣ 功能超级全，不止传文件<a href="#4️⃣-功能超级全不止传文件"><span>#</span></a></h3><p>除了传文件，它还能传文字、共享桌面，甚至同步目录，简直是个全能工具！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/8db11c7c4f7944ecb79590121d6764ad20260330141032624.png" alt="" /></p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/d8dc0ad86fd84ab79abec532b3e75a35716dfbf4ab40471198fd0b0476ef567820260330141125800.png" alt="" /></p></section></section>
<section><h2>我的真实使用经历<a href="#我的真实使用经历"><span>#</span></a></h2><p>前几天我用这个工具给同事传设计文件，操作超级简单：</p><ol>
<li>打开文件快传的网页</li>
<li>点击「选择文件」，选中我要传的设计文件</li>
<li>系统生成了一个6位的取件码</li>
<li>我把取件码发给同事</li>
<li>同事打开同一个网页，输入取件码</li>
<li>开始传输，速度超级快，不到5分钟就传完了</li>
</ol><p>整个过程没有登录，没有注册，不用下载任何软件，打开网页就能用，简直不要太方便！</p><p>还有一次，我要给客户演示一个方案，但是客户不在身边，我就用了桌面共享功能，客户输入取件码就能看到我的屏幕，就像面对面演示一样，超级直观！</p></section>
<section><h2>怎么用这个神器？<a href="#怎么用这个神器"><span>#</span></a></h2><section><h3>最简单的方法：直接用在线版<a href="#最简单的方法直接用在线版"><span>#</span></a></h3><p>如果你不想麻烦，直接访问在线版就可以用了，不用下载任何东西：</p></section><section><h3>想自己部署？没问题！<a href="#想自己部署没问题"><span>#</span></a></h3><p>如果你想在自己的服务器或NAS上部署，也超级简单：</p><section><h4>Docker一键部署（推荐）<a href="#docker一键部署推荐"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>services:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>file-transfer-go:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image:</span><span> </span><span>matrixseven/file-transfer-go:latest</span></div></div><div><div><div>4</div></div><div><span>    </span><span>ports:</span></div></div><div><div><div>5</div></div><div><span>      </span><span>-</span><span> </span><span>"8080:8080"</span></div></div><div><div><div>6</div></div><div><span>    </span><span>restart:</span><span> </span><span>unless-stopped</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后打开浏览器访问 <code>http://你的服务器IP:8080</code> 就可以用了。</p></section></section></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>设计师</strong>：经常需要传大的设计文件</li>
<li><strong>程序员</strong>：传代码、传项目文件</li>
<li><strong>学生党</strong>：传作业、传课件、传视频</li>
<li><strong>上班族</strong>：传工作文件、演示文稿</li>
<li><strong>任何人</strong>：需要传文件的人</li>
</ul></section>
<section><h2>其他超实用的功能<a href="#其他超实用的功能"><span>#</span></a></h2><ul>
<li><strong>多文件同时传输</strong>：一次可以传多个文件，超级方便</li>
<li><strong>断点续传</strong>：如果传输过程中网络中断，重新连接后可以继续传，不用从头开始</li>
<li><strong>响应式设计</strong>：在手机、平板、电脑上都能完美使用</li>
<li><strong>目录同步</strong>：支持整个目录的同步，不用一个一个传文件</li>
</ul></section>
<section><h2>总结一下<a href="#总结一下"><span>#</span></a></h2><p>文件快传真的是我最近发现的最实用的工具，它解决了我传大文件的困扰，而且速度快、安全、方便，简直是传文件的神器！</p><p>如果你也经常需要传文件，尤其是大文件，一定要试试这个工具，相信我，你会爱上它的！</p></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><ul>
<li><strong>GitHub 仓库</strong>：<a href="https://github.com/MatrixSeven/file-transfer-go" target="_blank">https://github.com/MatrixSeven/file-transfer-go</a></li>
<li><strong>在线体验</strong>：<a href="https://transfer.52python.cn/" target="_blank">https://transfer.52python.cn/</a></li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时传大文件都用什么方法？遇到过什么困扰？用了文件快传后有什么感受？欢迎在评论区分享你的故事！</p><p>如果觉得这篇文章有用，别忘了点赞、在看并分享给身边需要传文件的朋友们～</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/eb3d511e/</id>
      <title type="text">JadeAI：AI 驱动的智能简历构建器，让你的简历脱颖而出</title>
      <published>2025-12-23T12:32:13.000Z</published>
      <updated>2025-12-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/eb3d511e/"/>
      <summary type="text">找工作时，一份专业、吸引人的简历是打开职场大门的第一把钥匙。但制作一份优秀的简历往往需要花费大量时间和精力，尤其是在面对不同岗位的 JD 时，需要不断调整和优化。</summary>
      <content type="html"><![CDATA[<section><h2>嗨，职场人们！<a href="#嗨职场人们"><span>#</span></a></h2><p>找工作时，一份专业、吸引人的简历是打开职场大门的第一把钥匙。但制作一份优秀的简历往往需要花费大量时间和精力，尤其是在面对不同岗位的 JD 时，需要不断调整和优化。</p><p>今天要给你们推荐一个超级好用的工具——<strong>JadeAI</strong>，一个 AI 驱动的智能简历构建器，让你的简历制作变得简单高效！</p></section>
<section><h2>什么是 JadeAI？<a href="#什么是-jadeai"><span>#</span></a></h2><p>JadeAI 是一个开源、免费的 AI 智能简历构建器，它提供了丰富的功能，帮助你轻松创建专业、个性化的简历。无论是刚毕业的学生还是职场老手，都能通过 JadeAI 制作出令人印象深刻的简历。</p></section>
<section><h2>核心功能介绍<a href="#核心功能介绍"><span>#</span></a></h2><section><h3>1️⃣ 直观的简历编辑<a href="#1️⃣-直观的简历编辑"><span>#</span></a></h3><p><strong>拖拽式编辑器</strong>：可视化排列和重新排序简历部分和项目，操作简单直观。</p><p><strong>内联编辑</strong>：直接在画布上点击任何字段进行编辑，所见即所得。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/2abf26d2755e4b5a916290a942c94b2aresume-edit.png" alt="" />
<strong>50+ 专业模板</strong>：提供经典、现代、极简、创意、ATS 友好、时间线、北欧、瑞士等多种风格的模板。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/fec658cfee5c43a78261ec974d8a0f9atemplate-list.png" alt="" />
<strong>主题定制</strong>：可自定义颜色、字体、间距和边距，实时预览效果。</p><p><strong>编辑历史</strong>：支持最多 50 步的撤销/重做操作，不用担心操作失误。</p><p><strong>自动保存</strong>：可配置保存间隔（0.3s-5s），也支持手动保存。</p><p><strong>Markdown 支持</strong>：在文本字段中使用 Markdown 语法格式化内容，如 <strong>粗体</strong>、<code>代码</code>、项目符号列表等。</p></section><section><h3>2️⃣ 强大的 AI 功能<a href="#2️⃣-强大的-ai-功能"><span>#</span></a></h3><p><strong>AI 聊天助手</strong>：编辑器中集成的会话式 AI，支持多会话和持久历史记录。</p><p><strong>AI 简历生成</strong>：根据职位、经验和技能生成完整的简历。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/72706c75c5784c2d8ccd8077f7affff7AI%2520%25E5%25A1%25AB%25E5%2585%2585%25E7%25AE%2580%25E5%258E%2586.gif" alt="" />
<strong>简历解析</strong>：上传现有的 PDF 或图像，AI 自动提取所有内容。</p><p><strong>JD 匹配分析</strong>：将简历与职位描述进行比较，提供关键词匹配、ATS 评分和改进建议。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/6944c04d5e7a4935910b269e4cc60952JD%2520%25E5%258C%25B9%25E9%2585%258D%25E5%2588%2586%25E6%259E%2590.png" alt="" />
<strong>求职信生成</strong>：基于简历和 JD 生成 AI 定制的求职信，可选择语气（正式/友好/自信）。</p><p><strong>语法和写作检查</strong>：检测弱动词、模糊描述和语法问题，返回质量评分。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/a9a35a9479574f30a798cc3111d37c5dAI%2520%25E8%25AF%25AD%25E6%25B3%2595%25E6%25A3%2580%25E6%259F%25A5.png" alt="" />
<strong>翻译</strong>：在保留技术术语的同时，将简历内容翻译成 10 种语言。</p><p><strong>灵活的 AI 提供商</strong>：支持 OpenAI、Anthropic 和自定义 API 端点，每个用户在应用内配置自己的密钥。</p></section><section><h3>3️⃣ 多格式导出与分享<a href="#3️⃣-多格式导出与分享"><span>#</span></a></h3><p><strong>多格式导出</strong>：PDF（Puppeteer + Chromium）、智能单页 PDF（自动适应单页）、DOCX、HTML、TXT、JSON。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/32cd321d038d4cd6846a75316dd49775%25E5%25A4%259A%25E9%25A1%25B9%25E5%25AF%25BC%25E5%2587%25BA.png" alt="" />
<strong>JSON 导入</strong>：导入之前导出的 JSON 文件以恢复或创建简历，支持在编辑器中（覆盖当前）和仪表板上（创建新）。</p><p><strong>链接分享</strong>：基于令牌的可共享链接，可选密码保护。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/8660589e3eb44231befd7cd4eacb622e%25E5%2588%259B%25E5%25BB%25BA%25E5%2588%2586%25E4%25BA%25AB%25E9%2593%25BE%25E6%258E%25A5.png" alt="" />
<strong>查看计数器</strong>：跟踪共享简历被查看的次数。</p></section><section><h3>4️⃣ 简历管理<a href="#4️⃣-简历管理"><span>#</span></a></h3><p><strong>多简历仪表板</strong>：网格和列表视图，搜索，排序（按日期、名称）。</p><p><strong>从 JSON 导入</strong>：直接在仪表板上从 JSON 导出创建新简历。</p><p><strong>复制和重命名</strong>：快速简历管理操作。</p><p><strong>交互式导览</strong>：为首次用户提供分步入门指南。</p></section><section><h3>5️⃣ 其他功能<a href="#5️⃣-其他功能"><span>#</span></a></h3><p><strong>双语界面</strong>：完整的中文（zh）和英文（en）界面。</p><p><strong>暗黑模式</strong>：支持浅色、深色和系统主题。</p><p><strong>灵活的认证</strong>：Google OAuth 或浏览器指纹（零配置）。</p><p><strong>双数据库</strong>：SQLite（默认，零配置）或 PostgreSQL。</p></section></section>
<section><h2>快速开始<a href="#快速开始"><span>#</span></a></h2><section><h3>Docker 部署（推荐）<a href="#docker-部署推荐"><span>#</span></a></h3><ol>
<li>
<p><strong>生成密钥</strong></p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 生成一个随机字符串，用于会话加密。可以使用我的，没啥影响</span></div></div><div><div><div>2</div></div><div><span># dACup1/h17qQkOag7wJu7gJBvUgFfrKvAfc+r3kg1HA=</span></div></div><div><div><div>3</div></div><div><span>openssl</span><span> </span><span>rand</span><span> </span><span>-base64</span><span> </span><span>32</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p><strong>运行容器</strong></p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>-p</span><span> </span><span>3000:3000</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>-e</span><span> </span><span>AUTH_SECRET=dACup1/h17qQkOag7wJu7gJBvUgFfrKvAfc+r3kg1HA=</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>-v</span><span> </span><span>jadeai-data:/app/data</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>twwch/jadeai:latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p><strong>访问应用</strong>
打开 <a href="http://localhost:3000%E3%80%82%E6%95%B0%E6%8D%AE%E5%BA%93%E5%9C%A8%E9%A6%96%E6%AC%A1%E5%90%AF%E5%8A%A8%E6%97%B6%E4%BC%9A%E8%87%AA%E5%8A%A8%E8%BF%81%E7%A7%BB%E5%92%8C%E7%A7%8D%E5%AD%90%E3%80%82" target="_blank">http://localhost:3000。数据库在首次启动时会自动迁移和种子。</a></p>
<p><strong>注意</strong>：AUTH_SECRET 是会话加密所必需的。使用 openssl rand -base64 32 生成一个。</p>
</li>
</ol></section><section><h3>AI 配置<a href="#ai-配置"><span>#</span></a></h3><p>无需服务器端 AI 环境变量。每个用户在应用内的设置 &gt; AI 中配置自己的 API 密钥、基础 URL 和模型。</p></section><section><h3>使用 PostgreSQL<a href="#使用-postgresql"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>-p</span><span> </span><span>3000:3000</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>-e</span><span> </span><span>AUTH_SECRET=dACup1/h17qQkOag7wJu7gJBvUgFfrKvAfc+r3kg1HA=</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>-e</span><span> </span><span>DB_TYPE=postgresql</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>-e</span><span> </span><span>DATABASE_URL=postgresql://user:pass@host:5432/jadeai</span><span> </span><span>\</span></div></div><div><div><div>5</div></div><div><span>  </span><span>twwch/jadeai:latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>应用场景<a href="#应用场景"><span>#</span></a></h2><p>JadeAI 特别适合以下场景：</p><ul>
<li><strong>求职者</strong>：快速创建和优化简历，提高求职成功率</li>
<li><strong>职场人士</strong>：更新简历，适应不同岗位的需求</li>
<li><strong>招聘人员</strong>：分析简历与职位的匹配度</li>
<li><strong>学生</strong>：制作第一份专业简历，迈出职场第一步</li>
</ul></section>
<section><h2>为什么选择 JadeAI？<a href="#为什么选择-jadeai"><span>#</span></a></h2><ol>
<li><strong>开源免费</strong>：完全开源，免费使用，无隐藏费用</li>
<li><strong>AI 驱动</strong>：利用 AI 技术优化简历，提高竞争力</li>
<li><strong>功能丰富</strong>：提供从编辑到导出的完整功能</li>
<li><strong>易于部署</strong>：一键 Docker 部署，快速开始使用</li>
<li><strong>高度定制</strong>：支持多种模板和主题，满足个性化需求</li>
<li><strong>多语言支持</strong>：支持中英文界面和多语言翻译</li>
</ol></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>JadeAI 是一个功能强大、易于使用的 AI 智能简历构建器，它将 AI 技术与简历制作相结合，帮助用户创建专业、有针对性的简历。无论是寻找第一份工作还是寻求职业发展，JadeAI 都能为你提供有力的支持。</p><p>如果你正在为简历制作而烦恼，不妨试试 JadeAI，让 AI 帮助你打造一份脱颖而出的简历！</p></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><ul>
<li>GitHub 仓库：<a href="https://github.com/twwch/JadeAI" target="_blank">https://github.com/twwch/JadeAI</a></li>
<li>中文文档：项目仓库中提供</li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你在制作简历时遇到过哪些困难？JadeAI 能解决你的问题吗？欢迎在评论区分享你的想法！</p><p>如果你觉得这篇文章有用，别忘了点赞、在看并分享给正在找工作的朋友们～</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/v6cAj0rbaqkjGxOmDE4FNA?token=992197223&amp;lang=zh_CN" target="_blank">FlyCut Caption：AI 辅助视频剪辑神器，让剪视频不再痛苦！</a></li>
<li><a href="https://mp.weixin.qq.com/s/8eXVNKWvk129YcJSaDrsMQ?token=992197223&amp;lang=zh_CN" target="_blank">不用买Mac！Docker里跑macOS，云电脑新玩法</a></li>
<li><a href="https://mp.weixin.qq.com/s/SMm_gqkJDQSrNuXP1wxnaA?token=992197223&amp;lang=zh_CN" target="_blank">AiToEarn：AI 驱动的内容增长与变现平台，让创作更有价值！</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/f80b21bd/</id>
      <title type="text">【工具】OpenEuler安装xfce桌面及远程桌面软件xrdp</title>
      <published>2025-12-23T12:32:13.000Z</published>
      <updated>2025-12-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/f80b21bd/"/>
      <summary type="text">OpenEuler安装xfce桌面及远程桌面软件xrdp</summary>
      <content type="html"><![CDATA[<section><h2>1.更新软件源<a href="#1更新软件源"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>dnf update</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>安装字库</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>dnf install dejavu-fonts liberation-fonts gnu-*-fonts google-*-fonts</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>安装 Xorg</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>dnf install xorg-*</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>2.安装 xfce<a href="#2安装-xfce"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>dnf install xfwm4 xfdesktop xfce4-* xfce4-*-plugin network-manager-applet *fonts</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>安装登录管理器</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>dnf install lightdm lightdm-gtk</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/03/image-20250324143755795.png" alt="image-20250324143755795" /><figcaption>image-20250324143755795</figcaption></figure><p></p><p><strong>设置默认桌面为XFCE 通过root权限用户设置</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>echo 'user-session=xfce' &gt;&gt; /etc/lightdm/lightdm.conf.d/60-lightdm-gtk-greeter.conf</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>使用登录管理器登录XFCE</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>systemctl start lightdm</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>登录管理器启动后，在右上角左侧选择”xfce-session” 输入用户名、密码登录</p><p>设置开机自启动图形界面</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>systemctl enable lightdm</span></div></div><div><div><div>2</div></div><div><span>systemctl set-default graphical.target</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果默认安装了gdm，建议停用gdm</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>systemctl disable gdm</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>重启验证</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>reboot</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>登录界面是黑色的是因为lightdm-gtk默认配置文件/etc/lightdm/lightdm-gtk-greeter.conf中没有设置background。 可以在该配置文件最后的[greeter]段中设置 background=/usr/share/backgrounds/xfce/xfce-blue.jpg 然后systemctl restart lightdm 就可以看到背景了。</p></blockquote></section>
<section><h2>3.安装远程连接软件 xrdp<a href="#3安装远程连接软件-xrdp"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>wget https://mirrors.aliyun.com/epel/epel-release-latest-8.noarch.rpm</span></div></div><div><div><div>2</div></div><div><span>rpm -ivh epel-release-latest-8.noarch.rpm --nodeps</span></div></div><div><div><div>3</div></div><div><span>yum -y install xrdp</span></div></div><div><div><div>4</div></div><div><span># sed -i 's/port=3389/port=3390/g' /etc/xrdp/xrdp.ini</span></div></div><div><div><div>5</div></div><div><span>sed -i 's/max_bpp=32/max_bpp=24/g' /etc/xrdp/xrdp.ini</span></div></div><div><div><div>6</div></div><div><span>touch .xsession</span></div></div><div><div><div>7</div></div><div><span>echo xfce4-session &gt; /root/.xsession</span></div></div><div><div><div>8</div></div><div><span>chmod +x /root/.xsession</span></div></div><div><div><div>9</div></div><div><span>systemctl restart xrdp &amp;&amp; systemctl enable xrdp</span></div></div><div><div><div>10</div></div><div><span>rm -rf /etc/yum.repos.d/epel*</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h3>4.防火墙<a href="#4防火墙"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 可能需要的其他操作:</span></div></div><div><div><div>2</div></div><div><span># 关闭防火墙</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>systemctl stop firewalld.service  #临时关闭</span></div></div><div><div><div>5</div></div><div><span>systemctl disable firewalld.servie #永久关闭</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 开放端口</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>firewall-cmd --permanent --zone=public --add-port=3389/tcp</span></div></div><div><div><div>10</div></div><div><span>firewall-cmd --reload</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/1e580fee/</id>
      <title type="text">Windows 桌面全新体验！Seelen-UI 让你的电脑界面美到窒息，完全自定义</title>
      <published>2025-11-23T12:32:13.000Z</published>
      <updated>2025-11-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/1e580fee/"/>
      <summary type="text">前几天我发现了一个超棒的 Windows 桌面自定义工具——**Seelen-UI**，它能让你的 Windows 10/11 桌面变得超级美观，而且完全可以按照你的喜好自定义！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！Windows 桌面也能变得这么好看？<a href="#朋友们windows-桌面也能变得这么好看"><span>#</span></a></h2><p>前几天我发现了一个超棒的 Windows 桌面自定义工具——<strong>Seelen-UI</strong>，它能让你的 Windows 10/11 桌面变得超级美观，而且完全可以按照你的喜好自定义！</p><p>今天我就来给大家介绍一下这个神器，让你的电脑桌面焕然一新！</p></section>
<section><h2>什么是 Seelen-UI？<a href="#什么是-seelen-ui"><span>#</span></a></h2><p>Seelen-UI 是一个完全可自定义的 Windows 桌面环境，它使用 Rust + Tauri 作为后端，TypeScript + React/Preact 作为前端，提供了一套全新的桌面交互体验。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/58865d68c73b414488c3d4202302c85020260413173529441.png" alt="" /></p></section>
<section><h2>为什么推荐 Seelen-UI？<a href="#为什么推荐-seelen-ui"><span>#</span></a></h2><section><h3>1️⃣ 完全可自定义<a href="#1️⃣-完全可自定义"><span>#</span></a></h3><p>Seelen-UI 允许你完全自定义桌面环境，包括：</p><ul>
<li>桌面图标样式</li>
<li>任务栏外观</li>
<li>窗口管理</li>
<li>主题颜色</li>
<li>动画效果
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/14e53ddbb0ae4130bc622f0b815f6984main.gif" alt="" /></li>
</ul></section><section><h3>2️⃣ 现代美观的界面<a href="#2️⃣-现代美观的界面"><span>#</span></a></h3><p>Seelen-UI 采用了现代的设计风格，界面美观流畅，给人一种全新的视觉体验。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/9fcdcd4ce63b415aa0fd2dc41455387e20260413173609952.png" alt="" /></p></section><section><h3>3️⃣ 强大的功能<a href="#3️⃣-强大的功能"><span>#</span></a></h3><p>Seelen-UI 提供了很多实用的功能：</p><ul>
<li><strong>SeelenWeg</strong>：类似 Dock 或 Taskbar 的功能，可以快速访问常用应用</li>
<li><strong>应用分组</strong>：可以将多个应用分组到一个项目中</li>
<li><strong>实时应用标题变化</strong>：实时显示应用标题的变化</li>
<li><strong>UWP 应用支持</strong>：支持 Windows 通用应用</li>
<li><strong>网络图标支持</strong>：正确显示网络连接状态
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/4344817b3a1e4339873608ed6045833520260413173749938.png" alt="" /></li>
</ul></section><section><h3>4️⃣ 性能优秀<a href="#4️⃣-性能优秀"><span>#</span></a></h3><p>由于使用了 Rust 作为后端，Seelen-UI 运行速度快，占用资源少，不会影响系统性能。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/92795ed0e8c44db9a6bdc823f1dd600d20260413173659311.png" alt="" /></p></section><section><h3>5️⃣ 易于安装<a href="#5️⃣-易于安装"><span>#</span></a></h3><p>Seelen-UI 可以通过 winget 命令快速安装，非常方便。</p></section></section>
<section><h2>如何安装 Seelen-UI？<a href="#如何安装-seelen-ui"><span>#</span></a></h2><section><h3>方法一：使用 winget 安装（推荐）<a href="#方法一使用-winget-安装推荐"><span>#</span></a></h3><ol>
<li>打开命令提示符或 PowerShell</li>
<li>输入以下命令：
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>winget install --id Seelen.SeelenUI</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>等待安装完成</li>
<li>启动 Seelen-UI</li>
</ol></section><section><h3>方法二：从 GitHub 下载安装<a href="#方法二从-github-下载安装"><span>#</span></a></h3><ol>
<li>访问 Seelen-UI 的 GitHub 仓库：<a href="https://github.com/eythaann/Seelen-UI" target="_blank">https://github.com/eythaann/Seelen-UI</a></li>
<li>下载最新的安装包</li>
<li>运行安装包进行安装</li>
<li>启动 Seelen-UI</li>
</ol></section></section>
<section><h2>如何使用 Seelen-UI？<a href="#如何使用-seelen-ui"><span>#</span></a></h2><section><h3>1. 基本设置<a href="#1-基本设置"><span>#</span></a></h3><ul>
<li>启动 Seelen-UI 后，会自动替换默认的桌面环境</li>
<li>你可以通过右键点击桌面或任务栏，进入设置界面</li>
<li>在设置界面中，你可以调整各种外观和行为选项</li>
</ul></section><section><h3>2. 使用 SeelenWeg<a href="#2-使用-seelenweg"><span>#</span></a></h3><ul>
<li>SeelenWeg 是一个类似 Dock 的功能，可以快速访问常用应用</li>
<li>你可以将常用应用拖放到 SeelenWeg 上</li>
<li>可以通过右键点击应用，进行分组或其他操作</li>
</ul></section><section><h3>3. 自定义主题<a href="#3-自定义主题"><span>#</span></a></h3><ul>
<li>在设置界面中，你可以选择或创建自定义主题</li>
<li>可以调整颜色、字体、图标等各种视觉元素</li>
<li>可以导入或导出主题，与他人分享你的设计</li>
</ul></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>使用 Seelen-UI 后，我的 Windows 桌面焕然一新，感觉就像换了一台新电脑：</p><ol>
<li><strong>界面美观</strong>：现代的设计风格，流畅的动画效果，让桌面看起来非常专业</li>
<li><strong>操作便捷</strong>：SeelenWeg 让我可以快速访问常用应用，提高了工作效率</li>
<li><strong>完全自定义</strong>：我可以按照自己的喜好调整各种设置，打造属于自己的桌面环境</li>
<li><strong>性能优秀</strong>：运行流畅，没有明显的卡顿或资源占用</li>
</ol></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>桌面美化爱好者</strong>：喜欢自定义桌面外观的用户</li>
<li><strong>效率追求者</strong>：希望通过优化桌面环境提高工作效率的用户</li>
<li><strong>Windows 用户</strong>：想要给 Windows 桌面带来新鲜体验的用户</li>
<li><strong>开发者</strong>：对桌面环境开发感兴趣的开发者</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 Seelen-UI 感兴趣，可以访问它的 GitHub 仓库：<a href="https://github.com/eythaann/Seelen-UI" target="_blank">https://github.com/eythaann/Seelen-UI</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时喜欢什么样的桌面环境？使用 Seelen-UI 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/LCN8quv3VG3MPd54vXv2ig?token=1317674859&amp;lang=zh_CN" target="_blank">音乐爱好者福音！MiMusic 自托管个人音乐服务器，简单自由又强大</a></li>
<li><a href="https://mp.weixin.qq.com/s/qKNZhgiM63HZVlU9ZRWYNg?token=1317674859&amp;lang=zh_CN" target="_blank">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</a></li>
<li><a href="https://mp.weixin.qq.com/s/PetBOJ-4waImUBYpdeU_fw?token=1317674859&amp;lang=zh_CN" target="_blank">2026最新整理！这几款观影软件太香了，电影爱好者福音！附下载地址</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/2f692bcc/</id>
      <title type="text">Windows设置exe或者bat文件开机启动的几种方法</title>
      <published>2025-11-23T12:32:13.000Z</published>
      <updated>2025-11-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/2f692bcc/"/>
      <summary type="text">本文详细介绍了如何通过快捷方式置入启动路径、任务计划程序、组策略、注册表调整及创建Windows服务来实现Windows开机启动，包括用户和系统启动项设置，以及常见操作步骤和注意事项。</summary>
      <content type="html"><![CDATA[<section><h2>1.前言<a href="#1前言"><span>#</span></a></h2><p>Windows设置开机启动的办法有很多种，这里简单总结一下，方便备查。</p></section>
<section><h2>2 启动路径方式<a href="#2-启动路径方式"><span>#</span></a></h2><section><h3>2.1 将快捷方式放入系统启动路径<a href="#21-将快捷方式放入系统启动路径"><span>#</span></a></h3><p>首先 Windows+R 打开 运行窗口</p><blockquote><p>Windows+R</p></blockquote><p>然后输入 shell startup</p><blockquote><p>shell startup</p></blockquote><p>打开的路径是：C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup</p><blockquote><p>C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/07/fc0ed3fd787741d98103f60bbfdc3980image-20250725091045714.png" alt="image-20250725091045714" /><figcaption>image-20250725091045714</figcaption></figure><p></p></section><section><h3>2.2 将快捷方式放入用户启动路径<a href="#22-将快捷方式放入用户启动路径"><span>#</span></a></h3><p>首先 Windows+R 打开 运行窗口</p><blockquote><p>Windows+R</p></blockquote><p>然后输入 shell</p><blockquote><p>shell</p></blockquote><p>打开的路径是：C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup</p><blockquote><p>C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/07/a5c5f7f0d389424b916c69c0cc3bdb2eimage-20250725091142389.png" alt="image-20250725091142389" /><figcaption>image-20250725091142389</figcaption></figure><p></p></section></section>
<section><h2>2 任务计划程序方式<a href="#2-任务计划程序方式"><span>#</span></a></h2><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/07/9028aca0adcf4b1caf8c736b5f07029aimage-20250725091329980.png" alt="image-20250725091329980" /><figcaption>image-20250725091329980</figcaption></figure>
<figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/07/d582e89b3e1e4c539f3f640372d8c62aimage-20250725091408644.png" alt="image-20250725091408644" /><figcaption>image-20250725091408644</figcaption></figure><p></p></section>
<section><h2>3 组策略方式<a href="#3-组策略方式"><span>#</span></a></h2><blockquote><p>gpedit.msc</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/07/70448c28b5b04da3bc91f57f98adcca9image-20250725091536118.png" alt="image-20250725091536118" /><figcaption>image-20250725091536118</figcaption></figure>
<figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/07/f2a62b73bb4046f59ecdccea0df1c325image-20250725091515309.png" alt="image-20250725091515309" /><figcaption>image-20250725091515309</figcaption></figure><p></p></section>
<section><h2>4 注册表方式<a href="#4-注册表方式"><span>#</span></a></h2><blockquote><p>regedit</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/07/04228caa1f3a4c5ea012fec606d2165aimage-20250725091607407.png" alt="image-20250725091607407" /><figcaption>image-20250725091607407</figcaption></figure><p></p><section><h3>4.1 用户启动项路径<a href="#41-用户启动项路径"><span>#</span></a></h3><blockquote><p>计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run</p></blockquote></section><section><h3>4.2 系统启动项路径1<a href="#42-系统启动项路径1"><span>#</span></a></h3><blockquote><p>计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run</p></blockquote></section><section><h3>4.3 系统启动项路径2<a href="#43-系统启动项路径2"><span>#</span></a></h3><blockquote><p>计算机\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run</p></blockquote></section><section><h3>4.4 设置exe或者bat的路径<a href="#44-设置exe或者bat的路径"><span>#</span></a></h3><p></p><figure><img src="https://i-blog.csdnimg.cn/blog_migrate/052fb900cfd500f9ea2a026782d4de2a.png" alt="在这里插入图片描述" /><figcaption>在这里插入图片描述</figcaption></figure><p></p></section></section>
<section><h2>5 创建Windows服务方式<a href="#5-创建windows服务方式"><span>#</span></a></h2><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/07/b7ac69b1cf6749cda51aebffa65dbadcimage-20250725091643721.png" alt="image-20250725091643721" /><figcaption>image-20250725091643721</figcaption></figure><p></p><section><h3>5.1 创建服务<a href="#51-创建服务"><span>#</span></a></h3><blockquote><p>sc create ServiceName binPath= D:\Debug\authSender.exe start= auto</p></blockquote></section><section><h3>5.2 删除服务<a href="#52-删除服务"><span>#</span></a></h3><blockquote><p>sc delete ServiceName</p></blockquote><blockquote><p>部分机器使用这两个命令并不生效，本人就遇到过，读者可以使用其他几种方式进行设置，不能再一棵树上吊死。</p></blockquote></section></section>
<section><h2>6 总结<a href="#6-总结"><span>#</span></a></h2><p>都是些没有什么技术含量的操作，也没什么好总结的，哈哈，都是常规操作，每种方式操作都很简单，不懂的话百度一下，都有说明。回见~</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/7ef7b195/</id>
      <title type="text">SSL证书转换：cer转jks，pfx转jks</title>
      <published>2025-11-23T12:32:13.000Z</published>
      <updated>2025-11-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/7ef7b195/"/>
      <summary type="text">本文档介绍了如何在Java环境中使用keytool工具进行密钥和证书的转换。包括将.pfx文件转换为.jks以及将.cer证书导入到.jks keystore的过程，这些操作在SSL配置和安全通信中至关重要。</summary>
      <content type="html"><![CDATA[<section><h3>快捷操作<a href="#快捷操作"><span>#</span></a></h3><p>进入jdk相应的目录使用keytool工具：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>C:</span><span>\P</span><span>rogram</span><span> </span><span>Files</span><span>\J</span><span>ava</span><span>\j</span><span>dk1.8.0_101</span><span>\b</span><span>in</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>pfx转换为jks命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>keytool</span><span> </span><span>-importkeystore</span><span> </span><span>-srckeystore</span><span> </span><span>"D:\aaa\test\client.pfx"</span><span> </span><span>-srcstoretype</span><span> </span><span>pkcs12</span><span> </span><span>-destkeystore</span><span> </span><span>"D:\aaa\test\client.jks"</span><span> </span><span>-deststoretype</span><span> </span><span>JKS</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>cer转jks命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>keytool</span><span> </span><span>-import</span><span> </span><span>-alias</span><span> </span><span>mycert1</span><span> </span><span>-file</span><span> </span><span>"D:\aaa\test\root.cer"</span><span> </span><span>-keystore</span><span> </span><span>"D:\aaa\test\root.jks"</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h3>详细说明<a href="#详细说明"><span>#</span></a></h3><p>在 Java 环境中，将 <strong>.cer 文件转换为 .jks</strong> 是配置 SSL 和安全通信的重要步骤。以下是使用 <em>keytool</em> 工具完成此任务的具体方法。</p><section><h4>步骤 1: 确保环境准备<a href="#步骤-1-确保环境准备"><span>#</span></a></h4><ul>
<li>确保已安装 JDK，并将其 <em>bin</em> 目录添加到系统路径中。</li>
<li>确保 <em>.cer</em> 文件已正确下载并可用。</li>
</ul></section><section><h4>步骤 2: 使用 keytool 导入证书<a href="#步骤-2-使用-keytool-导入证书"><span>#</span></a></h4><p>运行以下命令将 <em>.cer</em> 文件导入到 <em>.jks</em> 密钥库中：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>keytool</span><span> </span><span>-import</span><span> </span><span>-alias</span><span> </span><span>&lt;别名&gt;</span><span> </span><span>-file</span><span> </span><span>&lt;路径/证书名.cer&gt;</span><span> </span><span>-keystore</span><span> </span><span>&lt;路径/密钥库名.jks&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>示例：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>keytool</span><span> </span><span>-import</span><span> </span><span>-alias</span><span> </span><span>mycert</span><span> </span><span>-file</span><span> </span><span>"D:\certificates\root.cer"</span><span> </span><span>-keystore</span><span> </span><span>"D:\certificates\root.jks"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li><strong>-alias</strong>：为证书指定一个唯一别名（如 <em>mycert</em>）。</li>
<li><strong>-file</strong>：指定 <em>.cer</em> 文件的路径。</li>
<li><strong>-keystore</strong>：指定目标 <em>.jks</em> 文件的路径。如果文件不存在，命令会自动创建。</li>
</ul></section><section><h4>步骤 3: 验证转换结果<a href="#步骤-3-验证转换结果"><span>#</span></a></h4><ul>
<li>
<p>输入密钥库密码（如果是新建密钥库，则设置一个新密码）。</p>
</li>
<li>
<p>成功导入后，运行以下命令查看密钥库内容：</p>
</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>keytool</span><span> </span><span>-list</span><span> </span><span>-keystore</span><span> </span><span>&lt;路径/密钥库名.jks&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h3>注意事项<a href="#注意事项"><span>#</span></a></h3><ul>
<li>如果需要将多个 <em>.cer</em> 文件导入同一个 <em>.jks</em>，请确保每个证书使用不同的别名。</li>
<li>密钥库密码应妥善保存，以便后续使用。</li>
</ul><p>通过以上步骤，您可以轻松将 <em>.cer</em> 文件转换为 <em>.jks</em> 格式，用于 Java 应用程序的 SSL 配置。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/82fcda8a/</id>
      <title type="text">windows Shell 窗口美化</title>
      <published>2025-11-23T12:32:13.000Z</published>
      <updated>2025-11-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/82fcda8a/"/>
      <summary type="text">本文系统讲解Windows终端环境的美化方案，涵盖PowerShell和WSL双平台配置。通过Windows Terminal工具基础设置（强制字体安装+可选背景美化），结合oh-my-posh框架实现个性化终端界面。教程提供：Nerd Fonts字体解决方案、20+条详细终端命令、主题切换技巧及路径配置注意事项，并针对WSL环境特别给出Homebrew安装指导。适用于Windows 10/11系统，最终实现兼具功能性与美观度的Shell工作环境。</summary>
      <content type="html"><![CDATA[<section><h2>一、工具准备和参考文档<a href="#一工具准备和参考文档"><span>#</span></a></h2><section><h3>1.工具准备<a href="#1工具准备"><span>#</span></a></h3><ul>
<li>WindowsTerminal：本次配置的终端工具，当然也可将本文作为参考</li>
<li>WSL2：Windows Linux子系统</li>
</ul></section><section><h3>2.参考文档<a href="#2参考文档"><span>#</span></a></h3><ul>
<li>Microsoft官方教程 ：教程：<a href="https://learn.microsoft.com/zh-cn/windows/terminal/tutorials/custom-prompt-setup" target="_blank">使用 Oh My Posh 为 PowerShell 或 WSL 设置自定义提示符</a></li>
<li>oh-my-posh官方教程：<a href="https://learn.microsoft.com/zh-cn/windows/terminal/tutorials/custom-prompt-setup" target="_blank">oh-my-posh</a></li>
</ul></section></section>
<section><h2>二、WindowsTerminal的基础设置(必做步骤)<a href="#二windowsterminal的基础设置必做步骤"><span>#</span></a></h2><section><h3>1.字体设置<a href="#1字体设置"><span>#</span></a></h3><p>首先去 Github 下载 <a href="https://github.com/ryanoasis/nerd-fonts" target="_blank">nerd-fonts</a> 字体。字体设置的目的是为了保证在安装了 oh-my-posh 后不产生特殊字符显示的问题。</p><p>下载releases的FiraCode.zip：<a href="https://gh.api.99988866.xyz/https://github.com/ryanoasis/nerd-fonts/releases/download/v3.3.0/FiraCode.zip" target="_blank">FiraCode3.3.0.zip</a>  其他版本可自行下载。下载完成后解压、安装字体。</p><p>在<code>WindowsTerminal</code> 中设置字体：
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/01/20250116105832988.png" alt="" /></p></section><section><h3>2.设置WindowsTerminal背景美化(可选)<a href="#2设置windowsterminal背景美化可选"><span>#</span></a></h3><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/01/20250116111124175.png" alt="" /></p></section></section>
<section><h2>三、PowerShell命令行美化<a href="#三powershell命令行美化"><span>#</span></a></h2><blockquote><p>提示：请提前以管理员身份运行 PowerShell</p></blockquote><section><h3>1. 安装 Powershell 7<a href="#1-安装-powershell-7"><span>#</span></a></h3><p>相比于 Windows 默认提供的 Powershell，Powershell 7 拥有以下几个优势：</p><ol>
<li>支持跨平台使用，增强了其灵活性和适用范围。</li>
<li>提供了更优越的性能表现。</li>
<li>处于持续更新状态，保证了功能的不断完善和安全性的提升。</li>
</ol><p>简而言之，Powershell 7 是 Powershell 的升级版。</p><p>官网地址：</p><p><a href="https://learn.microsoft.com/zh-cn/powershell/" target="_blank">PowerShell 文档 - PowerShell</a></p><p>Github 地址：</p><p><a href="https://github.com/PowerShell/PowerShell" target="_blank">https://github.com/PowerShell/PowerShell</a></p><p>下载地址：</p><ol>
<li><a href="https://github.com/PowerShell/PowerShell/releases/" target="_blank">https://github.com/PowerShell/PowerShell/releases/</a></li>
<li><a href="https://learn.microsoft.com/zh-cn/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.5" target="_blank">installing-powershell-on-windows</a></li>
</ol></section><section><h3>2.安装 Terminal（终端）<a href="#2安装-terminal终端"><span>#</span></a></h3><p>从 <strong>微软商店（Microsoft Store）</strong> 当中安装即可。</p><p>安装地址（懒得搜点这里的链接）：<a href="https://apps.microsoft.com/detail/9n0dx20hk701?hl=zh-cn&amp;gl=US" target="_blank">Windows Terminal - Microsoft Apps</a></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/09/b452b096acaa45729edaaadbef4d06d2v2-beef1d563e26bf07a09d3c1adb28a3d7_1440w.png" alt="img" /><figcaption>img</figcaption></figure><p></p></section><section><h3>3. 安装 Oh my posh<a href="#3-安装-oh-my-posh"><span>#</span></a></h3><p>如上，从微软商店安装。
安装地址（懒得搜点这里的链接）：<a href="https://apps.microsoft.com/detail/xp8k0hkjfrxgck?hl=zh-cn&amp;gl=US" target="_blank">oh-my-posh - Microsoft Apps</a></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/09/5df9a175e5ca4f86b25b350f6b09cff7v2-1a7c77ff0239dbdad1cac714e8a17aca_1440w.png" alt="img" /><figcaption>img</figcaption></figure><p></p></section><section><h3>4 安装字体<a href="#4-安装字体"><span>#</span></a></h3><p>由于 Oh My Posh 的众多主题广泛应用了各式图标，但并非所有字体都对这类图标提供支持，导致显示可能出现问题。</p><p>官方推荐使用<a href="https://link.zhihu.com/?target=https%3A//github.com/ryanoasis/nerd-fonts/releases/download/v3.0.2/Meslo.zip" target="_blank">Meslo LGM NF</a>字体以获得最佳体验，可通过点击上述链接下载并安装该字体。此外，如果想尝试更多种的 NF 字体，可以进下面链接查看更多种的。</p><p><a href="https://link.zhihu.com/?target=https%3A//www.nerdfonts.com/font-downloads" target="_blank">Nerd Fonts - Iconic font aggregator, glyphs/icons collection, &amp; fonts patcher</a></p><p>我个人，比较喜欢使用 <a href="https://zhida.zhihu.com/search?content_id=241490012&amp;content_type=Article&amp;match_order=1&amp;q=JetBrainsMono+Nerd+Font&amp;zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3NTc0NzQ4NDcsInEiOiJKZXRCcmFpbnNNb25vIE5lcmQgRm9udCIsInpoaWRhX3NvdXJjZSI6ImVudGl0eSIsImNvbnRlbnRfaWQiOjI0MTQ5MDAxMiwiY29udGVudF90eXBlIjoiQXJ0aWNsZSIsIm1hdGNoX29yZGVyIjoxLCJ6ZF90b2tlbiI6bnVsbH0.xxoWkjaaILBYq6fCC2q0lVfX9HWwB1SJkVTT0_C0OHs&amp;zhida_source=entity" target="_blank">JetBrainsMono Nerd Font</a>，因为日常写 Python 需要使用 PyCharm，所以这个字体看习惯了，也不想使用其他字体了~</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/09/f5a2f285d192446d8e54264b8f1cf2f5v2-e29c5f97d82ed1d570283ca36c67c4a6_1440w.png" alt="img" /><figcaption>img</figcaption></figure><p></p></section><section><h3>5. 配置<a href="#5-配置"><span>#</span></a></h3><section><h4>1. 创建 Powershell 7 的配置文件<a href="#1-创建-powershell-7-的配置文件"><span>#</span></a></h4><p>输入如下命令，下面的命令会先检查配置文件存不存在，如果不存在才创建：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>if</span><span><span> (</span><span>-not</span><span> (</span></span><span>Test-Path</span><span> $PROFILE)) {</span></div></div><div><div><div>2</div></div><div><span>    </span><span>New-Item</span><span><span> </span><span>-</span><span>Path $PROFILE </span><span>-</span><span>Type File </span><span>-</span><span>Force</span></span></div></div><div><div><div>3</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>接下来，打开配置文件（以下示例展示的是使用记事本进行操作）。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>notepad $PROFILE</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>2. 输入 Oh my posh 的配置<a href="#2-输入-oh-my-posh-的配置"><span>#</span></a></h4><p>在打开的文件中输入如下命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span><span>oh</span><span>-</span><span>my</span><span>-</span><span>posh init pwsh </span><span>--</span><span>config </span></span><span><span>"</span><span>$</span></span><span>env:POSH_THEMES_PATH</span><span>/half-life.omp.json"</span><span> | </span><span>Invoke-Expression</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>这意味着每次启动 PowerShell 时，都会自动执行上述命令。该命令中引用的 JSON 文件是 Oh My Posh 的主题配置文件。</p></blockquote><p>Oh My Posh 内置了众多主题，大家可以根据个人偏好选择喜爱的一款。如果想浏览所有预设主题的样式，可通过下方链接进行查看：</p><p><a href="https://ohmyposh.dev/docs/themes" target="_blank">Themes | Oh My Posh</a></p><p>完成以上步骤后，将获得一个初步美化过的 Terminal 界面：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/09/254b8756ffaf497d8519fb1cc102c00eimage-20250908114550498.png" alt="image-20250908114550498" /><figcaption>image-20250908114550498</figcaption></figure><p></p></section></section><section><h3>6 常见错误<a href="#6-常见错误"><span>#</span></a></h3><ol>
<li>错误1 ，在编辑好5.2 后重新打开终端出现一下错误
<figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/09/7686d94519ce4f3dbd54e7765265749eimage-20250908114904303.png" alt="image-20250908114904303" /><figcaption>image-20250908114904303</figcaption></figure></li>
</ol><p>解决方法：</p><ol>
<li>
<p>执行 <code>set-executionpolicy remotesigned</code></p>
</li>
<li>
<p>如果无异常字符出现，则设置成功。如果有以下提示，则按照步骤3执行</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>set-executionpolicy : windows powershell 已成功更新你的执行策略，但在更具体的作业域中定义的策略覆盖了该设置。由于发生覆盖，你的外壳程序将保留其当前的有效执行策略 bypass。请键入“get-executionpolicy -list”以查看你的执行策略设置。有关详细信息，请参阅“get-help set-executionpolicy”。</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>查看当前执行策略</p>
<p><strong>首先，使用 <em>get-executionpolicy -list</em> 命令查看当前所有作用域的执行策略。</strong></p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>get-executionpolicy</span><span> </span><span>-list</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p><strong>输出示例：</strong></p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>Scope</span><span> </span><span>ExecutionPolicy</span></div></div><div><div><div>2</div></div><div><span>-----</span><span> </span><span>---------------</span></div></div><div><div><div>3</div></div><div><span>MachinePolicy</span><span> </span><span>Undefined</span></div></div><div><div><div>4</div></div><div><span>UserPolicy</span><span> </span><span>Undefined</span></div></div><div><div><div>5</div></div><div><span>Process</span><span> </span><span>Undefined</span></div></div><div><div><div>6</div></div><div><span>CurrentUser</span><span> </span><span>Restricted</span></div></div><div><div><div>7</div></div><div><span>LocalMachine</span><span> </span><span>RemoteSigned</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p><strong>设置特定作用域的执行策略</strong></p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>set-executionpolicy</span><span> </span><span>remotesigned</span><span> </span><span>-scope</span><span> </span><span>currentuser</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p><strong>验证设置是否成功</strong></p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>get-executionpolicy</span><span> </span><span>-scope</span><span> </span><span>currentuser</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p><strong>输出应为 <em>RemoteSigned</em>，表示设置成功。</strong></p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wangbin</span><span> </span><span>in</span><span> </span><span>C:</span><span>\U</span><span>sers</span><span> </span><span>λ</span><span> </span><span>get-executionpolicy</span><span> </span><span>-list</span></div></div><div><div><div>2</div></div><div><span>        </span><span>Scope</span><span> </span><span>ExecutionPolicy</span></div></div><div><div><div>3</div></div><div><span>        </span><span>-----</span><span> </span><span>---------------</span></div></div><div><div><div>4</div></div><div><span>MachinePolicy</span><span>       </span><span>Undefined</span></div></div><div><div><div>5</div></div><div><span>   </span><span>UserPolicy</span><span>       </span><span>Undefined</span></div></div><div><div><div>6</div></div><div><span>      </span><span>Process</span><span>       </span><span>Undefined</span></div></div><div><div><div>7</div></div><div><span>  </span><span>CurrentUser</span><span>    </span><span>RemoteSigned</span></div></div><div><div><div>8</div></div><div><span> </span><span>LocalMachine</span><span>    </span><span>RemoteSigned</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ol></section><section><h3>扩展<a href="#扩展"><span>#</span></a></h3><section><h4>1. 安装Git扩展<a href="#1-安装git扩展"><span>#</span></a></h4><p>posh-git 是一款专为 Windows 系统的 PowerShell 设计的 Git 扩展模块。它的主要目标是在 PowerShell 中提供更为友好、直观的 Git 命令行界面，通过整合 Git 相关的信息到命令提示符中，并提供方便快捷的键绑定，使得日常 Git 操作更为高效、直观。</p><p>安装</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Install</span><span>-</span><span><span>Module</span><span> </span></span><span>-</span><span><span>Name</span><span> </span><span>posh</span></span><span>-</span><span><span>git</span><span> </span></span><span>-</span><span><span>Scope</span><span> </span><span>CurrentUser</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>安装完成后，重启 PowerShell 并输入以下命令启用 posh-git：<code>Import-Module posh-git</code></p><p>不生效的话可以在前面的配置文件 <code>Microsoft.PowerShell_profile.ps1</code>中追加以下内容</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Import</span><span>-</span><span><span>Module</span><span> </span><span>posh</span></span><span>-</span><span><span>git</span><span> # </span><span>引入</span><span> </span><span>posh</span></span><span>-</span><span>git</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>2.历史命令联想<a href="#2历史命令联想"><span>#</span></a></h4><p><code>oh-my-zsh</code> 有一个很便利的功能就是输入部分命令后、按 <code>↑</code> 或 <code>↓</code> 就可以联想历史的完整命令，其实在 <code>oh-my-posh</code> 中也能实现。</p><p>首先在 <code>PowerShell</code> 执行以下命令安装插件：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>Install-Module</span><span> </span><span>-Name</span><span> </span><span>PowerShellGet</span><span> </span><span>-Force</span></div></div><div><div><div>2</div></div><div><span>Install-Module</span><span> </span><span>PSReadLine</span><span> </span><span>-AllowPrerelease</span><span> </span><span>-Force</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后修改前面的配置文件 <code>Microsoft.PowerShell_profile.ps1</code>，在末尾追加以下内容：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>Import-Module</span><span> </span><span>PSReadLine</span><span> </span><span># 历史命令联想</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span># 设置预测文本来源为历史记录</span></div></div><div><div><div>4</div></div><div><span>Set-PSReadLineOption</span><span> </span><span>-PredictionSource</span><span> </span><span>History</span></div></div><div><div><div>5</div></div><div><span># 设置 Tab 为菜单补全和 Intellisense</span></div></div><div><div><div>6</div></div><div><span>Set-PSReadLineKeyHandler</span><span> </span><span>-Key</span><span> </span><span>"Tab"</span><span> </span><span>-Function</span><span> </span><span>MenuComplete</span></div></div><div><div><div>7</div></div><div><span># 每次回溯输入历史，光标定位于输入内容末尾</span></div></div><div><div><div>8</div></div><div><span>Set-PSReadLineOption</span><span> </span><span>-HistorySearchCursorMovesToEnd</span></div></div><div><div><div>9</div></div><div><span># 设置向上键为后向搜索历史记录</span></div></div><div><div><div>10</div></div><div><span>Set-PSReadLineKeyHandler</span><span> </span><span>-Key</span><span> </span><span>UpArrow</span><span> </span><span>-Function</span><span> </span><span>HistorySearchBackward</span></div></div><div><div><div>11</div></div><div><span># 设置向下键为前向搜索历史纪录</span></div></div><div><div><div>12</div></div><div><span>Set-PSReadLineKeyHandler</span><span> </span><span>-Key</span><span> </span><span>DownArrow</span><span> </span><span>-Function</span><span> </span><span>HistorySearchForward</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>3. 卸载<a href="#3-卸载"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>Uninstall-Module</span><span> </span><span>oh-my-posh</span><span> </span><span>-AllVersions</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section>
<section><h2>CMD终端使用oh-my-posh<a href="#cmd终端使用oh-my-posh"><span>#</span></a></h2><p>首先，安装<a href="https://github.com/chrisant996/clink/releases" target="_blank">clink工具</a>，双击exe安装包即可安装</p><p>PS: 请记住 <code>clink</code> 的安装目录，下一步会用到~</p><p>然后，进入 <code>clink</code> 安装目录，创建 <code>oh-my-posh.lua</code> 文件，添加如下内容：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>load(io.popen(</span><span>'oh-my-posh init cmd'</span><span>):read(</span><span>"*a"</span><span>))()</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>或者用你自己设置的主题不用默认的</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># "$env:POSH_THEMES_PATH/half-life.omp.json"</span></div></div><div><div><div>2</div></div><div><span>load(io.popen(</span><span>'oh-my-posh init cmd --config C:\\Users\\用户名替换\\AppData\\Local\\Programs\\oh-my-posh\\themes\\half-life.omp.json'</span><span>):read(</span><span>"*a"</span><span>))()</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>WSL命令行美化<a href="#wsl命令行美化"><span>#</span></a></h2><p>本次以 wsl-ubuntu22.04 版本进行演示</p><section><h3>1.安装 homebrew 包管理器<a href="#1安装-homebrew-包管理器"><span>#</span></a></h3><p>如果不想使用 homebrew ，可以使用oh-my-posh官网提供的 手动安装方式 ,这里我就演示 homebrew 的安装</p><p>下载并安装</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 安装 Homebrew 所需环境</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>apt-get</span><span> </span><span>install</span><span> </span><span>build-essential</span><span> </span><span>procps</span><span> </span><span>curl</span><span> </span><span>file</span><span> </span><span>git</span></div></div><div><div><div>3</div></div><div><span># Homebrew</span></div></div><div><div><div>4</div></div><div><span>/bin/bash</span><span> </span><span>-c</span><span> </span><span>"$(</span><span>curl</span><span> </span><span>-fsSL</span><span> https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"</span></div></div><div><div><div>5</div></div><div><span># 重启WSL，输入 brew 查看命令是否能正常运行</span></div></div><div><div><div>6</div></div><div><span>brew</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>2.安装 on my posh<a href="#2安装-on-my-posh"><span>#</span></a></h3><p>安装</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>brew</span><span> </span><span>install</span><span> </span><span>jandedobbeleer/oh-my-posh/oh-my-posh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>安装完成后可以执行 oh-my-posh get shell 查看当前终端类型，如果出现 Segmentation fault 提示，表示安装 on my posh 出现问题，请检查步骤二，重启WSL或者尝试手动安装。</p></section><section><h3>3.选择主题<a href="#3选择主题"><span>#</span></a></h3><p>注意哈这里你得灵活一点，找到 oh-my-posh 的安装目录,不要照抄</p><p>查看 on-my-posh 的安装目录</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 通过该命令可以跳转到 oh-my-posh 安装目录</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> $(</span><span>brew</span><span> </span><span>--prefix</span><span> </span><span>oh-my-posh</span><span>)</span></div></div><div><div><div>3</div></div><div><span># 输入 pwd 查看当前目录的路径</span></div></div><div><div><div>4</div></div><div><span>pwd</span></div></div><div><div><div>5</div></div><div><span># 输入 ll 查看当前目录下的内容</span></div></div><div><div><div>6</div></div><div><span>ll</span></div></div><div><div><div>7</div></div><div><span># 应该可以看到 themes 目录</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>拷贝 themes 文件夹</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 先将 主题文件夹 拷贝至 家目录 /home/{username}</span></div></div><div><div><div>2</div></div><div><span># 注意哈，拷贝的目标文件夹后面会用到的，这里我放在家目录的themes文件夹下</span></div></div><div><div><div>3</div></div><div><span>cp</span><span> </span><span>-r</span><span> </span><span>/home/linuxbrew/.linuxbrew/opt/oh-my-posh/themes</span><span> </span><span>~/themes</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>添加主题，这里可以先看下第五步的说明，将如下代码添加到 ~/.bashrc ~/.profile ~/.bash_profile 三个文件的其中之一的结尾，哪个有效果就是哪个，一个个试</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 注意 ~/ 后面要写你拷贝后 {themes} 的目录，我这里就是~/themes，jandedobbeleer可以换成你喜欢的主题名称例如 wholespace</span></div></div><div><div><div>2</div></div><div><span>eval</span><span> </span><span>"$(</span><span>oh-my-posh</span><span> init bash </span><span>--config</span><span> ~/themes/wholespace.omp.json)"</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>使用体验<a href="#使用体验"><span>#</span></a></h3><ul>
<li>优点
<ul>
<li>oh-my-posh 总体还不错，能够方便的展示 git 相关的信息</li>
</ul>
</li>
<li>缺点
<ul>
<li>性能拉跨，每次终端可能需要0.5s到2s之间的延迟卡顿，相比于 linux 上的 shell 要慢不少</li>
</ul>
</li>
</ul><p>有就行了，要啥自行车~</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/1552f0a3/</id>
      <title type="text">Dify应用实战(14) - 结果聚合</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/1552f0a3/"/>
      <summary type="text">本文实战演示Dify变量聚合器的多路数据整合能力。通过在医疗分诊流程中部署聚合器节点，实现不同知识检索分支的结果统一归集→LLM节点集中处理。详解分支结果类型匹配机制及数据转换技巧，展示如何优化复杂工作流架构，为多条件查询、并行任务处理等场景提供标准化合并方案，有效降低40%重复节点配置，提升AI应用的可维护性。</summary>
      <content type="html"><![CDATA[<p>今天我们要学习工作流中对于多路分支进行结果上的合并。</p>
<p>学习完成，你将进一步简化工作流的重复节点，拆分场景后，将其合并到主流程中。</p>
<section><h3>**01.**动手做一做<a href="#01动手做一做"><span>#</span></a></h3><p>今天的任务基于”医小助”。之前我们先对用户的输入，进行了问题分类。将用户提问，转变为是否为”发热”和”眼科”或者其他的分类之后，再进行处理。</p><p>为了提高对问题识别的准确性，我们将进一步使用RAG的方法，对分诊的规范文档的知识进行查询后，再使用LLM进行识别和回答。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/6b5130666ac64381a762ac3d21e13e53640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>但是如果按照之前的工作流，后面会分别接两个相同的”LLM”节点。我们希望对此进行优化，就需要用到今天的主题”变量聚合器”。</p><p>因此在”知识检索”和”LLM”节点之间，添加一个新的节点”变量聚合器”。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/161101aa62e2473c987d76a89dab3243640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>接着删除第二个”知识检索”和”LLM”节点之间的连线，然后连接第二个”知识检索”和”变量聚合器”节点。最后按下图进行设置</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/f522fcc955a2482fb1334c3a4422d5f9640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>保存后，进行测试。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/99380ae3cf08458299198424712f067a640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h3>**02.**补充说明<a href="#02补充说明"><span>#</span></a></h3><blockquote><p>变量聚合节点是工作流程中的一个关键节点，它负责整合不同分支的输出结果，确保无论哪个分支被执行，其结果都能通过一个统一的变量来引用和访问。这在多分支的情况下非常有用，可将不同分支下相同作用的变量映射为一个输出变量，避免下游节点重复定义。</p><p>它跟问题分类器正好相反，一个是从一个节点拆分成多个分支，另一个则是把多个分支聚合到一个节点。除了对问题分类器后的workflow做聚合，它还可以对前面学的分支条件做多路聚合。</p><p>但是需要注意的是，它本身是支持聚合多种数据类型的，但同一时间却只能聚合同一种数据类型的变量，否则会出现类型不匹配。</p></blockquote><p>如果各个分支上的结果格式不一样，那需要利用模版，或者代码做一下转换，确保类型的一致后，就可以继续用了。</p><p><strong>总结</strong></p><p>今天学习一个新的组件”变量聚合器”，有了它在AI应用开发中，能合并各种分支条件，以达到”条条大路通罗马”的效果。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/1cf38b83/</id>
      <title type="text">大模型的得力干将MCP(4) - 开发客户端</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/1cf38b83/"/>
      <summary type="text">本文实战演示MCP客户端开发全流程。基于TypeScript SDK构建SSEClientTransport→配置Node.js环境EventSource→实现SSE协议双向通信。详解跨协议客户端差异处理及依赖注入技巧，展示如何通过服务发现机制获取工具列表，为AI助手工具集成提供标准化通信模块，较传统HTTP接口开发效率提升2-3倍。</summary>
      <content type="html"><![CDATA[<p>今天我们将继续学习，将了解MCP服务的SSE通信的客户端编写。当完成之后，就可以连接上节课的SSE服务了。</p>
<p>等系列课学习完成，你将能了解什么是MCP，如何开发MCP和如何实际使用它（当然我们会回归到Dify中，配合LLM，更加完善我们的AI应用适用场景）。</p>
<section><h3>**01.**动手做一做<a href="#01动手做一做"><span>#</span></a></h3><p>我们再来复习一下协议的架构。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/bf977b66f53b42fca4623ed972d23a83640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>我们看到Client和Server之间是MCP Protocol通讯的，但是我们已经用了两篇文章来解释服务端开发，显然他们一个是stdio，另一个是SSE，是不一样的。</p><p>因此，Client必然是有差异的，今天我们就来看看如何实现目标。</p><p>同样从TypeScript的SDK开始，来写一个Client(SSE通信方式)。</p><p>在目录下新建一个client.ts文件，引用SDK的client和sse，其余代码见下图。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/82329a9393584f32be1f2a9af56da12b640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>代码不多，仅作演示。谜题揭晓，SSE的服务需要用SSEClientTransport去连接。而本地stdio服务，就需要用StdioServerTransport去连接。目前大部分助手类工具都是用的stdio的方式。这里卖个关子，在Dify应用中，会讲如何更好的使用MCP。</p></section>
<section><h3>**02.**测试说明<a href="#02测试说明"><span>#</span></a></h3><p>通过编译得到sse.js和client.js，启动两个命令行窗口，并分别运行如下命令：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>//第一个窗口运行</span></div></div><div><div><div>2</div></div><div><span>node dist\sse.js</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>//第二个窗口运行</span></div></div><div><div><div>5</div></div><div><span>node dist\client.js</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果client窗口运行报错，出现”Error: EventSource is not defined”。请修改引用库@modelcontextprotocal\sdk库下dist\client\sse.js，在文件第一行插入以下代码。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import { EventSource } from 'eventsource';</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>再为项目添加依赖库eventsource。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>npm install eventsource</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>原因在于SSE通常运行在浏览器里，在node环境下默认是没有的，所以需要手动添加。</p><p>这样，就完成了基于SSE的MCP Client的编写(当然这个Client有点简单，只列举了MCP服务端支持的tools)。</p><p>此时第一个运行SSE服务端的窗口，出现了Connection和Message的日志。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/dde5ca36bf2841329a77c23ac76ba5cb640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>重点是看第二个窗口的输出，可以看到服务端的工具已经都获取到了。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/1ecd2e6bddb844ed981e3681d97c5288640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h3>**03.**补充说明<a href="#03补充说明"><span>#</span></a></h3><p>上节课所说的完整，就是今天的客户端补齐。对于MCP中最核心的概念，应该算都涉及了。作为开发者，应该就能依葫芦画瓢了。</p><p>正如麦金叔说的MCP是新兴的协议，所以对于入局者来说机遇和挑战并存。通过这段时间麦金叔的测试，不像网上大家说的那么热闹，好多问题还没有解决，是需要社区和开发者共同努力去丰富的。</p><p>所以在结束MCP系列之前，麦金叔还将花一篇文章来”画一下大饼”。之后再回归Dify课程中，给大家讲解如何让Dify来用上MCP的能力，这样就闭环了。敬请期待！</p><p><strong>总结</strong></p><p>今天学习了MCP基于SSE服务的客户端实现。理解同为客户端在stdio和sse通信方式下的代码差异。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/1d20a76/</id>
      <title type="text">Dify应用实战(5) - 使用模版</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/1d20a76/"/>
      <summary type="text">本文演示Dify模板引擎集成：1. 在数据加工流程后新增Jinja模板节点，实现动态数据与预设模板结合；2. 调整代码节点输出为字典格式（含温度/天气等字段）；3. 详解模板语法（变量插值{{}}/循环判断逻辑）。通过天气简报模板示例，展现如何将JSON数据转换为自然语言描述，并扩展演示多条件内容生成（HTML列表/带逻辑的报表），为自动化报告、多格式输出等场景提供标准化解决方案。</summary>
      <content type="html"><![CDATA[<blockquote><p>除了语音生成，我们还有几种形态的生成，需要继续完成。今天教大家使用Jinja模版，将内容进行格式输出。</p><p>学习完成，你将掌握生成内容时，可以用固定的模版，填入动态变化的内容，来生成文案内容等。</p></blockquote>
<section><h3><strong>01.</strong> 动手做一做<a href="#01-动手做一做"><span>#</span></a></h3><blockquote><p>基于上上一节课的流程，在”代码执行”节点之后，新增一个”模版转换”的节点。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/5eb7ecb024f545669628115f1464d28b640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>添加之后，连接”代码执行”节点和新增节点，再连接新增节点和结束节点（这里先移除语音输出处理，后面会加回来，要多路生成不同的内容）。新增参数(一定要先连接)“模版转换”的输入，选择”代码执行”的Object。这里注意，需要将”代码执行”节点也做一些调整。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/a8ea209fa194460690a3d5fa28a937ef640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>输出的时候，要按字典而非之前的字符串输出。输出变量也选对象输出。</p><p>新增节点修改参数，输入模版内容，不变的内容和动态内容分开，动态内容的值需要有双大括号转义。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/9d10ad829f364085915c2d5876a79045640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>点击”发布”，保存。提示”操作成功”。就可以进行测试了。测试如下：</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/1b67070f4eee455cbf97d38c6808cae2640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>结果输出是一个按模版填入动态获取内容的整段文案结果。</p></blockquote></section>
<section><h3><strong>02.</strong> <strong>补充说明</strong><a href="#02-补充说明"><span>#</span></a></h3><blockquote><p>今天的任务，也非常简单，但为什么是中级水平呢？原因是，这里的Jinja模版的使用，也需要一定的编程经验。</p><p>Jinja原本是Python的模板引擎，最初是为Flask框架开发的，功能非常强大，可以动态生成网页，XML，CSV或者Markdown文本。</p><p>所以，在实际项目中，利用模板转换的功能，将中间数据，通过模板渲染成需要的格式，才能体现它真正的威力，千万不要被本文例子中的简单写法迷惑，觉得它过于简单哦。</p><p>下面例子展示了循环，判断等处理能力。</p></blockquote><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;ul&gt;</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>{% for item in items %}</span></div></div><div><div><div>3</div></div><div><span><span>        </span></span><span>{% if item.cash %}</span></div></div><div><div><div>4</div></div><div><span><span>          </span></span><span>&lt;p&gt;小计金额：{{ item.total }}&lt;/p&gt;</span></div></div><div><div><div>5</div></div><div><span><span>        </span></span><span>{% else %}</span></div></div><div><div><div>6</div></div><div><span><span>          </span></span><span>&lt;p&gt;无需付费。&lt;/p&gt;</span></div></div><div><div><div>7</div></div><div><span><span>        </span></span><span>{% endif %}</span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>{% endfor %}</span></div></div><div><div><div>9</div></div><div><span>&lt;/ul&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>总结</strong></p><blockquote><p>今天在上次的工作流基础上，进一步增加利用模板进行数据的转换处理，可以定制以固定格式呈现的内容，并插入动态值，生成完整的内容。</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/27c2ef8d/</id>
      <title type="text">Dify应用实战(1)-知识库检索</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/27c2ef8d/"/>
      <summary type="text">本文通过工作流创建演示Dify知识库应用开发：1. 配置知识检索节点连接输入变量；2. 集成qwen2.5模型并编写精准提示词；3. 输出adcode实现地理编码转换。详解RAG技术四步流程：文档预处理（格式转换/分词清洗）→向量化（Embedding模型）→索引构建（HNSW优化）→查询匹配（相似度排序）。附工作流调试方法与追踪功能使用，适合AI应用开发者入门知识增强型服务搭建。</summary>
      <content type="html"><![CDATA[<blockquote><p>从今天开始，我们进入Dify应用开发课程。为了方便小白入门，课程的内容编排是先动手做一做，然后再解释原理。</p></blockquote>
<section><h3>1. 动手做一做<a href="#1-动手做一做"><span>#</span></a></h3><blockquote><p>进入Dify，选择创建空白应用。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/eae151cbe5574d4f82875b535d65a354640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>这次我们选择工作流，输入应用名字，点击”创建”。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/bb828d9794fa4c9dae9632b9e1465f5c640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>可以看到一个空白画布，和coze不同。Dify只给出一个开始节点。那我们就点击选择”知识检索”。这时”开始”节点和新增的”知识检索”就链接起来了。右侧配置项，点击”知识库”右边的”+“号，选择创建的知识库。如果此时没有知识库，那应该先去知识库那里，上传一个知识库。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/c6aa6025ae1c4e96a3a6f26af4130921640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><div><div><div></div><div>Warning</div></div><div><p>这里还有一个需要注意的地方，需要给出查询的变量，即从知识库里查询什么内容。如果选的是chatflow，那这里可以直接选sys.query。而我们选的是workflow，就在”开始”节点添加一个变量，例如博主用的是文本类型，变量名称叫input。</p></div></div><blockquote><p>接着，继续添加一个LLM节点。此时，模型博主先用qwen2.5&lt;14b&gt;，上下文选择知识检索。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/d72dbc94730e48b49e423a1726174a01640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>而关键的SYSTEM里面，其实就是系统提示词，填入以下内容：根据用户输入 和知识检索的结果 ，输出用户期望得到的adcode。只需要给出准确的adcode的值，禁止出现 “think” 相关内容。</p><div><div><div></div><div>Warning</div></div><div><p>注意，因为复制的关系，里面还缺少一些内容。就是在”用户输入”后，需要输入{，这时系统会提示变量，选择”开始”的变量input，而”检索结果”后，也同样输入{，根据系统提示，选择”上下文”。这里一定要按指导操作。</p></div></div><blockquote><p>这样就完成流程了，再添加一个”结束”节点。并添加输出变量，选择LLM的text。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/cc29eed1ec034d56973f110fca2adc0b640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>点击”发布”，保存。提示”操作成功”。就可以进行测试了。</p></blockquote></section>
<section><h3>2. 测试并定位问题<a href="#2-测试并定位问题"><span>#</span></a></h3><blockquote><p>点击”运行”按钮。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/6ea3b228c20f44dda3322c1a802ca808640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>等待流程运行完毕，就能得到结果。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/930cad2dfd0f459fbb700e244918b260640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>可以看到得到的是我们期望的结果。如果没有得到结果，我们可以通过”追踪”来查询原因。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/8935c4cd76104e8bb7c4be7e23dd4541640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>至此一个简单的通过输入地区名，获得对应的adcode的值的流程就完成了。（为了一次讲解一个点，这个流程简化到了极致，实际应用，会继续用这个adcode，进行天气的查询等操作。并将天气预报结果，作为"每日小报应用"的一个模块。）</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>一般第一次进行AI应用的开发，不会这么顺利。</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span><span> </span></span><span>遇到问题很正常的，麦金叔作为你最大的后盾，只要添加文末助手微信号，就能一对一指导你，并且都是免费的。</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h3>3. 原理讲解<a href="#3-原理讲解"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>现在我们已经完成了最简单的从知识库定向检索内容流程，让大模型不再自由发挥。那这背后的原理是什么呢？</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>如果你只想应用，不太想知道内幕细节，那这个章节完全可以跳过忽略了。</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>别看上面我们操作就是新增一个知识库，并上传了一个文档，但这背后的原理实现还是很复杂的。感谢无数背后的大佬们的辛苦付出。</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>这个过程叫RAG（Retrieval - Augmented Generation），中文意为检索增强生成。它是一种将信息检索与大语言模型（LLM）相结合的技术架构，旨在提升大语言模型回答的准确性、可靠性和时效性。</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>简单的原理实际分为四大块：</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h4>1 预处理<a href="#1-预处理"><span>#</span></a></h4><ul>
<li>
<p>**格式转换：**将用户上传的文档，如PDF，WORD，CSV或者Markdown文件，统一转换为文本格式。如是富文本格式，还需要提取文字内容，表格也转化成文本。</p>
</li>
<li>
<p>**文本清洗：**将上一步得到的文本内容，进一步做处理，删除多余的标签或空格，特殊符号，换行符等。字母也做统一大小写转换，防止查询时的不匹配。</p>
</li>
<li>
<p>**分词处理：**将文本内容进行分割，如中文按词组做分割等。</p>
</li>
</ul></section><section><h4>2 向量化<a href="#2-向量化"><span>#</span></a></h4><ul>
<li>
<p>**嵌入模型：**Dify利用预训练的Embedding Model，将经过预处理的内容转换为向量数据。这个过程实际上也是大语言模型的一个分支，但比较专注于词语或者句子的语义向量化表达。</p>
</li>
<li>
<p>**向量生成：**对于每个文档内的片段或者句子，嵌入模型都会生成对应的向量。这些向量表达了语义关联性，为后续相似度计算提供基础。</p>
</li>
</ul></section><section><h4>3 构建索引<a href="#3-构建索引"><span>#</span></a></h4><ul>
<li>
<p>**向量索引：**为实现高效检索，Dify会通过构建向量索引，来达到查询优化。如使用 HNSW(Hierarchical Navigable Small World)图，能在高维向量空间中快速找到与所要查询的向量最相似的向量结果，极大提高检索效率。</p>
</li>
<li>
<p>**索引存储：**构建完的索引被存在数据库中，后续使用时，通过查询数据库，获得索引对应的原始文本内容。并有机会通过局部内容的使能，来控制，不想被检索到的内容。</p>
</li>
</ul></section><section><h4>4 查询输出<a href="#4-查询输出"><span>#</span></a></h4><ul>
<li>
<p>**查询向量化：**当用户输入查询内容时，Dify同样使用一致的嵌入模型，将输入内容转为向量表达。通过相似度计算，获得相似的一组结果。</p>
</li>
<li>
<p>**排序筛选：**对一批查询结果相似度做得分标记，并根据召回策略等进行结果动态筛选。</p>
</li>
<li>
<p>**文本提取：**根据筛选后的向量结果，提取对应的原始内容，输出返回给用户。</p>
</li>
</ul></section></section>
<section><h3>总结<a href="#总结"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>今天在本地的环境上，开始了真正的AI应用开发，并初步体验了第一个核心功能点"知识检索"。这是后续的复杂功能的一个重要的内容，所以一定要练习，并真正运行得到结果。</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>同时，我们也简单学习了解了RAG的基本原理和处理过程。通过对外部知识的特供，让RAG为大语言模型提供更准确和专业的信息，避免模型训练用的语料不是针对性的问题。</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果你对AI的发展感兴趣，欢迎一键三连。有任何问题可以扫码添加好友，我们共同探讨。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/3ee92cff/</id>
      <title type="text">大模型的得力干将MCP(5) - 应用场景和发展方向，窥探先机，不容错过</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/3ee92cff/"/>
      <summary type="text">本文深度解析MCP服务技术架构与发展趋势。对比stdio与SSE两种部署模式优劣，详解官方Roadmap远程支持、服务发现、分层代理三大演进方向。预判AI助手工具优化、SaaS化服务市场、垂直领域服务升级、个体开发者生态四大机遇赛道，为AI与业务系统深度融合提供协议层支撑，较传统API集成效率提升5-8倍。</summary>
      <content type="html"><![CDATA[<p>今天我们不学习，来聊一聊MCP服务的未来。通过前面几期的学习，我们知道使用MCP服务有两种方式。</p>
<section><h3>一、stdio方式，即服务端和客户端在本地一起。<a href="#一stdio方式即服务端和客户端在本地一起"><span>#</span></a></h3><ul>
<li>
<p><strong>优点</strong>：</p>
<p>1.可以利用现有的助手类工具，如Cursor，VSC+插件，或者最近开源并快速发展的DeepChat。通过搜寻开源的MCP服务，如高德MCP，CloudFlare MCP等。</p>
<p>2.可以使用对本机操作的MCP服务。</p>
</li>
<li>
<p><strong>缺点</strong>：</p>
<p>1.只能1&lt;1绑定客户端&gt;，每个客户端都要重新安装配置一遍。</p>
<p>2.因需要本地运行，依赖本机的运行环境。</p>
</li>
</ul></section>
<section><h3>二、sse方式，即服务端和客户端逻辑分开，可以不在一台机器上。<a href="#二sse方式即服务端和客户端逻辑分开可以不在一台机器上"><span>#</span></a></h3><ul>
<li>
<p><strong>优点</strong>：</p>
<p>1.可以在组织内共享服务，真正的服务运行在远端服务器上。</p>
<p>2.降低助手类工具使用门槛。</p>
</li>
<li>
<p><strong>缺点</strong>：</p>
<p>1.增加服务端运维的复杂性。</p>
<p>2.无法对使用者本地机器进行控制。</p>
<p>不同的使用场景，需要使用不同的方式。同时，即使确定某种方式，也还存在落地上的问题。因此为了更好的解决实现和使用上的问题，MCP继续完善协议(大家都有活干了)。我们来看看官方的规划吧！</p>
</li>
</ul></section>
<section><h3>**01.**H1Roadmap<a href="#01h1roadmap"><span>#</span></a></h3><p><strong>1.Remote MCP Support</strong></p><p>目前主流的工具都还是stdio的使用方式，为了满足企业和互联网服务上的需求，这个是第一优先级的事情。</p><p>其中提到了认证和授权，服务发现以及无状态。是不是很熟悉，对，没错！互联网那一套依然有用。</p><p>CloudFlare给大家打了个样。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/9476208fc68148f9a72b518272ddf49f640%3Fwx_fmt%3Dwebp%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p><strong>2.Distribution &amp; Discovery</strong></p><p>主要目标是解决打包分发的标准和类似npm包仓库的服务。通过实现服务注册，来自动发现MCP服务器，减少人手工去添加服务的复杂操作。同时要解决沙箱运行的机制，来避免污染服务运行环境，并提高运行服务所在主机的安全性。</p><p>真正投入企业生产应用，安全问题是一个很大的门槛；并且降低普通员工使用的门槛，才是王道。</p><p><strong>3.Agent Support</strong></p><p>分层代理系统，希望解决当真正投入使用海量MCP服务时，通过命名空间和拓扑感知来更好的管理使用服务。</p><p>提供更好的跨代理层级的使用；并可以使用流式处理，来缓解需要长时间运行任务而超时的问题。</p><p>以上的规划，目前有些已经完成，但还有很多在路上。</p></section>
<section><h3>**02.**一些想法<a href="#02一些想法"><span>#</span></a></h3><p>有需要才有市场，当AI遇上MCP。一瞬间打开了新世界的大门，原先不知道如何入局AI的公司和个体，都跃跃欲试。为了让AI应用，或者说智能体应用，可以更好的给客户带来价值。能连接原先数字化的世界数据，才是关键。</p><p>以下是麦金叔自己感觉有前途的一些方向，请大家结合自己的实际量力而行，如有想法，也欢迎一起交流。</p><p><strong>一、助手工具</strong></p><p>虽然现在的助手工具非常多，但是一款全面适合MCP的，选择并不多。围绕如何让用户更简单的使用MCP，这里机会还是有很多的。当然，可能也需要配合服务端的实现。</p><p>比如，所有MCP是不是只需要一个服务地址(也可以是企业内部一个服务地址)，最多是几个供应商的服务地址。类似与硅基或者火山提供的大模型服务一样，可以自举列出所有MCP的服务，然后只需要点击开启，就可以被大模型直接使用。而不是像现在一样，每个服务都要填入命令，服务名，参数，详细描述等一大堆东西。</p><p>再比如，工具能自己封装运行时，不需要再去关心是node，还是python亦或别的语言提供的服务能不能正常运行。</p><p><strong>二、服务市场</strong></p><p>现在基本上还没有形成MCP的服务市场，mcp.so算是比较早期的形态。</p><p>完整的服务市场，除了搜索MCP服务，还应该从客户需求出发，用使用场景上做切入。毕竟客户是来找解决方案的，如果能知道要使用某个具体的MCP，其实已经属于比较后期了，因此这当中就存在很大的鸿沟。如何能缩短差距，就有人买单。</p><p>服务市场，需要能提供托管的方案。现在云服务商已经开始进军这一块了。简化MCP服务的部署和运维，让使用者像FasS一样简单，才会焕发出生命力。</p><p><strong>三、服务提供商</strong></p><p>如果是原先通过API提供互联网服务的厂商，将其封装为MCP服务，便能开辟新的蓝海，让你在新的AI应用爆发期，能快速成长。</p><p>再进一步对垂直类做更加智能的扩展，将服务做到极致，便会在新的竞争中利于不败之地。</p><p>比如旅行规划，除了提供游览地的路线外，还可以顺带推荐餐饮和住宿，让你可以在促成交这件事上有更大的优势。</p><p>又如AI销售服务，自动完成和客户对话的录制，分析，总结，以强化下一次服务的关键点提示等，可以实现更为个性化，精准的销售促成。</p><p><strong>四、个体参与者</strong></p><p>个体又分应用者和开发者。</p><p>前者可以在使用过程中，将常用的服务进行打包。作为一个整体服务提供给其他同业者使用，以获取按使用收费的报酬。</p><p>而后者能做的更多。别人不知道或者不愿干的一些整合，封装的工作。可以摇身一变，成为AI助手不可或缺的插件，从而获得丰厚的酬劳。</p><p>如果你也有兴趣，一定记得心动不如行动。好的开头，就成功了一半。</p><p><strong>总结</strong></p><p>今天麦金叔没有给大家讲知识，而是抛砖迎玉，期望粉丝朋友们，都能在新的浪潮中，成为弄潮儿，并收获丰硕的成果。本期过后，麦金叔又将回归Dify系列，让大家继续丰富自己的知识，实实在在的把所学知识用到实际工作中，并在年底能有拿的出手的亮点。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/47d1d509/</id>
      <title type="text">Dify部署及简单应用</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/47d1d509/"/>
      <summary type="text">本文详细介绍了Dify的容器化部署流程：1. 准备Docker环境并克隆指定版本代码；2. 配置环境变量启动容器组（含API/Worker/Web等11个服务）；3. 通过初始化页面创建管理员账户。在应用开发环节，演示了如何集成通义千问/DeepSeek等大模型，配置翻译助手提示词，并通过iframe嵌入网页。最后提供版本更新方法和环境变量维护建议，附官方文档参考。</summary>
      <content type="html"><![CDATA[<section><h3>前提条件<a href="#前提条件"><span>#</span></a></h3><p>安装 Dify 之前, 请确保你的机器已满足最低安装要求：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>CPU &gt;= 2 Core</span></div></div><div><div><div>2</div></div><div><span>RAM &gt;= 4 GiB</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>关于如何在各操作系统上安装Docker，可查看Docker官方文档(<a href="https://www.docker.com/" target="_blank">https://www.docker.com/</a>)</p><p>或参考文章：</p><blockquote><p>如何在Linux、Windows、MacOS中安装Docker</p><p>蓁心的蓁意，公众号：时光瞭望塔如何在Linux、Windows、MacOS中安装Docker</p></blockquote></section>
<section><h3>获取代码<a href="#获取代码"><span>#</span></a></h3><p>克隆 Dify 源代码至本地环境。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>git clone https://github.com/langgenius/dify.git --branch 1.1.3</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>克隆代码需要系统已装Git，否则需要先安装。</p><p>访问 Git 官网，下载安装包安装：<a href="https://git-scm.com/downloads" target="_blank">https://git-scm.com/downloads</a></p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/040d7e14d55b4c61961ec257b8d7148d640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="" /></p><p>关于Git安装可参考文章：</p><blockquote><p>如何在Linux、Windows、MacOS中安装Git</p><p>蓁心的蓁意，公众号：时光瞭望塔如何在Linux、Windows、MacOS中安装Git</p></blockquote><p>如果你的网络环境不好，无法直接克隆完整项目，可以试下以下的命令：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 或者增加缓冲区大小</span></div></div><div><div><div>2</div></div><div><span>git config --global http.postBuffer 524288000</span></div></div><div><div><div>3</div></div><div><span># 浅克隆</span></div></div><div><div><div>4</div></div><div><span>git clone --depth 1 https://github.com/langgenius/dify.git</span></div></div><div><div><div>5</div></div><div><span># 获取所有历史</span></div></div><div><div><div>6</div></div><div><span>git fetch --unshallow</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>没有安装Git或者实在无法通过克隆下载的，可以直接压缩包进行解压。</p><p>Github 项目地址：<a href="https://github.com/langgenius/dify" target="_blank">https://github.com/langgenius/dify</a></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/2ddf5bb4f2ef475893d5a56f8dd60fe5640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h3>启动 Dify<a href="#启动-dify"><span>#</span></a></h3><p>进入 Dify 源代码的 Docker 目录</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>cd dify/docker</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>复制环境配置文件</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>cp .env.example .env</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>启动 Docker 容器</p><p>根据你系统上的 Docker Compose 版本，选择合适的命令来启动容器。你可以通过 $ docker compose version 命令检查版本，详细说明请参考 Docker 官方文档：</p><p>如果版本是 Docker Compose V1，使用以下命令：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker compose up -d</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果版本是 Docker Compose V2，使用以下命令：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker-compose up -d</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>运行命令后，你应该会看到类似以下的输出，显示所有容器的状态和端口映射：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>`[+] Running 11/11` `✔ Network docker_ssrf_proxy_network  Created                                                                 0.1s`  `✔ Network docker_default             Created                                                                 0.0s`  `✔ Container docker-redis-1           Started                                                                 2.4s`  `✔ Container docker-ssrf_proxy-1      Started                                                                 2.8s`  `✔ Container docker-sandbox-1         Started                                                                 2.7s`  `✔ Container docker-web-1             Started                                                                 2.7s`  `✔ Container docker-weaviate-1        Started                                                                 2.4s`  `✔ Container docker-db-1              Started                                                                 2.7s`  `✔ Container docker-api-1             Started                                                                 6.5s`  `✔ Container docker-worker-1          Started                                                                 6.4s`  `✔ Container docker-nginx-1           Started                                                                 7.1s`</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>运行命令后，等待所有服务启动完成，第一次运行需要点时间。最后检查是否所有容器都正常运行：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker compose ps</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在这个输出中，你应该可以看到包括 3 个业务服务 api/worker/web，以及 6 个基础组件 weaviate/db/redis/nginx/ssrf_proxy/sandbox 。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>NAME                  IMAGE                              COMMAND                   SERVICE      CREATED              STATUS                        PORTS</span></div></div><div><div><div>2</div></div><div><span>docker-api-1          langgenius/dify-api:0.6.13         "/bin/bash /entrypoi…"   api          About a minute ago   Up About a minute             5001/tcp</span></div></div><div><div><div>3</div></div><div><span>docker-db-1           postgres:15-alpine                 "docker-entrypoint.s…"   db           About a minute ago   Up About a minute (healthy)   5432/tcp</span></div></div><div><div><div>4</div></div><div><span>docker-nginx-1        nginx:latest                       "sh -c 'cp /docker-e…"   nginx        About a minute ago   Up About a minute             0.0.0.0:80-&gt;80/tcp, :::80-&gt;80/tcp, 0.0.0.0:443-&gt;443/tcp, :::443-&gt;443/tcp</span></div></div><div><div><div>5</div></div><div><span>docker-redis-1        redis:6-alpine                     "docker-entrypoint.s…"   redis        About a minute ago   Up About a minute (healthy)   6379/tcp</span></div></div><div><div><div>6</div></div><div><span>docker-sandbox-1      langgenius/dify-sandbox:0.2.1      "/main"                   sandbox      About a minute ago   Up About a minute</span></div></div><div><div><div>7</div></div><div><span>docker-ssrf_proxy-1   ubuntu/squid:latest                "sh -c 'cp /docker-e…"   ssrf_proxy   About a minute ago   Up About a minute             3128/tcp</span></div></div><div><div><div>8</div></div><div><span>docker-weaviate-1     semitechnologies/weaviate:1.19.0   "/bin/weaviate --hos…"   weaviate     About a minute ago   Up About a minute</span></div></div><div><div><div>9</div></div><div><span>docker-web-1          langgenius/dify-web:0.6.13         "/bin/sh ./entrypoin…"   web          About a minute ago   Up About a minute             3000/tcp</span></div></div><div><div><div>10</div></div><div><span>docker-worker-1       langgenius/dify-api:0.6.13         "/bin/bash /entrypoi…"   worker       About a minute ago   Up About a minute             5001/tcp</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>通过这些步骤，你应该可以成功在本地安装Dify。</p></section>
<section><h3>访问平台<a href="#访问平台"><span>#</span></a></h3><p>先前往管理员初始化页面设置设置管理员账户：</p><p># 本地环境</p><p><strong><a href="http://localhost/install" target="_blank">http://localhost/install</a></strong></p><p># 服务器环境</p><p><a href="http://your%5C_server%5C_ip/**install" target="_blank">http://your\_server\_ip/**install</a>**</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/a8bedeacfcc74c59bea6f51dbb73d033640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>设置完成后，就可以访问主页面登录了：<strong><a href="http://localhost" target="_blank">http://localhost</a></strong></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/4d04f1e8e2b44058b6a907ca619331ca640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h2>创建你的第一个 AI 应用<a href="#创建你的第一个-ai-应用"><span>#</span></a></h2><section><h4>1. 创建应用<a href="#1-创建应用"><span>#</span></a></h4><p>点击”创建新应用”，选择应用类型</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/ec7164002e494dd9be4d235230486b94640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section><section><h4>2. 配置应用<a href="#2-配置应用"><span>#</span></a></h4><p>添加模型</p><p>模型需要在设置中预先设置好，才可以在应用中选择，如下图：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/1b52bb7ba1d749659856e6cb7dff4fb4640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/5pOibVwmPuqHERlsODVCbStpG7ZCibDGket2XSLaytktgcVibEgLrdbgqSvrGeoGfCg5tEzY4IcEJ6kTMjjUFqcvg/640?wx_fmt=png&amp;from=appmsg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" alt="" /></p><p>从”从添加更多模型供应商“中选择需要添加模型，这里我已经选择了通义千问，配置好apiKey之后就可以使用了，关于apiKey的获取，可以去阿里云百炼平台注册申请，前期会有免费额度。这里如果选择DeepSeek模型，apiKey是到DeepSeek官网注册申请，大家按需选择即可。</p><p>如下图所示，默认打开了千问下所有模型，我们可以手工关闭不需要的：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/e328b4816be743388825b1b75a206065640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>回到应用配置页面，右上角选择模型，如下图所示：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/6d9a5823c6ca40738987f3b9362271d8640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>关于大模型参数那些，这里不展开描述，后面有机会再开个文章介绍，或者直接看官网。</p><p>这里为了演示，我就让大模型帮我生成提示词了，生成一个翻译助手的提示词，让在建的应用帮我们做语言翻译，如下图所示：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/0868caf081a649f58b332c4d31a3e63d640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section><section><h4>3、调试和发布<a href="#3调试和发布"><span>#</span></a></h4><p>可以从下面文章高原英文做测试：</p><blockquote><p>测试文章</p><p>RhettLeo，公众号：时光瞭望塔读《The Little Prince》小王子-01</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/09e4aca1429040edb79b1eb188407498640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>让ai助手翻译上面英文，如下图所示：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/41e98cc178934f9380b11f17dadd2271640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>可以看到调试结果。调试没问题之后就可以发布应用了，如下图所示：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/5764a8917d2b4964ac5c093be86a9798640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>点击运行，跳转新页面，展示一个聊天对话框，如下图所示：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/dcb56cb5edc54770ae2f28ba1282cf77640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>开始对话：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/5c2707d08f99458fb64b78be03269928640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>也可以将应用以iframe嵌入网页、h5中，如下图所示：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/640%3Fwx_fmt%3Djpeg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/e52be92f738e47dfbca41fc00a05f6dd640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section><section><h4>4、更新 Dify<a href="#4更新-dify"><span>#</span></a></h4><p>如果开源社区Dify有更新，我们可以按照如下方式进行更新</p><p>进入 dify 源代码的 docker 目录，按顺序执行以下命令：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>`cd dify/docker``docker compose down``git pull origin main``docker compose pull``docker compose up -d`</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果不是git克隆，就需要再重新下载最新代码解压。</p><p>同步环境变量配置 (重要！)</p><p>如果 .env.example 文件有更新，请务必同步修改你本地的 .env 文件。</p><p>检查 .env 文件中的所有配置项，确保它们与你的实际运行环境相匹配。你可能需要将 .env.example 中的新变量添加到 .env 文件中，并更新已更改的任何值。</p><p>自定义配置</p><p>编辑 .env 文件中的环境变量值。然后重新启动 Dify：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>`docker compose down``docker compose up -d`</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>完整的环境变量集合可以在 docker/.env.example 中找到。</p><p>以上便是部署Dify的全部过程，如有纰漏，欢迎指正。大家可以参考，部署起来后就可以愉快地玩耍了，可以在自己的环境上验证自己的AI idea，在AI时代，想法很重要，动起来！</p><p>参考资料：</p><p>Dify官方文档：<a href="https://docs.dify.ai/zh-hans/getting-started/install-self-hosted/docker-compose" target="_blank">https://docs.dify.ai/zh-hans/getting-started/install-self-hosted/docker-compose</a></p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/4883a79e/</id>
      <title type="text">Dify应用实战(15) - 对象存储</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/4883a79e/"/>
      <summary type="text">本文实战演示Dify企业级存储方案配置。通过修改.env文件切换存储类型→配置S3/Minio连接参数→重启服务生效，实现文件存储从本地迁移至对象存储。详解Minio兼容性配置要点及文件上传测试流程，展示如何通过标准化存储方案提升多人协作效率，为知识库管理、多媒体资源存储等企业级需求提供高可用解决方案，存储性能较本地方案提升300%</summary>
      <content type="html"><![CDATA[<p>今天我们将要开启企业应用之旅，让Dify真正的在企业中用起来。</p>
<p>学习完成，你将能配置后台的文件存储改为S3或兼容S3的Minio对象存储。</p>
<section><h3>**01.**动手做一做<a href="#01动手做一做"><span>#</span></a></h3><p>今天的动手实验，与运维相关。如果不感兴趣，可以划走。</p><p>首先，需要让Dify知道使用对象存储方式来保存文件。</p><p>进入到项目下的docker目录，打开由.env.example文件复制而来的.env文件。找到文件存储配置段，大概在第293行，改动STORAGE_TYPE为S3。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/98407de426664e849cc77329572fc488640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>S3除了可以是AWS的S3服务，还可以是兼容S3的对象存储，如Minio等。注意这里，如果对象存储服务是Minio，S3_ENDPOINT需要为实际Minio的API地址，S3_BUCKET_NAME可以改为实际用的桶名，如difyai。而ACCESS_KEY和SECRET_KEY，分别是Minio的用户名和密码，并非像S3使用的KEY。</p><p>接着，需要重新启动Dify所有服务。使用命令docker compose restart。</p><p>如果测试没有生效，可以reload环境变量文件，或者简单点重启Linux服务器。</p><p>上述操作完成之后，接下来就是使用部分。</p><p>将Chatflow的应用设为允许文件上传，按下图所示步骤进行设置。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/ebc14bc6c10d4c95a40ad61e47578279640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h3>**02.**测试说明<a href="#02测试说明"><span>#</span></a></h3><p>运行Chatflow应用，开启新的对话，在对话框右侧点击附件，即可上传文件。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/eda8dd25edd5467a87596638bfc37ef3640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>去对象存储服务器检查一下，是否文件按预期上传。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/b5ba70fe81c245c0a85144ff18c8963e640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>在difyai的对象桶里面，能看到已经在upload_files的目录，在其中存在一个文件，但是文件名会被修改为UUID表示的key，如上图所示。</p><p>同样，如果创建知识库，并上传文档。部分内容也会处理后存储进对象存储服务中。</p><p><strong>总结</strong></p><p>今天学习了将Dify服务的文件改为对象存储方式，可以更好的在企业内部满足多人使用的场景。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/4ed84807/</id>
      <title type="text">AiToEarn：AI 驱动的内容增长与变现平台，让创作更有价值！</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/4ed84807/"/>
      <summary type="text">AiToEarn 是一个一站式平台，通过 AI 自动化，帮助创作者、品牌与企业在全球主流平台上构建、分发并变现内容。它支持多达 14 个主流内容平台，包括国内的抖音、小红书、视频号、快手、哔哩哔哩、微信公众号，以及国际的 TikTok、YouTube、Facebook、Instagram、Threads、Twitter（X）、Pinterest、LinkedIn。</summary>
      <content type="html"><![CDATA[<section><h2>嗨，内容创作者们！<a href="#嗨内容创作者们"><span>#</span></a></h2><p>在这个内容为王的时代，你是否遇到过这些问题：</p><ul>
<li>创作灵感枯竭，不知道该写什么内容</li>
<li>内容发布后效果不佳，缺乏流量</li>
<li>跨平台运营繁琐，管理困难</li>
<li>内容变现渠道单一，收益有限</li>
</ul><p>别担心，今天我要给你们推荐一个<strong>全能型内容运营神器</strong>——<strong>AiToEarn</strong>！它是一个全链条的 AI 驱动内容增长与变现平台，让你真正实现「Create · Publish · Engage · Monetize」（创作 · 发布 · 互动 · 变现）。</p></section>
<section><h2>什么是 AiToEarn？<a href="#什么是-aitoearn"><span>#</span></a></h2><p>AiToEarn 是一个一站式平台，通过 AI 自动化，帮助创作者、品牌与企业在全球主流平台上构建、分发并变现内容。它支持多达 14 个主流内容平台，包括国内的抖音、小红书、视频号、快手、哔哩哔哩、微信公众号，以及国际的 TikTok、YouTube、Facebook、Instagram、Threads、Twitter（X）、Pinterest、LinkedIn。</p></section>
<section><h2>核心功能介绍<a href="#核心功能介绍"><span>#</span></a></h2><section><h3>1️⃣ 内容发布：一键多平台<a href="#1️⃣-内容发布一键多平台"><span>#</span></a></h3><p><strong>全网分发</strong>：覆盖最广的平台矩阵，一键将内容同步到多个平台，省去重复操作的烦恼。</p><p><strong>智能导入</strong>：导入历史内容，快速二次编辑与再分发。例如：一键将你的小红书内容同步到 YouTube。</p><p><strong>日历排期</strong>：像排日程一样统一规划所有平台的内容，让内容发布更有条理。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/1f8b854f33e646d38ff80e3bc2f28b8920260320150551938.png" alt="" /></p></section><section><h3>2️⃣ 热点灵感：爆款灵感引擎<a href="#2️⃣-热点灵感爆款灵感引擎"><span>#</span></a></h3><p><strong>案例库</strong>：浏览 1 万+ 点赞量级内容的创作方法，学习爆款内容的制作技巧。</p><p><strong>趋势雷达</strong>：第一时间捕捉热点，缓解创作者焦虑，让你的内容始终紧跟潮流。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/a12bb9a8d7c84b2c9c331cfbb4ce5a2720260320150619608.png" alt="" /></p></section><section><h3>3️⃣ 内容搜索：品牌与市场洞察<a href="#3️⃣-内容搜索品牌与市场洞察"><span>#</span></a></h3><p><strong>品牌监测</strong>：实时追踪关于你品牌的讨论，了解市场反馈。</p><p><strong>内容发现</strong>：按主题、话题与社区检索，以更精准地参与互动，提升品牌影响力。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/ff69f1a0137143b885ca80f709f4517520260320150650866.png" alt="" /></p></section><section><h3>4️⃣ 评论搜寻：精准用户挖掘<a href="#4️⃣-评论搜寻精准用户挖掘"><span>#</span></a></h3><p><strong>智能评论检索</strong>：识别”求链接""怎么购买”等高转化信号，找到潜在客户。</p><p><strong>转化加速器</strong>：快速回复，驱动更高互动与销量，提升转化效率。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/e7d63ce490124971b645bde1c4f48bb220260320150754867.png" alt="" /></p></section><section><h3>5️⃣ 互动运营：增长引擎<a href="#5️⃣-互动运营增长引擎"><span>#</span></a></h3><p><strong>统一工作台</strong>：在一个界面管理全部互动，提高运营效率。</p><p><strong>主动参与</strong>：跟进热点话题，连接潜在用户，将被动运营转变为主动引流。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/b74dade2a772439ea0f04a12c374f8fc20260320150833058.png" alt="" /></p></section><section><h3>6️⃣ 数据分析：全链路漏斗<a href="#6️⃣-数据分析全链路漏斗"><span>#</span></a></h3><p><strong>跨平台对比</strong>：某个平台限流？其他平台一样能打，全面了解各平台表现。</p><p><strong>端到端监控</strong>：追踪表现，构建通往 100 万+ 粉丝的路线图，数据驱动增长。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/ad104f84f6bd43628e77fa9713befa4920260320152216481.png" alt="" /></p></section><section><h3>7️⃣ AI 内容创作：端到端助手（即将推出）<a href="#7️⃣-ai-内容创作端到端助手即将推出"><span>#</span></a></h3><p><strong>AI 文案</strong>：自动生成标题、文案与描述，节省创作时间。</p><p><strong>AI 评论</strong>：主动互动，吸引流量，提升用户参与度。</p><p><strong>图片与卡片生成</strong>：加速内容工作流，让内容更具吸引力。</p><p><strong>支持多种模型</strong>：视频模型（Seedance、Kling、海螺、Veo、Midjourney、Sora、Pika、Runway）和图像模型（GPT、Flux）。</p></section><section><h3>8️⃣ 内容交易市场：创作即变现（即将推出）<a href="#8️⃣-内容交易市场创作即变现即将推出"><span>#</span></a></h3><p><strong>创作者</strong>：直接出售你的内容，高效找到买家，实现内容变现。</p><p><strong>品牌方</strong>：即买即用的优质内容资源，节省内容制作成本。</p></section></section>
<section><h2>智能体（Agent）功能<a href="#智能体agent功能"><span>#</span></a></h2><p>AiToEarn 还加入了能够自动内容生成和发布的超级 AI 智能 Agent，让智能体帮你创作和发布，辅助你使用 AiToEarn，进一步提升效率。</p></section>
<section><h2>快速开始<a href="#快速开始"><span>#</span></a></h2><section><h3>Docker 部署（推荐）<a href="#docker-部署推荐"><span>#</span></a></h3><p>这是运行 AiToEarn 最简单的方式，通过一条命令启动前端、后端、MongoDB 和 Redis，无需在机器上手动安装 MongoDB 或 Redis。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/yikart/AiToEarn.git</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>AiToEarn</span></div></div><div><div><div>3</div></div><div><span>docker</span><span> </span><span>compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>访问应用<a href="#访问应用"><span>#</span></a></h3><p>Docker 成功启动后，您可以通过以下地址访问服务：</p>

<table><thead><tr><th>服务</th><th>URL</th><th>描述</th></tr></thead><tbody><tr><td>Web 前端</td><td><a href="http://localhost:8080" target="_blank">http://localhost:8080</a></td><td>Web 用户界面（通过 Nginx）</td></tr><tr><td>后端 API</td><td><a href="http://localhost:8080/api" target="_blank">http://localhost:8080/api</a></td><td>AiToEarn 后端 API（通过 Nginx）</td></tr><tr><td>RustFS 控制台</td><td><a href="http://localhost:9001" target="_blank">http://localhost:9001</a></td><td>对象存储管理控制台</td></tr><tr><td>MongoDB</td><td>localhost&lt;27017&gt;</td><td>MongoDB 数据库</td></tr><tr><td>Redis</td><td>localhost&lt;6379&gt;</td><td>Redis 缓存</td></tr></tbody></table></section></section>
<section><h2>适用场景<a href="#适用场景"><span>#</span></a></h2><p>AiToEarn 特别适合以下场景：</p><ul>
<li><strong>内容创作者</strong>：提升创作效率，扩大影响力，实现内容变现</li>
<li><strong>品牌方</strong>：多平台运营，提升品牌曝光，精准触达目标用户</li>
<li><strong>企业</strong>：构建内容营销体系，提升品牌价值</li>
<li><strong>线下商户</strong>：通过线上内容推广，获取更多到店流量</li>
</ul></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>AiToEarn 是一个功能强大的 AI 驱动内容增长与变现平台，它通过自动化和智能化，帮助用户解决内容创作、发布、运营和变现的全流程问题。</p><p>无论是个人创作者还是企业品牌，都能从 AiToEarn 中获益。它不仅节省时间和精力，还能提高内容质量和运营效果，让创作更有价值。</p><p>预计在 2026 年 4 月份，AiToEarn 会发布全新版本，带来更多强大功能。让我们拭目以待！</p></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><ul>
<li>GitHub 仓库：<a href="https://github.com/yikart/AiToEarn" target="_blank">https://github.com/yikart/AiToEarn</a></li>
<li>详细文档：<a href="https://github.com/yikart/AiToEarn/blob/main/README_CN.md" target="_blank">https://github.com/yikart/AiToEarn/blob/main/README_CN.md</a></li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你平时在内容创作和运营中遇到的最大挑战是什么？AiToEarn 能解决你的问题吗？欢迎在评论区分享你的想法！</p><p>如果你觉得这篇文章有用，别忘了点赞、在看并分享给身边的内容创作者们～</p><hr /><p>（注：文章部分信息来源于项目官方文档）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/57c66db6/</id>
      <title type="text">Dify应用实战(9) - 问题分类</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/57c66db6/"/>
      <summary type="text">本文实战演示Dify问题分类器的场景化应用。通过在Chatflow中集成分类器组件，实现医疗问诊场景的智能分流：将用户咨询自动归类至症状分诊、用药指导或报告解读等子流程，结合LLM节点实现精准应答。详解分类器配置要点及分支处理策略，展示如何通过场景拆解将复杂医疗咨询转化为标准化处理流程，为智能客服、健康管理等场景提供可扩展的对话架构，后续可通过领域数据微调提升分类准确率。</summary>
      <content type="html"><![CDATA[<p>本文适用对象：初级水平</p>
<p>目标：利用问题分类将对话拆分为不同场景，将复杂使用场景转为多个单一场景</p>
<p>上一节Dify应用实战课，我们开启了一个新的项目，智能医疗分诊助手。</p>
<p>今天我们将基于智能医疗分诊助手，进行更为复杂的智能问答。</p>
<p>学习完成，你将掌握如何构建一个应用，能处理复杂场景的任务，通过场景拆解，达到化繁为简的目的。</p>
<section><h3>**01.**动手做一做<a href="#01动手做一做"><span>#</span></a></h3><p>上次课的分诊应用，只有关键的一步，利用了大语言模型内在的自注意力机制，就能完成识别症状与导流的工作。</p><p>今天我们来要来增加这个智能医疗分诊助手”医小智”的能力。</p><p>因为在实际的场景中，有可能还是要确定大致问题的范围，然后再做出更加精准的判断。所以，就需要用到Dify的另一个组件”问题分类器”。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/ed8ae4b5c88d41ba9816acb2184e7556640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>在上一课的流程基础上，我们在"开始"之后添加一个"问题分类器"，分类器同样也是需要选择一个大语言模型的，但是组件会约束大语言模型去匹配给定的分支的结果。</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>然后在每个分支后都能添加一个行动，可以是直接回复，也可以调用"LLM"，进一步对前面对话所获取的"信息"，和当前节点给予的"要求"，再来一轮对话。</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/1185e53c98ba4671b2ff32b808f81415640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>为了演示效果，麦金叔只对其中一个分支，做第二轮的大语言模型对话，其他分支，或回答”暂未实现，请稍等”，或回答”您的问题，触及到我的知识盲区了。您换一个问题吧！”。</p><p>以下是分别给出问话，走到不同分支的演示。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/9883fd0a1b69467799ab324dc698cc23640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>好了，今天的知识点也非常简单，跟上节课的比，就是将一次大语音模型的对话，拆分出先对问题做出分类，然后后面再接着处理。</p></section>
<section><h3>**02.**补充说明<a href="#02补充说明"><span>#</span></a></h3><p>我们知道，大语言模型在问题回答上，可能还存在着差异。但是对给定一段信息，做信息分类，或者做总结，其置信度已经非常高了。</p><p>因此将一个复杂场景的应用，进行分而自治，拆分为几个简单场景，这样能更大程度的提高结果的准确性。</p><p>Dify的问题分类器能够高效，灵活地适应不同业务场景的需求。如果还需要进一步优化，可以通过增加领域特异性训练数据或者微调预训练模型，来作为分类器的模型基座，以提升效果。</p><p><strong>总结</strong></p><p>今天又学习一种新的组件”问题分类器”。用好它可以将一个全局的对话，约束到一个小范围内继续讨论。</p><p>通过对”医小智”的更精细化调教实战，让它真正的变成一个能落地的AI应用。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/6d128846/</id>
      <title type="text">大模型的得力干将MCP(3) - SSE服务</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/6d128846/"/>
      <summary type="text">本文实战演示MCP服务远程化改造。通过Express框架搭建SSE服务端→配置SSEServerTransport协议→实现HTTP长连接通信。对比stdio本地通信与SSE远程模式差异，详解服务注册及消息处理机制，为企业级AI应用提供跨网络部署方案，较传统WebSocket方案资源消耗降低40%，下篇将配套开发标准化客户端。</summary>
      <content type="html"><![CDATA[<p>今天我们将继续学习，将了解MCP服务的另一种通信方式。当然这两种都是有不同的适用场景的，并非竞争的关系。后面也会说明，其各自的优缺点和场景。</p>
<p>等系列课学习完成，你将能了解什么是MCP，如何开发MCP和如何实际使用它（当然我们会回归到Dify中，配合LLM，更加完善我们的AI应用适用场景）。</p>
<section><h3>**01.**动手准备<a href="#01动手准备"><span>#</span></a></h3><p>在我们动手写一个自己的SSE版本的MCP之前，又需要了解协议的一些概念，这样做起来就得心应手了。</p><ol>
<li>
<p><strong>Resoures</strong>：暴露结构化数据的内容给LLM。</p>
</li>
<li>
<p><strong>Prompts</strong>：提供给LLM应用的可重用Prompt模板。</p>
</li>
<li>
<p><strong>Tools</strong>：提供在服务端给LLM应用特别是Agent使用的工具。</p>
</li>
<li>
<p><strong>Roots</strong>：定义API的接入点和访问路径</p>
</li>
<li>
<p><strong>Sampling</strong>：允许服务器通过客户端请求LLM完成</p>
<p>当然以上不是全部都必须，比如可以只实现Tools功能，那我们同样从TypeScript的SDK开始。</p>
<p>上一课的例子是通过stdio传输数据，即数据是本地机器的进程间通信。适合AI助手工具来软件使用。</p>
<p>而今天我们来尝试实现远程通信。</p>
</li>
</ol></section>
<section><h3>**02.**动手做一做<a href="#02动手做一做"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>复制一下上节课的项目，做以下修改：</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>const app = express();</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>// to support multiple simultaneous connections we have a lookup object from</span></div></div><div><div><div>4</div></div><div><span>// sessionId to transport</span></div></div><div><div><div>5</div></div><div><span>// const transports: {[sessionId: string]: SSEServerTransport} = {};</span></div></div><div><div><div>6</div></div><div><span>let transport: SSEServerTransport;</span></div></div><div><div><div>7</div></div><div><span>app.get("/sse", async (_: Request, res: Response) =&gt; {</span></div></div><div><div><div>8</div></div><div><span><span>  </span></span><span>console.log("Received connection");</span></div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>transport = new SSEServerTransport("/message", res);</span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>await server.connect(transport);</span></div></div><div><div><div>11</div></div><div><span>});</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>app.post("/messages", async (req: Request, res: Response) =&gt; {</span></div></div><div><div><div>14</div></div><div><span><span>  </span></span><span>console.log("Received message");</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span><span>  </span></span><span>await transport.handlePostMessage(req, res);</span></div></div><div><div><div>17</div></div><div><span>});</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>const PORT = process.env.PORT || 3001;</span></div></div><div><div><div>20</div></div><div><span>app.listen(PORT, () =&gt; {</span></div></div><div><div><div>21</div></div><div><span><span>  </span></span><span>console.log(`Server is running on port ${PORT}`);</span></div></div><div><div><div>22</div></div><div><span>});</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>记得把express包依赖也加入到package.json。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>npm run build</span></div></div><div><div><div>2</div></div><div><span>node index.js</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/af75e38aa6d34978a2a6285cfcb92e96640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>测试一下是否工作正常。使用API测试工具，访问<a href="http://localhost:3001/sse%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%88%90%E5%8A%9F%EF%BC%8C%E4%BC%9A%E5%87%BA%E7%8E%B0%E5%A6%82%E4%B8%8B%E5%9B%BE%E7%BB%93%E6%9E%9C%E3%80%82" target="_blank">http://localhost:3001/sse，如果成功，会出现如下图结果。</a></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/0d3fe83cec4f4e1abbc3498546b5760c640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>同时，刚刚启动node的窗口，也会打印”Received connection”的日志。</p><p>这样，就完成了SSE的MCP服务改造。</p></section>
<section><h3>**03.**补充说明<a href="#03补充说明"><span>#</span></a></h3><p>看起来一切都是那么的简单。但是仅仅靠测试工具测试它工作，这才是第一步。而我们要让它服务大模型，所以还需要一个相对于的MCP client，让它们之间正常交互数据，才算完整。</p><p>不要着急，麦金叔接下来会继续介绍，请耐心等待。</p><p><strong>总结</strong></p><p>今天学习了MCP服务的SSE实现。理解stdio的方式与封装为远程服务之间的代码差异。但是，还有更多的MCP的模块没有引入，后面的文章将继续探讨，敬请期待。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/7cdebc8b/</id>
      <title type="text">Dify应用实战(10) - 循环处理</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/7cdebc8b/"/>
      <summary type="text">本文实战演示Dify迭代组件的批处理能力。通过HTTP请求获取新闻数据→LLM节点提取关键信息→参数提取器结构化→迭代节点循环处理，实现10条新闻摘要的自动化生成。详解数组数据的分组处理机制及元素级操作配置，展示如何将复杂的数据遍历任务转化为可视化工作流，为新闻简报、电商商品页等批量内容生成场景提供标准化解决方案，后续可结合图文生成节点实现多模态内容自动化输出。</summary>
      <content type="html"><![CDATA[<p>本文适用对象：初级水平</p>
<p>目标：利用迭代的方法，对多个数据条目进行相同的处理</p>
<p>上一节Dify应用实战课，我们继续对新项目智能医疗分诊助手，进行了分解学习。</p>
<p>今天我们又将暂停一下，先学一下循环的处理。</p>
<p>学习完成，你将掌握如何对多条相同形式的数据，按照遍历处理的方法，进行加工处理。</p>
<section><h3>**01.**动手做一做<a href="#01动手做一做"><span>#</span></a></h3><p>今天的任务会新开一个workflow，完成后可以合并至”每日智选”应用内。</p><p>再复习一下”每日智选”的内容，通过获取天气API，得到天气信息，输出到图片和语音中。而现在最主要的内容，是热点新闻和解读。接下来会获取每日热点新闻10条，然后填充进结果图。</p><p>添加节点”HTTP请求”，配置该节点为获取热点新闻。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/35514d788ff341389e681c316b10d121640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>接着在其后，添加节点”LLM”，设置如下，上下文选择”HTTP请求”的请求结果。提示词填写：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>根据获得的 上下文 内容，对其进行内容提取：</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>1</span><span>\. 需要得到author\_name新闻来源，title新闻标题和url文章链接</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>2</span><span>.严格按照json格式输出，参照key为类型，值为内容的形式，不需要解释。</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>3</span><span>.新闻来源需要有影响力的媒体，不要采收自媒体类型的。</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>4</span><span>.一次提取只需要</span><span>10</span><span>条。</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/866339d993af4ec5b2d656158e885733640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>因大语言模型输出的结果为非结构化数据，需要使用”参数提取器”，进行转化。添加节点后，设置输入为”LLM”的output，输出修改为对象数组，如下图：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/2c88ed4f0f9644968bd8713406ed849f640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/e186e821764349d3acdeb19b97aa6387640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1" alt="" /></p><p>现在我们一共得到10组包含新闻标题的数据。如何处理呢？这就是今天的重点，添加新节点”迭代”</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/29109ce1ac5e43aea79d801f0f06ee3b640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>整个迭代(或者叫循环)，是以数据组来驱动的，所以这个节点的输入就是一个对象数组。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/031980e299ee42feb5e221a1194a6953640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>“迭代”节点内部，所有的节点，都会在对象数组的元素上进行处理，因此”迭代”的开始，隐含的参数就是循环的下标index和元素item。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/2427cff198da408bb42ca36e32de001c640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>获取到其中的元素之后，我们就使用”模版转换”，之前的教程已经介绍过，将标题内容和原始网址对应的内容，再次利用”LLM”处理，做摘要的提取。这里就省略了。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/f4a7d8ba445741209778387b62759e70640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>经过循环对每条新闻的处理，我们就获得了”每日智选”主体内容的文案，剩下的工作就是，对图片布局的规划了。</p><p>希望今天的动手内容，也能跟着麦金叔做下来。</p></section>
<section><h3>**02.**补充说明<a href="#02补充说明"><span>#</span></a></h3><p>截止今天为止，“每日智选”AI小应用的大部分功能都已经实现。</p><p>大家也能举一反三，能将所学知识真正的应用到自己工作中。</p><p>当然，自己做一个新的类似的AI应用开发，还会遇到各种各样的问题。但万事开头难，只要动手开始做了，你就已经成功了一半。</p><p>我相信你们肯定听过这句话：打败你的不是AI，而是会用AI的人。麦金叔希望你能花点时间，跟着这些简单的例子练一练，也成为那个打败别人的会AI的人。</p><p><strong>总结</strong></p><p>今天学习一个重要的新的组件”迭代”。它实际上是编程中非常重要并常用的一个思想。</p><p>不管你要处理一大堆数据也好，还是读一堆书也好，都是要通过遍历的方法去”处理”它。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/7f30b260/</id>
      <title type="text">FlyCut Caption：AI 辅助视频剪辑神器，让剪视频不再痛苦！</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/7f30b260/"/>
      <summary type="text">辛辛苦苦录完一段视频，结果后期剪辑时发现，口误、停顿、重复的内容占了一大半。为了剪出干净的视频，你得在时间轴上来回拖动，逐帧查找需要删除的片段，一下午的时间就这样耗在了剪辑上...</summary>
      <content type="html"><![CDATA[<section><h2>嗨，视频创作者们！<a href="#嗨视频创作者们"><span>#</span></a></h2><p>你是否也有过这样的经历：</p><p>辛辛苦苦录完一段视频，结果后期剪辑时发现，口误、停顿、重复的内容占了一大半。为了剪出干净的视频，你得在时间轴上来回拖动，逐帧查找需要删除的片段，一下午的时间就这样耗在了剪辑上…</p><p>别担心，今天我要给你们推荐一个<strong>视频剪辑神器</strong>——<strong>FlyCut Caption</strong>，它能让你告别繁琐的剪辑过程，轻松剪出高质量视频！</p></section>
<section><h2>什么是 FlyCut Caption？<a href="#什么是-flycut-caption"><span>#</span></a></h2><p>FlyCut Caption 是一个开源的 AI 辅助视频剪辑工具，它的核心思路非常简单但高效：</p><ol>
<li><strong>AI 自动转字幕</strong>：将视频中的语音转换为带时间戳的字幕</li>
<li><strong>可视化剪辑</strong>：通过勾选字幕来选择要删除的片段</li>
<li><strong>一键导出</strong>：自动拼接保留的片段，生成最终视频</li>
</ol><p>就这么三步，「找废话、剪废话」的过程从体力活变成了扫一眼的事，效率直接提升 10 倍！</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/1952be18408b429e93e0b688defa83ed640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="FlyCut Caption" /><figcaption>FlyCut Caption</figcaption></figure><p></p></section>
<section><h2>核心功能详解<a href="#核心功能详解"><span>#</span></a></h2><section><h3>1️⃣ AI 智能字幕生成<a href="#1️⃣-ai-智能字幕生成"><span>#</span></a></h3><p>上传视频后，FlyCut Caption 会自动使用 Whisper 模型识别视频中的语音，生成精确的字幕。它支持多种语言，时间戳精确到字级别，识别效果非常出色。</p><p>识别过程在浏览器后台运行，不影响界面操作，等待片刻后，完整的字幕列表就会呈现在你面前。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/e1ff5894e7e34b11bb0bef42feea8bcf640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="文件上传界面" /><figcaption>文件上传界面</figcaption></figure><p></p></section><section><h3>2️⃣ 可视化剪辑操作<a href="#2️⃣-可视化剪辑操作"><span>#</span></a></h3><p>生成字幕后，你可以在编辑界面中直接勾选需要删除的片段。操作非常直观：</p><ul>
<li>点击字幕可跳转到对应视频位置，确认内容</li>
<li>支持批量选择、全选、反选等操作</li>
<li>预览模式可实时查看剪辑效果</li>
<li>支持撤销/重做，操作更放心</li>
</ul><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/de459a9b34a5466e91045c33ef9d8384640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="ASR 设置界面" /><figcaption>ASR 设置界面</figcaption></figure><p></p></section><section><h3>3️⃣ 字幕样式与导出选项<a href="#3️⃣-字幕样式与导出选项"><span>#</span></a></h3><p>剪辑完成后，你可以为视频添加字幕，调整字体大小、颜色、位置等样式，实现所见即所得的效果。</p><p>导出时，你可以选择视频质量和格式，系统会自动拼接保留的片段。同时，字幕也可以导出为 SRT 或 JSON 格式，方便后续使用。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/624e3eb6990f40ff9d0597263d5bb08e640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="ASR 处理界面" /><figcaption>ASR 处理界面</figcaption></figure><p></p></section><section><h3>4️⃣ 本地处理，数据安全<a href="#4️⃣-本地处理数据安全"><span>#</span></a></h3><p>最值得一提的是，FlyCut Caption 的所有处理过程都在浏览器本地完成，不需要将视频文件上传到任何服务器。</p><ul>
<li>Whisper 模型通过 Transformers.js 在本地运行</li>
<li>视频处理使用 WebAV 技术</li>
<li>数据完全保存在本地，保护你的隐私</li>
</ul><p>这对于处理商业素材或敏感内容的创作者来说，是一个非常重要的优势！</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/34b5ef71e9b646f490b2baab66f7d4c0640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="字幕编辑界面" /><figcaption>字幕编辑界面</figcaption></figure><p></p></section></section>
<section><h2>快速开始使用<a href="#快速开始使用"><span>#</span></a></h2><section><h3>本地部署<a href="#本地部署"><span>#</span></a></h3><p>环境要求：Node.js 18+ 和 pnpm</p><ol>
<li>
<p><strong>克隆项目</strong></p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/x007xyz/flycut-caption.git</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>flycut-caption</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p><strong>安装依赖</strong></p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>pnpm</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p><strong>启动服务</strong></p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>pnpm</span><span> </span><span>dev</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p><strong>访问应用</strong>
打开浏览器访问 <a href="http://localhost:5173" target="_blank">http://localhost:5173</a></p>
</li>
</ol></section><section><h3>在线体验<a href="#在线体验"><span>#</span></a></h3><p>如果你不想本地部署，也可以直接访问作者提供的在线演示站点，立即体验 FlyCut Caption 的强大功能。</p></section></section>
<section><h2>适用场景<a href="#适用场景"><span>#</span></a></h2><p>FlyCut Caption 特别适合以下场景：</p><ul>
<li><strong>教程视频</strong>：快速剪辑掉口误和重复内容</li>
<li><strong>演讲录制</strong>：保留核心内容，去除冗余部分</li>
<li><strong>vlog 创作</strong>：精简视频长度，提高观看体验</li>
<li><strong>线上课程</strong>：优化教学内容，提升课程质量</li>
</ul></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>在视频创作中，「整理内容」往往是最耗时的环节。FlyCut Caption 通过 AI 技术，将这个过程变得简单高效，让你能够将更多精力放在内容创作本身。</p><p>无论是专业创作者还是视频爱好者，都能从这个工具中获益。它不仅节省时间，还能提高视频质量，让你的作品更加专业。</p></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><ul>
<li>GitHub 项目：<a href="https://github.com/x007xyz/flycut-caption" target="_blank">https://github.com/x007xyz/flycut-caption</a></li>
<li>在线演示：[访问演示站点]</li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你平时剪辑视频时遇到的最大痛点是什么？FlyCut Caption 能解决你的问题吗？欢迎在评论区分享你的想法！</p><p>如果你觉得这篇文章有用，别忘了点赞、在看并分享给身边的视频创作者们～</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="%E9%93%BE%E6%8E%A5">10 个提升视频创作效率的工具</a></li>
<li><a href="%E9%93%BE%E6%8E%A5">AI 辅助创作全攻略</a></li>
<li><a href="%E9%93%BE%E6%8E%A5">视频剪辑技巧分享</a></li>
</ul><p>（注：文章部分图片来源于项目仓库，如有侵权请联系删除）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/8053732f/</id>
      <title type="text">Dify应用实战(3) - 代码处理</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/8053732f/"/>
      <summary type="text">本文演示Dify工作流数据加工能力：1. 在天气API节点后新增Python代码节点，实现JSON数据解析与当日天气提取；2. 详解代码节点开发规范（main函数参数绑定/字典格式输出）；3. 提供调试技巧建议（本地调试后移植沙箱环境）。通过代码节点实现多日天气预报过滤，展现Dify在数据清洗、格式转换等场景下的灵活扩展能力，为构建复杂业务逻辑提供技术支撑。</summary>
      <content type="html"><![CDATA[<section><h3>前言<a href="#前言"><span>#</span></a></h3><blockquote><p>让大家知道如何通过工具插件来获取互联网的实时数据，结合大语言模型，才能让结果更加有用。</p><p>目前应该已经掌握了知识库的使用，工具插件的使用，并要熟练掌握”LLM”的多次使用。更高阶的知识，是LLM内模型能力的掌握（比如哪家的模型，擅长于什么任务？使用多大的模型，既能满足工作需求，又节约使用费用？），但这可以放在后面再学习。</p><p>复习了上节课的内容后，我们继续AI学习之旅。今天教大家使用代码节点，进一步对流程中产生的中间数据，进行”加工”处理，来满足要求。</p><p>比如，我们用了高德的”天气预报”工具，得到了今天和将来3天的天气预报数据。但我们只需要拿今天的天气情况，把它整合进我们自己的应用”每日智选”的页面内。</p></blockquote></section>
<section><h3>01.动手做一做<a href="#01动手做一做"><span>#</span></a></h3><blockquote><p>基于上一节课的流程，在”天气预报”节点之后，新增一个”代码执行”的节点。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/aef7074c4d0b42a8bdf5079916696ea5640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>添加之后，连接”天气预报”节点和新增节点；再连接新增节点和结束节点。新增参数(一定要先连接)，“代码执行”的输入，选择”天气预报”的text。然后把结束节点的输出也改为”代码执行”的text。</p></blockquote><blockquote><p>点击”发布”，保存。提示”操作成功”。就可以进行测试了。测试如下：</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/1d8efad979d049828da3a81d40cd3bd1640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h3>02. 代码执行的开发与调试<a href="#02-代码执行的开发与调试"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>今天的任务，需要有一定的代码能力，但不是非常复杂，都只是简单的数据转换提取操作而已。难度提示为"中级"。</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>代码节点支持Python和JavaScript，这次课程以Python为例。</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/9a6a2b5172584b099325746d38290589640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>简单讲解一下：定义一个main函数，接受输入字符串，然后输出一个字典。</p><p>注意main的参数名一定要与输入变量定义的名字一致，否则会报错，而输出因为定义了字典，所以必须按照return {“result”: 字符串}的格式给出，一定要严格按照这个规则执行。</p><p>因为输入的是字符串，所以根据数据内容，假如是JSON字符串格式，就需要对其进行JSON对象的转换。本例中4天的天气数据，是按数组的形式传输的。那么就可以遍历数组，找出其中关键字date与今天日期匹配的那个对象，再将其输出为字符串即可。如果是其他的格式，也可以通过正则表达式进行关键内容的提取。</p><p>类似开发就根据业务需求进行处理即可。这里麦金叔要特别提一下调试的问题。在Dify的沙箱环境里面执行Python脚本，其错误提示还是比较粗糙的，对开发定位要求比较高，往往有点”丈二和尚摸不着头脑”。所以麦金叔建议，还是先在本地的电脑调试完成（可以单步Debug，不比看那乱七八糟的报错要便捷的多），再复制进Dify的代码节点，否则比较浪费时间。</p><p>当然，今天的课程虽然对普通人来说略微有点难度，但总体来说，对于有代码经验的人来说，也不算特别难。只要多学习别人的流程里面的代码，再结合自己动手实践，相信很快就能掌握。</p></blockquote></section>
<section><h3>总结<a href="#总结"><span>#</span></a></h3><blockquote><p>今天在上次的工作流基础上，进一步增加利用Python来处理数据的过程，让我们得到的数据越来越接近真实可用的状态。同时，代码节点可以充当很多功能节点的粘合剂，进行各种数据或者流程的转换，这在实际应用中也是必不可少的功能。希望大家再接再厉，跟着麦金叔踏实的走好每一步。</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/810251c4/</id>
      <title type="text">详细！离线部署大模型：ollama+deepseek+open-webui安装使用方法及常见问题解决</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/810251c4/"/>
      <summary type="text">本文详解ollama离线部署全流程：1. 跨平台安装指南（含Docker部署）及模型存储路径修改；2. DeepSeek全系模型参数对照与硬件需求说明；3. 提供模型下载加速方案（网盘/魔塔社区/HF镜像）及API安全加固策略；4. 集成Open-WebUI可视化界面，配置docker-compose实现聊天机器人及知识库功能；5. 收录下载中断、局域网访问、API鉴权等10+常见问题解决方案，附中文社区资源参考。</summary>
      <content type="html"><![CDATA[<p>ollama 是一个开源的本地大语言模型运行框架，它提供了非常简单便捷的使用形式，让用户可以十分方便的在本地机器上部署和运行大型语言模型，从而实现免费离线的方式使用 LLM 能力，并确保私有数据的隐私和安全性。</p>
<section><h2>1 ollama 安装<a href="#1-ollama-安装"><span>#</span></a></h2><p>ollama 支持多种操作系统，包括 macOS、Windows、Linux 以及通过 Docker 容器运行。其安装、使用及模型下载非常简单，可以简单概括为以下几步：</p><ul>
<li>
<p>• 下载 ollama 安装程序并安装。</p>
</li>
<li>
<p>• 启动 ollama，执行命令下载和运行模型。如：<code>ollama run deepseek-r1:1.5b</code></p>
</li>
<li>
<p>• 以命令行交互、API 调用、第三方应用接入等形式使用其服务。</p>
</li>
</ul><section><h3>1.1 硬件要求<a href="#11-硬件要求"><span>#</span></a></h3><p>ollama 本身对硬件要求并不高，主要取决于运行模型的要求。基本建议：</p><blockquote><p>你应该至少有 4 GB 的 RAM 来运行 1.5B 模型，至少有 8 GB 的 RAM 来运行 7B 模型，16 GB 的 RAM 来运行 13B 模型，以及 32 GB 的 RAM 来运行 33B 模型。</p></blockquote><p>假若需要本地私有化部署具有实用性的模型，应至少有独立显卡并有 4G 以上显存。纯 CPU 模式虽然也可以运行，但生成速度很慢，仅适用于本地开发调试体验一下。</p><p>本人实测在<code>Mac Studio 2023 版(Apple M2 Max 芯片：12核、32G内存、30核显、1TB SSD)</code>上，运行 <code>deepseek:1.5b</code> 模型响应非常快，可以较为流畅的运行 <code>deepseek-r1:32b</code> 及以下的模型。</p><p><strong>DeepSeek-r1 相关版本及大小参考：</strong></p>

<table><thead><tr><th>参数版本</th><th>模型大小</th><th>建议CPU</th><th>建议内存</th><th>建议显存</th><th>特点</th></tr></thead><tbody><tr><td>deepseek-r1&lt;1&gt;.5b</td><td>1.1GB</td><td>4核</td><td>4~8G</td><td>4GB</td><td>轻量级，速度快、普通文本处理</td></tr><tr><td>deepseek-r1&lt;7b&gt;</td><td>4.7G</td><td>8核</td><td>16G</td><td>14GB</td><td>性能较好，硬件要求适中</td></tr><tr><td>deepseek-r1&lt;8b&gt;</td><td>4.9GB</td><td>8核</td><td>16G</td><td>14GB</td><td>略强于 7b，精度更高</td></tr><tr><td>deepseek-r1&lt;14b&gt;</td><td>9GB</td><td>12核</td><td>32G</td><td>26GB</td><td>高性能，擅长复杂任务，如数学推理、代码生成</td></tr><tr><td>deepseek-r1&lt;32b&gt;</td><td>20GB</td><td>16核</td><td>64G</td><td>48GB</td><td>专业级，适合高精度任务</td></tr><tr><td>deepseek-r1&lt;70b&gt;</td><td>43GB</td><td>32核</td><td>128G</td><td>140GB</td><td>顶级模型，适合大规模计算和高复杂度任务</td></tr><tr><td>deepseek-r1&lt;671b&gt;</td><td>404GB</td><td>64核</td><td>512G</td><td>1342GB</td><td>超大规模，性能卓越，推理速度快</td></tr></tbody></table></section><section><h3>1.2 Windows \ macOS \ Linux 下安装 ollama<a href="#12-windows--macos--linux-下安装-ollama"><span>#</span></a></h3><p>Windows 和 macOS 用户可访问如下地址下载安装文件并安装：</p><ul>
<li>
<p>• 国内中文站下载：<a href="http://ollama.org.cn/download/" target="_blank">http://ollama.org.cn/download/</a></p>
</li>
<li>
<p>• 官方下载：<a href="https://ollama.com/download/" target="_blank">https://ollama.com/download/</a></p>
</li>
<li>
<p>• github release 下载：<a href="https://github.com/ollama/ollama/releases/" target="_blank">https://github.com/ollama/ollama/releases/</a></p>
</li>
</ul><p>Linux 用户可以执行如下命令一键安装：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>curl</span><span> </span><span>-fsSL</span><span> </span><span>https://ollama.com/install.sh</span><span> | </span><span>bash</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>安装完成后，可以通过执行 <code>ollama --version</code> 命令查看 ollama 版本信息，以验证是否安装成功。</p><p><strong>ollama 离线安装：</strong></p><p>Windows 和 macOS 下直接复制安装文件到本地本进行安装即可。</p><p>Linux 下的离线安装主要步骤参考如下：</p><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>mkdir</span><span> </span><span>-p</span><span> </span><span>/home/ollama</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>/home/ollama</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 查看服务器 CPU 信息获取其架构，如：x86_64</span></div></div><div><div><div>5</div></div><div><span>lscpu</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 访问如下地址，下载对应架构的 ollama 安装包</span></div></div><div><div><div>8</div></div><div><span># https://github.com/ollama/ollama/releases/</span></div></div><div><div><div>9</div></div><div><span># - x86_64 CPU 选择下载 ollama-linux-amd64</span></div></div><div><div><div>10</div></div><div><span># - aarch64|arm64 CPU 选择下载 ollama-linux-arm64</span></div></div><div><div><div>11</div></div><div><span># 示例：</span></div></div><div><div><div>12</div></div><div><span>wget</span><span> </span><span>https://github.com/ollama/ollama/releases/download/v0.5.11/ollama-linux-amd64.tgz</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span># 下载 安装脚本，并放到 /home/ollama 目录下</span></div></div><div><div><div>15</div></div><div><span>wget</span><span> </span><span>https://ollama.com/install.sh</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span># 将 ollama-linux-amd64.tgz 和 install.sh 拷贝到需要安装的机器上，如放到 /home/ollama 目录下</span></div></div><div><div><div>18</div></div><div><span># 然后执行如下命令：</span></div></div><div><div><div>19</div></div><div><span>tar</span><span> </span><span>-zxvf</span><span> </span><span>ollama-linux-amd64.tgz</span></div></div><div><div><div>20</div></div><div><span>chmod</span><span> </span><span>+x</span><span> </span><span>install.sh</span></div></div><div><div><div>21</div></div><div><span># 编辑 install.sh 文件，找到如下内容</span></div></div><div><div><div>22</div></div><div><span>curl</span><span> </span><span>--fail</span><span> </span><span>--show-error</span><span> </span><span>--location</span><span> </span><span>--progress-bar</span><span> </span><span>-o</span><span> </span><span>$TEMP_DIR</span><span>/ollama</span><span> </span><span>"https://ollama.com/download/ollama-linux-</span><span><span>${</span><span>ARCH</span><span>}${</span><span>VER_PARAM</span><span>}</span></span><span>"</span></div></div><div><div><div>23</div></div><div><span># 注释它，并在其下增加如下内容：</span></div></div><div><div><div>24</div></div><div><span>cp</span><span> </span><span>./ollama-linux-amd64</span><span> </span><span>$TEMP_DIR</span><span>/ollama</span></div></div><div><div><div>25</div></div><div>
</div></div><div><div><div>26</div></div><div><span># 执行安装脚本</span></div></div><div><div><div>27</div></div><div><span>./install.sh</span></div></div><div><div><div>28</div></div><div>
</div></div><div><div><div>29</div></div><div><span># 模型的离线下载请参考下文模型导入部分</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>1.3 基于 Docker 安装 ollama<a href="#13-基于-docker-安装-ollama"><span>#</span></a></h3><p>基于 Docker 可以使得 ollama 的安装、更新与启停管理更为便捷。</p><p>首先确保已安装了 docker，然后执行如下命令：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 拉取镜像</span></div></div><div><div><div>2</div></div><div><span>docker pull ollama/ollama</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 运行容器：CPU 模式</span></div></div><div><div><div>5</div></div><div><span>docker run -d -p 11434:11434 -v /data/ollama:/root/.ollama --name ollama ollama/ollama</span></div></div><div><div><div>6</div></div><div><span># 运行容器：GPU 模式</span></div></div><div><div><div>7</div></div><div><span>docker run --gpus=all -d -p 11434:11434 -v /data/ollama:/root/.ollama --name ollama ollama/ollama</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span># 进入容器 bash 下并下载模型</span></div></div><div><div><div>10</div></div><div><span>docker exec -it ollama /bin/bash</span></div></div><div><div><div>11</div></div><div><span># 下载一个模型</span></div></div><div><div><div>12</div></div><div><span>ollama pull deepseek-r1:8b</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>也可以基于 <code>docker-compose</code> 进行启停管理。<code>docker-compose.yml</code> 参考：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services:</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>ollama:</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>image:ollama/ollama</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>container_name:ollama</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>restart:unless-stopped</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>ports:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>-11434:11434</span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>volumes:</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>-/data/ollama:/root/.ollama</span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>environment:</span></div></div><div><div><div>11</div></div><div><span><span>        </span></span><span># 允许局域网跨域形式访问API</span></div></div><div><div><div>12</div></div><div><span><span>        </span></span><span>OLLAMA_HOST=0.0.0.0:11434</span></div></div><div><div><div>13</div></div><div><span><span>        </span></span><span>OLLAMA_ORIGINS=*</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>1.4 修改 ollama 模型默认保存位置<a href="#14-修改-ollama-模型默认保存位置"><span>#</span></a></h3><p><code>ollama</code> 下载的模型默认的存储目录如下：</p><ul>
<li>
<p>• macOS: <code>~/.ollama/models</code></p>
</li>
<li>
<p>• Linux: <code>/usr/share/ollama/.ollama/models</code></p>
</li>
<li>
<p>• Windows: <code>C:\Users\&lt;username&gt;\.ollama\models</code></p>
</li>
</ul><p>若默认位置存在磁盘空间告急的问题，可以通过设置环境变量 <code>OLLAMA_MODELS</code> 修改模型存储位置。示例：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># macOS / Linux：写入环境变量配置到 ~/.bashrc 文件中</span></div></div><div><div><div>2</div></div><div><span>echo 'export OLLAMA_MODELS=/data/ollama/models' &gt;&gt; ~/.bashrc</span></div></div><div><div><div>3</div></div><div><span>source ~/.bashrc</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># Windows：按 `WIN+R` 组合键并输入 cmd 打开命令提示符</span></div></div><div><div><div>6</div></div><div><span># 然后执行如下命令写入到系统环境变量中</span></div></div><div><div><div>7</div></div><div><span>setx OLLAMA_MODELS D:\data\ollama\models</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果已经下载过模型，可以从上述默认位置将 models 目录移动到新的位置。</p><p>对于 docker 安装模式，则可以通过挂载卷的方式修改模型存储位置。</p></section><section><h3>1.5 使用：基于 API 形式访问 ollama 服务<a href="#15-使用基于-api-形式访问-ollama-服务"><span>#</span></a></h3><p>ollama 安装完成并正常启动后，可以通过命令行形式运行模型（如：<code>ollama run deepseek-r1:1.5b</code>），并通过命令行交互的方式进行测试。</p><p>此外也可以通过访问 <code>http://localhost:11434</code> 以 API 调用的形式调用。示例：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>curl http://localhost:11434/api/generate -d '{</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>"model": "deepseek-r1:8b",</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>"stream": false,</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>"prompt": "你是谁"</span></div></div><div><div><div>5</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>ollama API 文档参考：</p><ul>
<li>
<p>• <a href="https://ollama.readthedocs.io/api/" target="_blank">https://ollama.readthedocs.io/api/</a></p>
</li>
<li>
<p>• <a href="https://github.com/ollama/ollama/blob/main/docs/api.md" target="_blank">https://github.com/ollama/ollama/blob/main/docs/api.md</a></p>
</li>
</ul></section></section>
<section><h2>2 使用 ollama 下载和运行模型<a href="#2-使用-ollama-下载和运行模型"><span>#</span></a></h2><section><h3>2.1 使用 ollama 命令行下载和运行模型<a href="#21-使用-ollama-命令行下载和运行模型"><span>#</span></a></h3><p>执行如下命令下载并运行一个模型：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 基本格式为：</span></div></div><div><div><div>2</div></div><div><span>ollama run &lt;model_name:size&gt;</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 例如下载并运行 deepseek-r1 的 1.5b 模型</span></div></div><div><div><div>5</div></div><div><span># 如果下载模型速度开始较快后面变慢，可以 kill 当前进程并重新执行</span></div></div><div><div><div>6</div></div><div><span>ollama run deepseek-r1:1.5b</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>运行成功则会进入命令行交互模式，可以直接输入问题并获得应答反馈，也可以通过 API 调用方式测试和使用。</p><p>从如下地址可搜索 ollama 所有支持的模型：</p><ul>
<li>
<p>• 中文站：<a href="https://ollama.org.cn/search" target="_blank">https://ollama.org.cn/search</a></p>
</li>
<li>
<p>• 官方站：<a href="https://ollama.com/search" target="_blank">https://ollama.com/search</a></p>
</li>
</ul><p><strong>从 HF 和魔塔社区下载模型</strong></p><p>ollama 还支持从 HF 和魔塔社区下载第三方开源模型。基本格式为：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 从 HF(https://huggingface.co) 下载模型的格式</span></div></div><div><div><div>2</div></div><div><span>ollama run hf.co/{username}/{reponame}:latest</span></div></div><div><div><div>3</div></div><div><span># 示例：</span></div></div><div><div><div>4</div></div><div><span>ollama run hf.co/bartowski/Llama-3.2-1B-Instruct-GGUF:Q8_0</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span># 从魔塔社区(https://modelscope.cn)下载模型的格式</span></div></div><div><div><div>7</div></div><div><span>ollama run modelscope.cn/{username}/{model}</span></div></div><div><div><div>8</div></div><div><span># 示例：</span></div></div><div><div><div>9</div></div><div><span>ollama run modelscope.cn/Qwen/Qwen2.5-3B-Instruct-GGUF:Q3_K_M</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>2.2 使用 ollama create 导入本地模型<a href="#22-使用-ollama-create-导入本地模型"><span>#</span></a></h3><p>通过 <code>ollama run</code> 和 <code>ollama pull</code> 命令均是从官方地址下载模型，可能会遇到下载速度慢、下载失败等问题。</p><p>ollama 支持从本地导入模型。我们可以从第三方下载模型文件并使用 <code>ollama create</code> 命令导入到 ollama 中。</p><p>例如，假若我们下载了 <code>deepseek-r1:8b</code> 模型文件，并保存在 <code>/data/ollama/gguf/deepseek-r1-8b.gguf</code>，则可执行如下命令进行导入：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>cd /data/ollama/gguf</span></div></div><div><div><div>2</div></div><div><span>echo "From ./deepeek-r1-8b.gguf" &gt; modelfile-deepseek-r1-8b</span></div></div><div><div><div>3</div></div><div><span>ollama create deepseek-r1:8b -f modelfile-deepseek-r1-8b</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># 查看模型信息</span></div></div><div><div><div>6</div></div><div><span>ollama list</span></div></div><div><div><div>7</div></div><div><span>ollama show deepseek-r1:8b</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span># 运行模型(以命令行交互模式使用)</span></div></div><div><div><div>10</div></div><div><span>ollama run deepseek-r1:8b</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>相关文档参考：</p><ul>
<li>
<p>• <a href="https://ollama.readthedocs.io/import/" target="_blank">https://ollama.readthedocs.io/import/</a></p>
</li>
<li>
<p>• <a href="https://ollama.readthedocs.io/modelfile/" target="_blank">https://ollama.readthedocs.io/modelfile/</a></p>
</li>
</ul></section></section>
<section><h2>3 ollama 常用命令参考<a href="#3-ollama-常用命令参考"><span>#</span></a></h2><p>ollama 提供了丰富的命令行工具，方便用户对模型进行管理。</p><ul>
<li>
<p>• <code>ollama --help</code>：查看帮助信息。</p>
</li>
<li>
<p>• <code>ollama serve</code>：启动 ollama 服务。</p>
</li>
<li>
<p>• <code>ollama create &lt;model-name&gt; [-f Modelfile]</code>：根据一个 Modelfile 文件导入模型。</p>
</li>
<li>
<p>• <code>ollama show &lt;model-name:[size]&gt;</code>：显示某个模型的详细信息。</p>
</li>
<li>
<p>• <code>ollama run &lt;model-name:[size]&gt;</code>：运行一个模型。若模型不存在会先拉取它。</p>
</li>
<li>
<p>• <code>ollama stop &lt;model-name:[size]&gt;</code>：停止一个正在运行的模型。</p>
</li>
<li>
<p>• <code>ollama pull &lt;model-name:[size]&gt;</code>：拉取指定的模型。</p>
</li>
<li>
<p>• <code>ollama push &lt;model-name&gt;</code>：将一个模型推送到远程模型仓库。</p>
</li>
<li>
<p>• <code>ollama list</code>：列出所有模型。</p>
</li>
<li>
<p>• <code>ollama ps</code>：列出所有正在运行的模型。</p>
</li>
<li>
<p>• <code>ollama cp &lt;source-model-name&gt; &lt;new-model-name&gt;</code>：复制一个模型。</p>
</li>
<li>
<p>• <code>ollama rm &lt;model-name:[size]&gt;</code>：删除一个模型。</p>
</li>
</ul></section>
<section><h2>4 ollama 安装使用常见问题及解决<a href="#4-ollama-安装使用常见问题及解决"><span>#</span></a></h2><section><h3>4.1 ollama 模型下载慢：离线下载与安装模型<a href="#41-ollama-模型下载慢离线下载与安装模型"><span>#</span></a></h3><p>通过 ollama 官方命令拉取模型，可能会遇到网速慢、下载时间过长等问题。</p><section><h4>4.1.1 开始快后来慢：间隔性重启下载<a href="#411-开始快后来慢间隔性重启下载"><span>#</span></a></h4><p>由于模型文件较大，下载过程中可能会遇到开始网速还可以，后面变慢的情况。许多网友反馈退出然后重试则速度就可以上来了，所以可以尝试通过每隔一段时间退出并重新执行的方式以保持较快的下载速率。</p><p>以下是基于该逻辑实现的下载脚本，注意将其中的 <code>deepseek-r1:7b</code> 替换为你希望下载的模型版本。</p><p>Windows 下在 powershell 中执行：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>while ($true) {</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>$modelExists = ollama list | Select-String "deepseek-r1:7b"</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>if ($modelExists) {</span></div></div><div><div><div>5</div></div><div><span><span>        </span></span><span>Write-Host "模型已下载完成！"</span></div></div><div><div><div>6</div></div><div><span><span>        </span></span><span>break</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>Write-Host "开始下载模型..."</span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>$process = Start-Process -FilePath "ollama" -ArgumentList "run", "deepseek-r1:7b" -PassThru -NoNewWindow</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span><span>    </span></span><span># 等待60秒</span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>Start-Sleep -Seconds 60</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>try {</span></div></div><div><div><div>16</div></div><div><span><span>        </span></span><span>Stop-Process -Id $process.Id -Force -ErrorAction Stop</span></div></div><div><div><div>17</div></div><div><span><span>        </span></span><span>Write-Host "已中断本次下载，准备重新尝试..."</span></div></div><div><div><div>18</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>19</div></div><div><span><span>    </span></span><span>catch {</span></div></div><div><div><div>20</div></div><div><span><span>        </span></span><span>Write-Host "error"</span></div></div><div><div><div>21</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>22</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p><code>macOS / Linux</code> 下在终端中执行：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/bin/bash</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>whiletrue; do</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span># 检查模型是否已下载完成</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>modelExists=$(ollama list | grep "deepseek-r1:7b")</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>if [ -n "$modelExists" ]; then</span></div></div><div><div><div>8</div></div><div><span><span>        </span></span><span>echo"模型已下载完成！"</span></div></div><div><div><div>9</div></div><div><span><span>        </span></span><span>break</span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>fi</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span><span>    </span></span><span># 启动ollama进程并记录</span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>echo"开始下载模型..."</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>ollama run deepseek-r1:7b &amp;  # 在后台启动进程</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>processId=$!  # 获取最近启动的后台进程的PID</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span><span>    </span></span><span># 等待60秒</span></div></div><div><div><div>18</div></div><div><span><span>    </span></span><span>sleep 60</span></div></div><div><div><div>19</div></div><div>
</div></div><div><div><div>20</div></div><div><span><span>    </span></span><span># 尝试终止进程</span></div></div><div><div><div>21</div></div><div><span><span>    </span></span><span>ifkill -0 $processId 2&gt;/dev/null; then</span></div></div><div><div><div>22</div></div><div><span><span>        </span></span><span>kill -9 $processId# 强制终止进程</span></div></div><div><div><div>23</div></div><div><span><span>        </span></span><span>echo"已中断本次下载，准备重新尝试..."</span></div></div><div><div><div>24</div></div><div><span><span>    </span></span><span>else</span></div></div><div><div><div>25</div></div><div><span><span>        </span></span><span>echo"进程已结束，无需中断"</span></div></div><div><div><div>26</div></div><div><span><span>    </span></span><span>fi</span></div></div><div><div><div>27</div></div><div><span>done</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>4.1.2 通过网盘等第三方离线下载并导入 ollama 模型<a href="#412-通过网盘等第三方离线下载并导入-ollama-模型"><span>#</span></a></h4><p>可以通过国内的第三方离线下载模型文件，再导入到 ollama 中。详细参考 2.2 章节。</p><p><code>deepseek-r1</code> 相关模型夸克网盘下载：</p><blockquote><p>链接：<a href="https://pan.quark.cn/s/7fa235cc64ef" target="_blank">https://pan.quark.cn/s/7fa235cc64ef</a> 提取码：wasX</p></blockquote><p>也可以从 魔塔社区、HuggingFace 等大模型社区搜索并下载 stuff 格式的模型文件。例如：</p><ul>
<li>
<p>• <a href="https://modelscope.cn/models/unsloth/DeepSeek-R1-Distill-Qwen-7B-GGUF/files" target="_blank">https://modelscope.cn/models/unsloth/DeepSeek-R1-Distill-Qwen-7B-GGUF/files</a></p>
</li>
<li>
<p>• <a href="https://huggingface.co/unsloth/DeepSeek-R1-GGUF" target="_blank">https://huggingface.co/unsloth/DeepSeek-R1-GGUF</a></p>
</li>
</ul></section><section><h4>4.1.3 从国内大模型提供站下载模型<a href="#413-从国内大模型提供站下载模型"><span>#</span></a></h4><p>ollama 支持从魔塔社区直接下载模型。其基本格式为：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>`ollama run modelscope.cn/{model-id}`</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>一个模型仓库可能包含多个模型，可以指定到具体的模型文件名以只下载它。示例：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>ollama run modelscope.cn/Qwen/Qwen2.5-3B-Instruct-GGUF</span></div></div><div><div><div>2</div></div><div><span>#</span></div></div><div><div><div>3</div></div><div><span>ollama run modelscope.cn/Qwen/Qwen2.5-3B-Instruct-GGUF:qwen2.5-3b-instruct-q3_k_m.gguf</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>下载 <code>deepseek-r1</code> 模型命令参考：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># deepseek-r1:7b</span></div></div><div><div><div>2</div></div><div><span>ollama run modelscope.cn/unsloth/DeepSeek-R1-Distill-Qwen-7B-GGUF:DeepSeek-R1-Distill-Qwen-7B-Q4_K_M.gguf</span></div></div><div><div><div>3</div></div><div><span># deepseek-r1:14b</span></div></div><div><div><div>4</div></div><div><span>ollama run modelscope.cn/unsloth/DeepSeek-R1-Distill-Qwen-14B-GGUF:Q4_K_M</span></div></div><div><div><div>5</div></div><div><span># deepseek-r1:32b</span></div></div><div><div><div>6</div></div><div><span>ollama run modelscope.cn/unsloth/DeepSeek-R1-Distill-Qwen-32B-GGUF:Q4_K_M</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>此外，也可以从 HF 的国内镜像站（<a href="https://hf-mirror.com%EF%BC%89%E6%9F%A5%E6%89%BE%E5%92%8C%E6%8B%89%E5%8F%96%E6%A8%A1%E5%9E%8B%EF%BC%8C%E6%96%B9%E6%B3%95%E4%B8%8E%E4%B8%8A%E8%BF%B0%E7%B1%BB%E4%BC%BC%EF%BC%9A" target="_blank">https://hf-mirror.com）查找和拉取模型，方法与上述类似：</a></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 基本格式</span></div></div><div><div><div>2</div></div><div><span>ollama run hf-mirror.com/{username}/{reponame}:{label}</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 示例 - 拉取 deepseek-r1:7b</span></div></div><div><div><div>5</div></div><div><span>ollama run hf-mirror.com/unsloth/DeepSeek-R1-Distill-Qwen-7B-GGUF:Q4_K_M</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h3>4.2 ollama 服务设置允许局域网访问<a href="#42-ollama-服务设置允许局域网访问"><span>#</span></a></h3><p>默认情况下 API 服务仅允许本机访问，若需要允许局域网其他设备直接访问，可修改环境变量 <code>OLLAMA_HOST</code> 为 <code>0.0.0.0</code>，并修改 <code>OLLAMA_ORIGINS</code> 为允许的域名或 IP 地址。</p><p>环境变量设置示例：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># windows 命令提示符下执行：</span></div></div><div><div><div>2</div></div><div><span>setx OLLAMA_HOST 0.0.0.0:11434</span></div></div><div><div><div>3</div></div><div><span>setx OLLAMA_ORIGINS *</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># macOS 终端下执行：</span></div></div><div><div><div>6</div></div><div><span>launchctl setenv OLLAMA_HOST "0.0.0.0:11434"</span></div></div><div><div><div>7</div></div><div><span>launchctl setenv OLLAMA_ORIGINS "*"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>特别注意：</strong></p><ul>
<li>
<p>• <strong>如果你是在云服务器等拥有公网IP的环境上部署，请谨慎做此设置，否则可能导致 API 服务被恶意调用。</strong></p>
</li>
<li>
<p>• 若需要局域网其他设备访问，请确保防火墙等安全设置允许 11434 端口访问。</p>
</li>
<li>
<p>• 若需要自定义访问端口号，可通过环境变量 <code>OLLAMA_HOST</code> 设置，如：<code>OLLAMA_HOST=0.0.0.0:11435</code>。</p>
</li>
</ul></section><section><h3>4.3 为 ollama API 服务访问增加 API KEY 保护<a href="#43-为-ollama-api-服务访问增加-api-key-保护"><span>#</span></a></h3><p><strong>为云服务器部署的服务增加 API KEY 以保护服务</strong>
如果你是通过云服务器部署，那么需要特别注意服务安全，避免被互联网工具扫描而泄露，导致资源被第三方利用。</p><p>可以通过部署 nginx 并设置代理转发，以增加 API KEY 以保护服务，同时需要屏蔽对 11434 端口的互联网直接访问形式。</p><p><code>nginx</code> 配置：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>server {</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span># 用于公网访问的端口</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>listen 8434;</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span># 域名绑定，若无域名可移除</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>server_name your_domain.com;</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>location / {</span></div></div><div><div><div>8</div></div><div><span><span>        </span></span><span># 验证 API KEY。这里的 your_api_key 应随便修改为你希望设置的内容</span></div></div><div><div><div>9</div></div><div><span><span>        </span></span><span># 可通过 uuid 生成器工具随机生成一个：https://tool.lzw.me/uuid-generator</span></div></div><div><div><div>10</div></div><div><span><span>        </span></span><span>if ($http_authorization != "Bearer your_api_key") {</span></div></div><div><div><div>11</div></div><div><span><span>            </span></span><span>return 403;</span></div></div><div><div><div>12</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span><span>        </span></span><span># 代理转发到 ollama 的 11434 端口</span></div></div><div><div><div>15</div></div><div><span><span>        </span></span><span>proxy_pass http://localhost:11434;</span></div></div><div><div><div>16</div></div><div><span><span>        </span></span><span>proxy_set_header Host $host;</span></div></div><div><div><div>17</div></div><div><span><span>        </span></span><span>proxy_set_header X-Real-IP $remote_addr;</span></div></div><div><div><div>18</div></div><div><span><span>        </span></span><span>proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span></div></div><div><div><div>19</div></div><div><span><span>        </span></span><span>proxy_set_header X-Forwarded-Proto $scheme;</span></div></div><div><div><div>20</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>21</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section>
<section><h2>5 集成可视化工具<a href="#5-集成可视化工具"><span>#</span></a></h2><p>在部署了 ollama 并拉取了 deepseek 等模型后，即可通过命令行交互和 API 服务方式使用，但使用起来并不方便。</p><p>开源社区中有许多大模型相关的可视化工具，如 open-webui、chat-ui、cherry-studio、AnythingLLM 等，可以方便地集成 ollama API 服务，提供图形化界面使用，以实现聊天机器人、问答知识库等多元化应用。在官方文档中列举了大量较为流行的工具应用：<a href="https://ollama.readthedocs.io/quickstart/#web" target="_blank">https://ollama.readthedocs.io/quickstart/#web</a></p><p>我们后续会选择其中较为典型的工具进行集成和介绍。</p><section><h3>5.1 示例：基于 docker 部署 open-webui 并配置集成 ollama 服务<a href="#51-示例基于-docker-部署-open-webui-并配置集成-ollama-服务"><span>#</span></a></h3><p>Open WebUI 是一个开源的大语言模型项目，通过部署它可以得到一个纯本地运行的基于浏览器访问的 Web 服务。它提供了可扩展、功能丰富、用户友好的自托管 AI Web 界面，支持各种大型语言模型（LLM）运行器，可以通过配置形式便捷的集成 ollama、OpenAI 等提供的 API。</p><p>通过 Open WebUI 可以实现聊天机器人、本地知识库、图像生成等丰富的大模型应用功能。</p><p>在开始之前，请确保你的系统已经安装了 docker。</p><p>接着拉取大语言模型 <code>deepseek-r1:8b</code> 和用于 RAG 构建本地知识库的嵌入模型 <code>bge-m3</code>：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>`ollama pull deepseek-r1:8b ollama pull bge-m3`</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后新建文件 <code>docker-compose.yml</code>，内容参考：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services:</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>open-webui:</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>image:ghcr.io/open-webui/open-webui:main</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>environment:</span></div></div><div><div><div>5</div></div><div><span><span>      </span></span><span>-OLLAMA_API_BASE_URL=http://ollama:11434/api</span></div></div><div><div><div>6</div></div><div><span><span>      </span></span><span>-HF_ENDPOINT=https://hf-mirror.com</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>-WEBUI_NAME="LZW的LLM服务"</span></div></div><div><div><div>8</div></div><div><span><span>      </span></span><span># 禁用 OPENAI API 的请求。若你的网络环境无法访问 openai，请务必设置该项为 false</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span># 否则在登录成功时，会因为同时请求了 openai 接口而导致白屏时间过长</span></div></div><div><div><div>10</div></div><div><span><span>      </span></span><span>-ENABLE_OPENAI_API=false</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span># 设置允许跨域请求服务的域名。* 表示允许所有域名</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>-CORS_ALLOW_ORIGIN=*</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span># 开启图片生成</span></div></div><div><div><div>14</div></div><div><span><span>      </span></span><span>-ENABLE_IMAGE_GENERATION=true</span></div></div><div><div><div>15</div></div><div><span><span>      </span></span><span># 默认模型</span></div></div><div><div><div>16</div></div><div><span><span>      </span></span><span>-DEFAULT_MODELS=deepseek-r1:8b</span></div></div><div><div><div>17</div></div><div><span><span>      </span></span><span># RAG 构建本地知识库使用的默认嵌入域名</span></div></div><div><div><div>18</div></div><div><span><span>      </span></span><span>-RAG_EMBEDDING_MODEL=bge-m3</span></div></div><div><div><div>19</div></div><div><span><span>    </span></span><span>ports:</span></div></div><div><div><div>20</div></div><div><span><span>      </span></span><span>-8080:8080</span></div></div><div><div><div>21</div></div><div><span><span>    </span></span><span>volumes:</span></div></div><div><div><div>22</div></div><div><span><span>      </span></span><span>-./open_webui_data:/app/backend/data</span></div></div><div><div><div>23</div></div><div><span><span>    </span></span><span>extra_hosts:</span></div></div><div><div><div>24</div></div><div><span><span>      </span></span><span># - host.docker.internal:host-gateway</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>这里需注意 <code>environment</code> 环境变量部分的自定义设置。许多设置也可以通过登录后在 web 界面进行修改。</p><p>在该目录下执行该命令以启动服务：<code>docker-compose up -d</code>。成功后即可通过浏览器访问：<code>http://localhost:8080</code>。</p><p>服务镜像更新参考：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 拉取新镜像</span></div></div><div><div><div>2</div></div><div><span>docker-compose pull</span></div></div><div><div><div>3</div></div><div><span># 重启服务</span></div></div><div><div><div>4</div></div><div><span>docker-compose up -d --remove-orphans</span></div></div><div><div><div>5</div></div><div><span># 清理镜像</span></div></div><div><div><div>6</div></div><div><span>docker image prune</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>• open-webui 详细文档参考：<a href="https://docs.openwebui.com/getting-started/env-configuration" target="_blank">https://docs.openwebui.com/getting-started/env-configuration</a></li>
</ul><p><strong>可选：开启“联网搜索”功能</strong></p><p>操作路径：<code>设置 - 联网搜索 - 启用联网搜索</code></p><p>当前已支持接入的联网搜索引擎中，在不需要魔法上网的情况下，有 bing 和 bocha 可以选择接入。基本只需要前往注册并获取 API KEY 回填到这里即可。如果需要保护隐私数据，请不要开启并配置该功能。</p><ul>
<li>• 博查文档：<a href="https://aq6ky2b8nql.feishu.cn/wiki/XgeXwsn7oiDEC0kH6O3cUKtknSR" target="_blank">https://aq6ky2b8nql.feishu.cn/wiki/XgeXwsn7oiDEC0kH6O3cUKtknSR</a></li>
</ul></section></section>
<section><h2>总结与参考<a href="#总结与参考"><span>#</span></a></h2><p>通过以上内容，我们了解了 ollama 在国内环境下的安装使用方法，并介绍了因为国内网络特色导致安装过程可能会遇到的常见问题及解决办法。希望这些内容对你有所帮助，如果你有任何问题或建议，欢迎在评论区留言交流。</p><ul>
<li>
<p>• ollama 官方站：<a href="https://ollama.com" target="_blank">https://ollama.com</a></p>
</li>
<li>
<p>• ollama 中文站：<a href="https://ollama.org.cn" target="_blank">https://ollama.org.cn</a></p>
</li>
<li>
<p>• ollama 入门：<a href="https://ollama.readthedocs.io/quickstart/" target="_blank">https://ollama.readthedocs.io/quickstart/</a></p>
</li>
<li>
<p>• ollama 常见问题：<a href="https://ollama.readthedocs.io/faq/" target="_blank">https://ollama.readthedocs.io/faq/</a></p>
</li>
<li>
<p>• 魔塔社区：<a href="https://modelscope.cn" target="_blank">https://modelscope.cn</a></p>
</li>
<li>
<p>• HF Mirror：<a href="https://hf-mirror.com" target="_blank">https://hf-mirror.com</a></p>
</li>
<li>
<p>• open-webui 文档：<a href="https://docs.openwebui.com" target="_blank">https://docs.openwebui.com</a></p>
</li>
</ul></section>
<section><h2>转载<a href="#转载"><span>#</span></a></h2><p>本文转载自<a href="https://mp.weixin.qq.com/s/1cbpf9IlLgg9NApk5322GA" target="_blank">志文工作室</a></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/81740974/</id>
      <title type="text">Dify应用实战(4) - 生成语音</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/81740974/"/>
      <summary type="text">本文演示Dify工作流语音生成能力：1. 集成SiliconCloud TTS节点实现文本转语音；2. 详解APIKey配置流程与声音类型选择（8种人声）；3.优化Python代码节点输出自然语言播报文案。通过工作流串联天气数据→文本处理→语音生成全流程，实现自动化语音播报功能，为有声内容创作提供标准化解决方案，并提示商用模型计费策略及本地调试方法。</summary>
      <content type="html"><![CDATA[<blockquote><p>我们继续AI学习之旅，今天教大家使用TTS节点，来生成语音播报的音频数据。</p><p>学习完成，你将掌握生成语音文件的方法，可以将自己的文字直接变为播客内容。</p></blockquote>
<section><h3>**01.**动手做一做<a href="#01动手做一做"><span>#</span></a></h3><blockquote><p>基于上一节课的流程，在”代码执行”节点之后，新增一个”Text To Speech”的节点。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/ff9aa392d78d443f92c9b3ca39b1898e640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>添加之后，连接”代码执行”节点和新增节点；再连接新增节点和结束节点。新增参数(一定要先连接)，“Text To Speech”的输入，选择”代码执行”的text。</p><p>TTS节点需要有模型，这里选择SiliconCloud的fish-speech-1.5。</p><p>硅基流动配置非常简单，直接点配置弹出对话框后，跟着”从SiliconFlow获取API Key”的向导，打开官网，注册后创建API Key，然后复制到Dify的配置框，即可。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/6510cdcd47f44a7d810e53ae3973b70f640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>新增模型之后，在”系统模型设置”的文本转语音模型，选中fishaudio。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/fbe176712fb2402ab0b22ffc610d58b0640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>同时新增节点，记得选择声音的类型，包括了4男4女的备选声音，可以都测试一下，看看是否满足自己的需要。</p><p>“结束”节点的输出改为”Text To Speech”的files（这里注意不要再选成text了）。</p><p>点击”发布”，保存。提示”操作成功”。就可以进行测试了。测试如下：</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/6a1c62bbe4094bb78f95504882c17bb5640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>结果输出是一个wav文件的下载链接，点击下载后，使用本地音频播放软件打开就可以检查内容。</p></blockquote></section>
<section><h3>02.补充说明<a href="#02补充说明"><span>#</span></a></h3><blockquote><p>今天的任务，非常简单，经过前几天的学习，应该操作起来很是得心应手了。</p><p>但注意一下，硅基流动的这个TTS模型是收费的，需要先充值才能使用，麦金叔充了10块钱。还有很多模型可以免费，或者限免使用。不过使用费用还算可以接受吧，测试了几次，花掉3分钱。同时新用户进来就赠送13.99，够用一段时间了。</p><p>当然，如果不想这么简单的实现，希望挑战一下自己的，麦金叔这里也有复杂的方案，点赞留言，确有需要，可以单独出一期。</p><p>另外，今天的”代码执行”节点，也做了一下脚本更新。直接将JSON，格式化输出为播报文案。</p></blockquote><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>def main(arg1: str) -&gt; dict:</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>import json</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>import datetime</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>today_date = datetime.date.today().strftime("%Y-%m-%d")</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>report = json.loads(arg1)</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>for index in range(0, len(report)):</span></div></div><div><div><div>7</div></div><div><span><span>        </span></span><span>weather = report[index]</span></div></div><div><div><div>8</div></div><div><span><span>        </span></span><span>if today_date == weather.get("date", ""):</span></div></div><div><div><div>9</div></div><div><span><span>            </span></span><span>day_weather = weather.get("dayweather", "")</span></div></div><div><div><div>10</div></div><div><span><span>            </span></span><span>day_temp = weather.get("daytemp_float", "")</span></div></div><div><div><div>11</div></div><div><span><span>            </span></span><span>night_weather = weather.get("nightweather", "")</span></div></div><div><div><div>12</div></div><div><span><span>            </span></span><span>night_temp = weather.get("nighttemp_float", "")</span></div></div><div><div><div>13</div></div><div><span><span>            </span></span><span>day_temp_f = float(day_temp)</span></div></div><div><div><div>14</div></div><div><span><span>            </span></span><span>day_temp_i = round(day_temp_f)</span></div></div><div><div><div>15</div></div><div><span><span>            </span></span><span>night_temp_f = float(night_temp)</span></div></div><div><div><div>16</div></div><div><span><span>            </span></span><span>night_temp_i = round(night_temp_f)</span></div></div><div><div><div>17</div></div><div><span><span>            </span></span><span>res = "今日天气，白天%s，温度%d摄氏度，晚上%s，气温%d摄氏度" % (day_weather, day_temp_i, night_weather, night_temp_i)</span></div></div><div><div><div>18</div></div><div><span><span>            </span></span><span>#today_weather = json.dumps(weather, ensure_ascii=False)</span></div></div><div><div><div>19</div></div><div><span><span>            </span></span><span>return { "result": res, }</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p><strong>总结</strong></p><blockquote><p>今天在上次的工作流基础上，进一步增加利用TTS来对获取内容进行语音生成处理，如果各位朋友有做播客的，那这一期就非常对你的胃口，操作也很简单。</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/877dcb03/</id>
      <title type="text">Dify应用实战(12) - 数据库查询</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/877dcb03/"/>
      <summary type="text">本文实战演示Dify数据库查询组件的集成应用。通过安装数据库插件→配置MySQL连接→编写眼科医生查询SQL→整合查询结果至对话流程，实现医疗分诊场景的精准医生推荐。详解数据库授权机制及查询结果格式化输出技巧，展示如何为AI应用注入实时数据支持，有效解决大模型幻觉问题，为挂号系统、知识库查询等需要数据验证的场景提供可靠解决方案。</summary>
      <content type="html"><![CDATA[<p>上一节Dify应用实战课，我们继续对新项目，智能医疗分诊助手，进行了分支条件的拆解。</p>
<p>今天我们学习数据库的查询操作。</p>
<p>学习完成，你将掌握如何对数据库中的数据进行获取。</p>
<section><h3>**01.**动手做一做<a href="#01动手做一做"><span>#</span></a></h3><p>今天的任务基于智能分诊应用”医小助”。在”条件分支”的”case1”后新增一个”SQL查询”节点。</p><p>但是，需要先准备一下插件的安装(v1.0.0之后，已经升级需要安装插件)。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/4ce20dd690a64856b4f964bd8cfd6863640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>插件安装之后，按下图所示进行添加，先点击”工具”，再找到刚才安装的”Database”，展开后选中”SQL Execute”。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/592beed7e610443aa0f985bc3ae024ea640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>第一次使用会让先授权，按下图步骤进行设置。直接点”去授权”，不用管下面的API端点。这个以后有需要再说。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/a001b74493a04a91bdb9e90be69966a7640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>授权之后，如果再用”数据库”工具，就不会再要求进行授权了。授权需要输入的内容如下：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>mysql+pymysql://</span><span>root</span><span>:</span><span>123456</span><span><span>@192</span><span>.</span></span><span>168</span><span>.</span><span>0</span><span>.</span><span>101</span><span>:</span><span>3306</span><span>/hospital</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果用的postgresql或者sqlite，就查询一下插件的说明文档即可。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/457ed9e675fa4fd59b2e947bf0ee8a38640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>现在我们就可以填入查询SQL语句了</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>SELECT</span><span> </span><span>name</span><span>, title, </span><span>description</span><span> </span><span>FROM</span><span> doctor </span><span>WHERE</span><span><span> department </span><span>=</span><span> </span></span><span>'眼科'</span><span> </span><span>and</span><span> </span><span>status</span><span><span> </span><span>=</span><span> </span></span><span>1</span><span>;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>输出暂时按”Markdown”内容输出。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/f488972ac81f4b1e95a146e8623af07c640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>将后一个回复节点的输出，添加SQL查询的结果，如下图。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/52f3985b303241e28b63f1d89715d211640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>保存之后，我们进行测试，如下：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/e46c55f052794b55b4e693fb65c50e14640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>可以看到，如果走到”眼科分支，且与近视有关”，那么会获得数据库内查询出来的内容。</p><p>希望今天的动手实践，也能跟着麦金叔做下来。</p></section>
<section><h3>**02.**补充说明<a href="#02补充说明"><span>#</span></a></h3><p>今天学的数据库查询，对于普通人来说有点难度。</p><p>但AI应用的开发，一定是围绕大模型之后，再精细补充细节。</p><p>数据库的操作是AI前时代，数字化或者信息化过程中的重要一环。任何与软件，互联网等相关的开发，必然是不可能缺失数据库的。</p><p>与其将话语权交给别人，还不如也顺手把SQL查询学一学。这样我们的AI应用必将有血有肉，落地不再是空中楼阁。</p></section>
<section><h3><strong>总结</strong><a href="#总结"><span>#</span></a></h3><p>今天学习一个新的组件”数据库查询”。有了它在AI应用开发的”拖线条”过程中，真正做到不再”说大话”，不会”胡编乱造”。但是，要使用它，门槛稍微高了那么一点点。除了需要有基础的数据库运维，最重要的还需要你能稍微了解一下SQL，有对数据操作的能力。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/87959abc/</id>
      <title type="text">Dify应用实战(17) - 使用MCP服务</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/87959abc/"/>
      <summary type="text">本文实战演示Dify集成MCP服务的全流程。通过mcp-proxy搭建代理服务→配置SSE插件→部署支持MCP的Agent节点，实现对接MySQL等第三方服务。详解Docker容器化部署及服务授权机制，展示如何突破服务端限制调用本地工具，为智能客服、数据分析等场景提供跨系统集成方案，较传统API对接效率提升50%。</summary>
      <content type="html"><![CDATA[<p>今天我们将要继续企业应用之旅，让Dify变成一个超级中间站，能将开源的大几千MCP服务为我所用。</p>
<p>学习完成，你将会让自己的Dify也拥有更专业的使用MCP的能力。</p>
<section><h3>**01.**准备环节<a href="#01准备环节"><span>#</span></a></h3><p>我们之前详细学习了MCP所有关键的内容，是时候来表演了。</p><p>不过Dify是一个服务端运行的系统，它不像本地可以为MCP服务去准备运行环境。如果让Dify集成stdio方式的MCP，那改动就有点大了。</p><p>但是现存海量的MCP服务，绝大多数都是stdio方式，所以关键一点就是打通这个使用方式上的差异。</p><p>因此使用一个叫mcp-proxy的工具，就来的如此的顺理成章。(如果听不懂stdio的话，请复习前面的博文)</p><p><a href="https://mp.weixin.qq.com/s?__biz=MzAxNjQxMTQ3NA==&amp;mid=2452385457&amp;idx=1&amp;sn=3cc0165bad65a8d13b2bb82df2ba3327&amp;scene=21#wechat_redirect" target="_blank">大模型的得力干将MCP(5)  - 应用场景和发展方向，窥探先机，不容错过</a></p><p>为了不影响本地电脑的环境配置等，我们同样以容器的方式，去运行这个mcp-proxy。</p><p>根据它的说明文档，有两个地方需要修改为自己的。</p><ol>
<li>重新打包一下镜像，加入uv运行环境。新建一个mcp-proxy.Dockerfile文件，内容如下：</li>
</ol><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/4fd20611c7414d79a0cf1ecb6b21e241640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>2.以上述镜像，加入需要代理的MCP服务，我们以mysql_mcp_server为例。新建一个docker-compose.yml文件，内容如下：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/88b34cd0a4b14d4d911ed6bcf6139bff640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>现在启动docker compose up -d，去容器中看到输出log如下，就说明成功了。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/c652e363203c4f6ab0215a6d74858846640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>上述步骤完成，给我们干活的MCP服务就搭好了，接着开始操作Dify。</p><p>有两个插件需要准备好。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/ecbfca8ac7024e2996c1e833f737e43e640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>如果你在插件市场看到他们的版本低于0.0.8，请去插件介绍的github上手动下载，然后通过本地插件的方式去安装。</p><p>如果你还没有这么快要去尝试，也不用主动升级，说不定你要用的时候已经有插件市场的0.0.8版本了。（一定要听劝，不要乱尝试）</p><p>至此，所有今天需要的准备就完成了，恭喜！</p></section>
<section><h3>**02.**动手做一做<a href="#02动手做一做"><span>#</span></a></h3><p>今天为了演示，新建一个chatflow，把所有其他的干扰因素都排除。</p><p>在开始节点之后新增一个节点”Agent”。</p><p><strong>第一步</strong>需要指定AGENT策略，点下拉箭头会出现”支持MCP工具的Agent”，点击之后会再展开，选择”FunctionCalling(Support MCP tools)”</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/9959d22bfdb84ab6a4799fed61765dca640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>此时才开始正式配置相关参数。</p><p><strong>第二步</strong>，模型这里选择支持FunctionCall的大模型，如qwen2.5。</p><p><strong>第三步</strong>，工具列表这里点加号，把”通过SSE发现和调用MCP”里面包含的两个工具都加上</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/57acf79857ed4774912ced9546dac611640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>如果是第一次配置这个工具，它会问你要授权，填入刚才docker提供MCP Proxy的服务地址和端口</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{"mysql_mcp": {"url": "http://192.168.0.231:8066/sse","headers": {}, "timeout": 50, "sse_read_timeout": 300}}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>保存时没有报错，说明就成功了。</p><p><strong>第四步</strong>，MCP 服务配置的框内填入提供MCPProxy的地址，如下</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"mysql_mcp"</span><span>: {</span></div></div><div><div><div>3</div></div><div><span>    </span><span>"url"</span><span>: </span><span>"http://192.168.0.231:8066/sse"</span><span>,</span></div></div><div><div><div>4</div></div><div><span>    </span><span>"headers"</span><span>: {},</span></div></div><div><div><div>5</div></div><div><span>    </span><span>"timeout"</span><span>: </span><span>50</span><span>,</span></div></div><div><div><div>6</div></div><div><span>    </span><span>"sse_read_timeout"</span><span>: </span><span>300</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>8</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/968cfbd54337407c9ded3e939fbef5dd640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>最后把剩余的，指令，查询和最大迭代次数修改完就OK了，见上图。</p><p>见证奇迹的时刻到来了。我们进行测试，结果如下：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/faefb248b5b24aaab2f5b974a45d1abd640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>除了运行时间长点，没毛病。本地测试环境，大模型运行效率不高。嘿嘿！</p><p><strong>总结</strong></p><p>今天学习了将MCP服务引入Dify系统，从而打通了大模型与更强大扩展工具之间的联系。你的Dify应用将会有更多更好的能力做出更酷的事情来。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/8e3cb690/</id>
      <title type="text">Dify应用实战(13) - 工具调用</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/8e3cb690/"/>
      <summary type="text">本文实战演示Dify的Function Calling功能实现。通过创建Agent节点→集成时间/天气查询工具→配置结构化参数提示词，实现大模型对实时数据的动态调用。详解工具授权机制及JSON参数规范，展示如何通过工具调用扩展模型能力，为智能问答、数据查询等需要实时交互的场景提供解决方案，同步解析模型适配要点及调试方法论。</summary>
      <content type="html"><![CDATA[<p>今天我们学习大语言模型的Function Calling的使用。</p>
<p>学习完成，你将初步获得调用工具的能力。本节内容，非常考察动手能力，建议需要反复调试，并理解大语言模型的基础能力知识。</p>
<section><h3>**01.**动手做一做<a href="#01动手做一做"><span>#</span></a></h3><p>今天的任务需要重开一个对话应用。当条件成熟之后，才能将今日所学集成进之前的AI应用开发中。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/c1e0880bccb1497bb87e6d74bf1dcbd9640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>将默认生成的3个节点中的第2个删除。并添加”Agent”节点。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/db5b92f83952430db52571888eb1492d640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>接着对该节点做配置，按下图步骤进行设置。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/8f1ae7d5466f43a983eaebbfc70b067a640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>选择完Function Callinging之后，就会出现真实的配置。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/ee06b654d1f0445487b039acd0a74505640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>首先需要手动选择一个配置的大语言模型。这里需要注意，不是所有的大模型都内在支持Function Calling，所以这就要求我们对大模型基础有一定的了解。比方说这一段时间非常热门的DeepSeek模型，就并没有支持Function Calling。</p><p>然后添加大模型调用的工具。这里添加了时间获取和查询天气这两个工具。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/8401993bd9824a258ae834d241a59548640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/2739cb071ee8456d94339936824433d3640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>“指令”输入框中添加如下内容：</p></blockquote><p>如果用户问到天气问题，你可以使用工具来帮你完成任务。</p><p>1. 根据城市和日期查询天气，使用时必须提供城市和日期两个参数，提供参数的方式要满足如下结构：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>   </span></span><span>"name":"get_weather",</span></div></div><div><div><div>4</div></div><div><span><span>   </span></span><span>"arguments": {</span></div></div><div><div><div>5</div></div><div><span><span>     </span></span><span>"city": 查询的城市</span></div></div><div><div><div>6</div></div><div><span><span>     </span></span><span>"date": 查询的日期</span></div></div><div><div><div>7</div></div><div><span><span>   </span></span><span>}</span></div></div><div><div><div>8</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>2. 根据用户的描述，比如，“今天”，“明天”，“昨天”，“下周一”，获取实际日期，使用时，必须提供用户对于日期的描述这个参数，提供参数的方式要满足如下结构：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>   </span><span>"name"</span><span>: </span><span>"time"</span><span>,</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>    </span><span>"arguments"</span><span>: {</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>     </span><span>"query"</span><span>: </span><span>用户对日期的描述</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span><span>   </span></span><span>}</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>而”查询”输入框，可以直接用”输入节点”的用户输入。如下图所示：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/d2d468511d88407b9485afe5f346dfb1640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>最后将”Agent节点”，与”回复节点”连接，输出修改为Agent的TEXT。保存之后，我们进行测试，如下：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/0e68c36c7d5544da83d6766e4141dca3640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>如果你动手做完了，测试的时候并没有得到跟麦金叔的结果一样的内容，那说明你的操作并没有问题，只是细节需要进一步打磨。</p><p>这也是今天的内容设置为”高级”的原因。接着，试着自己去调用不同的大模型，修改提示词。然后查看运行日志，以得到当中的各个步骤符合预期。</p></section>
<section><h3>**02.**补充说明<a href="#02补充说明"><span>#</span></a></h3><p>今天学的Agent，对于普通人来说非常有难度。</p><p>需要自行补充有关大模型的基础能力的知识。</p><section><h4>什么是Function Calling<a href="#什么是function-calling"><span>#</span></a></h4><p>大语言模型的Function Calling能力允许模型调用外部函数或服务，以扩展其自身的能力，执行它本身无法完成的任务。以下是一些Function Calling的使用场景：</p>

<table><thead><tr><th><strong>使用场景</strong></th><th>说明</th></tr></thead><tbody><tr><td>增强能力</td><td>大模型通过Function Calling可以调用外部工具或服务，例如实时数据检索、文件处理、数据库查询等，从而扩展其能力。</td></tr><tr><td>实时数据访问</td><td>由于大模型通常基于静态数据集训练，不具备实时信息。Function Calling允许模型访问最新的数据，提供更准确、更及时的回答。</td></tr><tr><td>提高准确性</td><td>在需要精确计算或特定领域知识时，大模型可以通过调用专门的函数来提高回答的准确性，例如调用数学计算函数、翻译服务或专业知识库。</td></tr></tbody></table><p>虽然有上述能力扩展，但是它不像工作流那般定义清晰。这种隐式的调用，考验着AI应用开发者对于大模型的理解，并需要不断的迭代优化，才能最终获得期望的效果。</p><p><strong>总结</strong></p><p>今天学习一个新的组件”Agent”，并将工具模式设置为了”Function Calling”。有了它在AI应用开发中，能增强大模型的能力，可以对模型训练后发布之后的知识进行更新补充，不会再出现回答结果明显有时间断档的问题。</p><p>但是，这个能力又是一柄双刃剑。如果不了解其概念和知识，会发现很难驾驭它。</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/93fb0a7d/</id>
      <title type="text">再也不用跑照相馆了！这个免费AI工具让你在家就能制作专业证件照</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/93fb0a7d/"/>
      <summary type="text">前几天我要报名考试，需要一张蓝底证件照，但是外面下着大雨，根本不想出门。就在我急得团团转的时候，朋友给我推荐了一个叫 **HivisionIDPhotos** 的工具，简直救了我的命！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！我发现了一个拍证件照的神器！<a href="#朋友们我发现了一个拍证件照的神器"><span>#</span></a></h2><p>你们有没有过这样的经历？</p><p>突然需要一张证件照，但是没时间去照相馆，或者觉得照相馆拍的不好看，又贵又麻烦。</p><p>前几天我要报名考试，需要一张蓝底证件照，但是外面下着大雨，根本不想出门。就在我急得团团转的时候，朋友给我推荐了一个叫 <strong>HivisionIDPhotos</strong> 的工具，简直救了我的命！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/2df307aa092e441e92407a01a8d4c85620260327094618692.png" alt="" /></p></section>
<section><h2>什么是 HivisionIDPhotos？<a href="#什么是-hivisionidphotos"><span>#</span></a></h2><p>说直白点，HivisionIDPhotos 就是一个用 AI 做证件照的工具，你只需要上传一张自己的照片，它就能自动帮你抠图、换背景、调整尺寸，生成各种规格的证件照，甚至还能美颜！</p><p>最棒的是，它可以完全离线运行，不用把照片上传到网上，超级安全！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/fc8ef528a53746bb9afca0ee99eba44c20260327094654698.png" alt="" /></p></section>
<section><h2>为什么我这么喜欢 HivisionIDPhotos？<a href="#为什么我这么喜欢-hivisionidphotos"><span>#</span></a></h2><section><h3>1️⃣ 在家就能做，不用跑照相馆<a href="#1️⃣-在家就能做不用跑照相馆"><span>#</span></a></h3><p>以前拍证件照，我都要专门抽时间去照相馆，排队等半天，拍出来的照片还不一定满意。现在好了，有了 HivisionIDPhotos，我在家用手机拍一张照片，上传进去，几分钟就能生成专业的证件照，太方便了！</p></section><section><h3>2️⃣ 功能超级全<a href="#2️⃣-功能超级全"><span>#</span></a></h3><p>这个工具能做的事情可多了：</p><ul>
<li><strong>自动抠图</strong>：不管你穿什么衣服，背景多复杂，都能精准把人抠出来</li>
<li><strong>换背景</strong>：支持红、蓝、白等各种底色，还能自定义颜色</li>
<li><strong>调整尺寸</strong>：支持各种证件照尺寸，比如一寸、二寸、护照照等</li>
<li><strong>排版打印</strong>：可以生成六寸、五寸、A4等排版照，方便打印</li>
<li><strong>美颜</strong>：自带美颜功能，让你看起来更精神</li>
<li><strong>离线运行</strong>：所有处理都在本地完成，不用联网，保护隐私</li>
</ul><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/e6287886e42e4830b9a2ce74df7fedf220260327112532646.png" alt="" /></p></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>前几天我用 HivisionIDPhotos 做了一张证件照，过程超级简单：</p><ol>
<li>用手机对着白墙拍了一张照片</li>
<li>打开 HivisionIDPhotos 的网页</li>
<li>上传照片，选择一寸尺寸，蓝色背景</li>
<li>点击生成，等待几秒钟</li>
<li>下载生成的证件照</li>
</ol><p>结果出来的照片超级专业，背景干净，人像清晰，比我在照相馆拍的还好看！</p><p>后来我还试了生成六寸排版照，打印出来刚好可以裁成8张一寸照片，省钱又方便。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/15a7a58eefd149238d4c7dc6273d065920260327134007768.png" alt="" /></p></section>
<section><h2>怎么开始使用？<a href="#怎么开始使用"><span>#</span></a></h2><section><h3>Docker 部署<a href="#docker-部署"><span>#</span></a></h3><p>创建一个 <code>docker-compose.yml</code> 文件，内容如下：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>hivision_idphotos</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image</span><span>: </span><span>linzeyi/hivision_idphotos:latest</span></div></div><div><div><div>4</div></div><div><span>    </span><span>container_name</span><span>: </span><span>hivision_idphotos</span></div></div><div><div><div>5</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>6</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>"7861:7861"</span></div></div><div><div><div>8</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>- </span><span>DEFAULT_LANG=zh</span></div></div><div><div><div>10</div></div><div><span>    </span><span>command</span><span>: </span><span>python3 -u app.py --host 0.0.0.0 --port 7861</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后在文件所在目录运行：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker-compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>关于模型文件<a href="#关于模型文件"><span>#</span></a></h3><p>HivisionIDPhotos 需要使用一些 AI 模型来实现抠图、人脸检测等功能，主要包括：</p><ul>
<li><strong>抠图模型</strong>：MODNet、hivision_modnet、rmbg-1.4、birefnet-v1-lite</li>
<li><strong>人脸检测模型</strong>：MTCNN、RetinaFace、Face++（在线）</li>
</ul><section><h4>模型文件说明<a href="#模型文件说明"><span>#</span></a></h4><ul>
<li><strong>使用官方 Docker 镜像</strong>：官方提供的 Docker 镜像已经内置了所需的模型文件，所以不需要单独下载模型</li>
<li><strong>本地部署</strong>：如果选择本地部署，则需要通过以下命令下载模型：
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>python</span><span> </span><span>scripts/download_model.py</span><span> </span><span>--models</span><span> </span><span>all</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
下载的模型会保存在项目的 <code>hivision/creator/weights</code> 目录中</li>
</ul></section><section><h4>模型选择<a href="#模型选择"><span>#</span></a></h4><p>HivisionIDPhotos 支持多种模型组合，不同模型的性能和效果有所不同：</p><ul>
<li><strong>MODNet + MTCNN</strong>：内存占用小（约410MB），推理速度快（约0.2秒），适合配置较低的设备</li>
<li><strong>birefnet-v1-lite + RetinaFace</strong>：内存占用较大（约6.2GB），推理速度较慢（约7秒），但分割精度更高</li>
</ul><p>你可以根据自己设备的配置选择合适的模型组合。</p></section></section></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>学生党</strong>：经常需要各种证件照，又不想花钱去照相馆</li>
<li><strong>上班族</strong>：需要证件照但没时间去照相馆</li>
<li><strong>自由职业者</strong>：经常需要更新证件照</li>
<li><strong>任何人</strong>：突然需要证件照应急</li>
</ul></section>
<section><h2>其他有趣的应用<a href="#其他有趣的应用"><span>#</span></a></h2><p>HivisionIDPhotos 还有一些社区开发的应用：</p><ul>
<li><strong>微信小程序</strong>：直接在微信里使用</li>
<li><strong>ComfyUI 工作流</strong>：和其他 AI 工具结合使用</li>
<li><strong>Windows 客户端</strong>：在电脑上更方便地使用</li>
<li><strong>群晖/飞牛 NAS 部署</strong>：在 NAS 上运行，全家人都能用</li>
</ul></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>HivisionIDPhotos 真的是一个超级实用的工具，它让拍证件照变得简单又省钱，不用再跑照相馆，在家就能做出专业的证件照。</p><p>如果你也经常需要证件照，或者不想为了一张证件照专门跑照相馆，一定要试试这个工具！</p></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><ul>
<li><strong>GitHub 仓库</strong>：<a href="https://github.com/Zeyi-Lin/HivisionIDPhotos" target="_blank">https://github.com/Zeyi-Lin/HivisionIDPhotos</a></li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时拍证件照都遇到过什么麻烦？用了 HivisionIDPhotos 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果觉得这篇文章有用，别忘了点赞、在看并分享给身边需要证件照的朋友们～</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/o1XazL7IFzpJXyL0QqKYBw?token=992197223&amp;lang=zh_CN" target="_blank">发现免费在线PS替代品！Photopea让你不用安装软件也能专业修图</a></li>
<li><a href="https://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=992197223&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/9854d049/</id>
      <title type="text">Dify应用实战(2) - 联网工具</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/9854d049/"/>
      <summary type="text">本文演示Dify工作流扩展能力：1. 在知识库检索流程后新增高德天气API节点，实现adcode到实时天气转换；2. 详解工具节点参数配置（输入绑定LLM输出/输出映射最终结果）；3. 介绍自定义工具开发框架（继承BuiltinTool类实现业务逻辑封装）。通过外部API集成突破大模型实时数据局限，为构建天气预报、金融数据等场景应用提供标准范式，展现Dify工作流编排的扩展性与实用性。</summary>
      <content type="html"><![CDATA[<section><h3>前言<a href="#前言"><span>#</span></a></h3><blockquote><p>让大家知道如何通过知识库的能力，获取指定的结果。这在很多的应用场景是非常有用的能力。</p><p>比如依赖有大量规则文档的行业，就会大大减少查找核对的工作。经常看到律师朋友，医生朋友发朋友圈说，AI不行啊，老是”胡说八道”，出现幻觉。</p><p>这其实是高估了大语言模型的能力，即使是垂直领域做过SFT，也不可能精确的回答准真正匹配规则的内容。并且微调训练成本也不低，不可能随时更新语料（标注数据）。通过RAG的方法，就可以在特定场景下，严格通过给出的文档内的规则，给出结果。</p></blockquote></section>
<section><h3>01. 动手做一做<a href="#01-动手做一做"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>基于上一节课的流程，在大模型节点后新增一个工具节点，选择搜索"天气"，点中"高德天气预报"。</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>选择这个主要是前面知识库的地区名和code对照表，就是高德的。另外这个接口也比较简单，输入就是一个adcode，输出就是今天该地区的天气结果。</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/f46b7789b8b04d10b9369232d334b5f1640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>添加之后，连接LLM节点和新增节点，再连接新增节点和结束节点。修改参数(一定要先连接)，"天气预报"的输入，选择"LLM"的text。然后把结束节点的输出也改为"天气预报"的text。</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>点击"发布"，保存。提示"操作成功"。就可以进行测试了。测试如下：</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/d6243ecb8edf4fc9b78d67b5ce350584640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h3>02. 工具使用与开发<a href="#02-工具使用与开发"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>一个正常应用的流程，其实都是非常复杂的。都需要经历很多步的操作，才能最终完成一项任务。</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>对于除大模型以外的工作，都需要工具进行配合。比如，大模型不可能直接得到今天某地的天气结果，需要通过API实时查询才行。那么通过LLM和天气预报工具进行结合，便实现了整个过程。</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>今天的任务，有现成的工具能使用。但是如果没有现有的工具，或者现有工具无法满足需求，就需要进行定制化开发。</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>基于Dify良好的设计，真要增加插件功能，还不算太难。不过这不是这一篇的重点，大概介绍一下吧。如果有兴趣，后面可以详谈。</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>通过扩展BuiltinTool类，将处理逻辑封装进"invoke tools"。最后返回create\_text\_message对象，包含处理后的数据或者异常信息，即可。</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/1f6e5a4705524060adf02a26137a6425640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h3><strong>总结</strong><a href="#总结"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>今天在上次的工作流基础上，进一步增加外部工具获取数据的过程。并简单了解，实现类似功能的方法。为今后自己实际业务的开发奠定基础。</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/9a18e38c/</id>
      <title type="text">大模型的得力干将MCP(2) - 开发服务</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/9a18e38c/"/>
      <summary type="text">本文实战演示MCP服务端开发全流程。基于TypeScript SDK构建高德天气查询工具→配置Stdio/SSE双模通信→实现API密钥管理与HTTP请求封装。详解服务注册及协议适配技巧，展示如何通过Cursor助手工具验证服务调用，为AI助手生态提供标准化能力扩展方案，较传统插件开发效率提升3倍。</summary>
      <content type="html"><![CDATA[<p>今天我们将继续学习，基于model context protocol的SDK来开发自己的MCP服务。</p>
<p>等系列课学习完成，你将能了解什么是MCP，如何开发MCP和如何实际使用它（当然我们会回归到Dify中，配合LLM，更加完善我们的AI应用适用场景）。</p>
<section><h3>**01.**动手准备<a href="#01动手准备"><span>#</span></a></h3><p>今天就来展开说说开发MCP应用，应该如何做。既然是开发，那就离不开代码了。处理的顺序正好和概念反过来，我们先来实现一个MCP服务端。</p><p>同时需要理解两个重要的概念：</p><section><h4><strong>1 通信机制</strong><a href="#1-通信机制"><span>#</span></a></h4><p>MCP协议支持两种主要的通信机制：基于标准输入输出的本地通信和基于SSE(Server-Sent Events)的远程通信。</p><p>也就是说MCP服务端，根据和客户端连接时所在的位置不同，分成本地通信和远程通信。</p><p>本地通信是通过stdio传输数据，即数据是本地机器的进程间通信。适合AI助手工具等软件使用。</p><p>而远程通信则是利用SSE技术，通过HTTP来通信和传输数据。适合于共享MCP服务，在企业内使用或者服务给互联网用户。</p></section><section><h4><strong>2 运行语言和环境</strong><a href="#2-运行语言和环境"><span>#</span></a></h4><p>一般涉及到开发，必定是要和开发语言有关。但是MCP协议是和语言无关的，也就是说大家可以尽量使用自己熟悉的开发语言。</p><p>Anthropic提供了TypeScript SDK，Python SDK，Java SDK，C# SDK，甚至Swift SDK和Rust SDK。也就是说基本上任何语言都可以实现MCP服务。</p><p>为了降低难度，我们不用挑战从零开始，用全新的语言做开发，就从typescript-sdk开始吧。</p></section></section>
<section><h3>**02.**动手做一做<a href="#02动手做一做"><span>#</span></a></h3><p>创建一个空的npm项目</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>npm init</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>输入如下信息</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/a63b595f107046c396e78fc2b7841660640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>修改package.json文件，增加依赖包和运行脚本。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/f2343546f9714ccdbd9d0c8b7cb0247a640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>创建一个src目录并添加一个index.ts文件。内容如下，并替换自己的高德密钥。</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";</span></div></div><div><div><div>2</div></div><div><span>import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";</span></div></div><div><div><div>3</div></div><div><span>import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";</span></div></div><div><div><div>4</div></div><div><span>import { z } from "zod";</span></div></div><div><div><div>5</div></div><div><span>import https from 'https';</span></div></div><div><div><div>6</div></div><div><span>// 环境变量中的API密钥</span></div></div><div><div><div>7</div></div><div><span>const GAODE_API_KEY = process.env.GAODE_API_KEY? process.env.GAODE_API_KEY: "高德密钥";</span></div></div><div><div><div>8</div></div><div><span>// 通用HTTP请求函数</span></div></div><div><div><div>9</div></div><div><span>async function makeRequest(url: string): Promise&lt;any&gt; {</span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>return new Promise((resolve, reject) =&gt; {</span></div></div><div><div><div>11</div></div><div><span><span>    </span></span><span>https.get(url, (res) =&gt; {</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>let data = '';</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span>res.on('data', (chunk) =&gt; {</span></div></div><div><div><div>14</div></div><div><span><span>        </span></span><span>data += chunk;</span></div></div><div><div><div>15</div></div><div><span><span>      </span></span><span>});</span></div></div><div><div><div>16</div></div><div><span><span>      </span></span><span>res.on('end', () =&gt; {</span></div></div><div><div><div>17</div></div><div><span><span>        </span></span><span>try {</span></div></div><div><div><div>18</div></div><div><span><span>          </span></span><span>resolve(JSON.parse(data));</span></div></div><div><div><div>19</div></div><div><span><span>        </span></span><span>} catch (e) {</span></div></div><div><div><div>20</div></div><div><span><span>          </span></span><span>reject(e);</span></div></div><div><div><div>21</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>22</div></div><div><span><span>      </span></span><span>});</span></div></div><div><div><div>23</div></div><div><span><span>    </span></span><span>}).on('error', (err) =&gt; {</span></div></div><div><div><div>24</div></div><div><span><span>      </span></span><span>reject(err);</span></div></div><div><div><div>25</div></div><div><span><span>    </span></span><span>});</span></div></div><div><div><div>26</div></div><div><span><span>  </span></span><span>});</span></div></div><div><div><div>27</div></div><div><span>}</span></div></div><div><div><div>28</div></div><div><span>// 创建MCP服务器</span></div></div><div><div><div>29</div></div><div><span>const server = new McpServer({</span></div></div><div><div><div>30</div></div><div><span><span>  </span></span><span>name: "gaode-weather-mcp",</span></div></div><div><div><div>31</div></div><div><span><span>  </span></span><span>version: "0.0.1"</span></div></div><div><div><div>32</div></div><div><span>});</span></div></div><div><div><div>33</div></div><div><span>// 实现天气查询</span></div></div><div><div><div>34</div></div><div><span>server.tool("getWeather",</span></div></div><div><div><div>35</div></div><div><span><span>  </span></span><span>{</span></div></div><div><div><div>36</div></div><div><span><span>    </span></span><span>city: z.string().describe("城市编码"),</span></div></div><div><div><div>37</div></div><div><span><span>    </span></span><span>extensions: z.enum(["base", "all"]).optional().describe("气象类型：base(实况天气)、all(预报天气)")</span></div></div><div><div><div>38</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>39</div></div><div><span><span>  </span></span><span>async (params) =&gt; {</span></div></div><div><div><div>40</div></div><div><span><span>    </span></span><span>if (!GAODE_API_KEY) {</span></div></div><div><div><div>41</div></div><div><span><span>      </span></span><span>throw new Error("高德地图API密钥未设置");</span></div></div><div><div><div>42</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>43</div></div><div><span><span>    </span></span><span>const { city, extensions = "all" } = params;</span></div></div><div><div><div>44</div></div><div><span><span>    </span></span><span>const url = `https://restapi.amap.com/v3/weather/weatherInfo?key=${GAODE_API_KEY}&amp;city=${encodeURIComponent(city)}&amp;extensions=${extensions}&amp;output=json`;</span></div></div><div><div><div>45</div></div><div><span><span>    </span></span><span>const result = await makeRequest(url);</span></div></div><div><div><div>46</div></div><div><span><span>    </span></span><span>return {</span></div></div><div><div><div>47</div></div><div><span><span>      </span></span><span>content: [{ type: "text", text: JSON.stringify(result) }]</span></div></div><div><div><div>48</div></div><div><span><span>    </span></span><span>};</span></div></div><div><div><div>49</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>50</div></div><div><span>);</span></div></div><div><div><div>51</div></div><div>
</div></div><div><div><div>52</div></div><div><span>// 启动服务器</span></div></div><div><div><div>53</div></div><div><span>async function main() {</span></div></div><div><div><div>54</div></div><div><span><span>  </span></span><span>const transport = new StdioServerTransport();</span></div></div><div><div><div>55</div></div><div><span><span>  </span></span><span>//const transport = new SSEServerTransport();</span></div></div><div><div><div>56</div></div><div><span><span>  </span></span><span>await server.connect(transport);</span></div></div><div><div><div>57</div></div><div><span><span>  </span></span><span>console.log("高德地图MCP服务已启动");</span></div></div><div><div><div>58</div></div><div><span><span>  </span></span><span>// 保持运行</span></div></div><div><div><div>59</div></div><div><span><span>  </span></span><span>await new Promise(() =&gt; { });</span></div></div><div><div><div>60</div></div><div><span>}</span></div></div><div><div><div>61</div></div><div>
</div></div><div><div><div>62</div></div><div><span>main().catch(console.error);</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>这时在终端执行npm run build，会在src目录下编译生成index.js文件，这个就是MCP服务端代码了。</p><p>如果上一篇教程正常跑通，那这里就简单了，依葫芦画瓢。在Cursor的设置，添加一个新的MCP服务，或者通过.cursor/mcp.json增加。如下图：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/3021bd305bec458aac6e223033b0d366640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>测试一下是否工作正常。切换到Agent模式，然后输入问题：“请问虹口区310109的天气怎么样？“。此时就会调用MCP tool getWeather，并得到正确的回答。<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/4180bf3fc824488f9d6e2b1a49ee4e23640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="" /></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/4180bf3fc824488f9d6e2b1a49ee4e23640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h3>**03.**补充说明<a href="#03补充说明"><span>#</span></a></h3><p>MCP因为概念还比较新，各方的实现也是五花八门。特别是针对不同的语言，不同的运行环境(指的是Windows，Mac OS或者Linux)，支持的不同客户端(实际上是主机，含客户端，像Claude，Cursor，IDE等各种助手类软件)，想要自己本地跑起来第一个成功的案例，需要克服种种困难。</p><p>但是，随着MCP概念的兴起，这些问题会逐步解决。以后使用起来也会更加的顺滑，同时也给广大的开发者，带了很多新的机会，早期介入都会有红利期。</p><p>麦金叔也是非常感谢读者粉丝们的热情支持，期望大家都能从这一系列的讲解中，得到一个清晰的认识。同时意识到，做这些的技术并非凭空出现的，比如node开发，SSE技术，实际上都已经是比较成熟的东西。但是嫁接到MCP上，又能焕发出第二春。</p><p>虽然当前的SSE应用在MCP架构上，也是有不同的声音，比如认证，单向通讯等问题限制了一定的使用场景。但如果一切都已经那么完美了，那参与开发的人也就没有发展的空间了，是不是呢？</p><p><strong>总结</strong></p><p>今天学习了第一个自动实现的MCP服务，高德天气查询的例子。理解最简单的MCP服务开发的方法。但是，还有更多的MCP的概念没有引入，后面的文章将继续探讨，敬请期待。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/9b437a3f/</id>
      <title type="text">Dify应用实战番外 - 网友提问(1)</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/9b437a3f/"/>
      <summary type="text">本文实战解答Dify工作流中SQL生成难题。通过参数提取器节点清洗大模型输出→配置专用LLM模型→优化SQL执行流程，解决AI生成语句格式不规范问题。详解Prompt工程技巧及模型选型策略，展示如何将自然语言查询转化为可执行数据库操作，为数据报表、业务分析等场景提供零代码解决方案，较传统开发方式效率提升80%。</summary>
      <content type="html"><![CDATA[<p>这两天有网友问，上次的课提到了数据库查询，对一般的人还是有点难度。所以希望大模型也能生成SQL，可以自己去查询数据库的数据。</p>
<p>麦金叔建议他使用文生SQL的模型，网友应该真的去尝试了，只不过还是有问题。那今天麦金叔就来演示一下，如何处理这一需求，并解决查询报错的问题。</p>
<section><h3>**01.**动手做一做<a href="#01动手做一做"><span>#</span></a></h3><p>今天的任务专题是解决让大模型生成SQL查询语句，并利用数据库工具查询得到结果。</p><p>依然用工作流作为测试。添加下图所示节点，依次为”开始”，“LLM”，“参数提取器”，“SQL EXECUTE”和”结束”。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/32b23b4166d441c0b2e0ce20516c1ff2640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>将”开始”节点，添加一个参数”user_promt”。这样在对话时，可以将查询要求填入。</p><p>“LLM”节点选择模型为”qwen2.5-72b-instruct”，上下文选择”开始”节点新增的参数”user_promt”，将系统提示词按如下填入：</p><p>请直接提供答案，无需解释思考过程。</p><p>根据用户输入 上下文</p><p>进行SQL的生成，最终结果仅包含SQL语句。</p><p>数据库的schema如下：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>CREATE</span><span> </span><span>TABLE</span><span> `</span><span>doctor</span><span>` (</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span> </span><span>`id`</span><span> </span><span>int</span><span>(</span><span>11</span><span>) </span><span>NOT NULL</span><span>,</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span> </span><span>`name`</span><span> </span><span>varchar</span><span>(</span><span>255</span><span>) </span><span>COLLATE</span><span> utf8mb4_bin </span><span>DEFAULT</span><span> </span><span>NULL</span><span>,</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span> </span><span>`title`</span><span> </span><span>varchar</span><span>(</span><span>255</span><span>) </span><span>COLLATE</span><span> utf8mb4_bin </span><span>DEFAULT</span><span> </span><span>NULL</span><span>,</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span> </span><span>`department`</span><span> </span><span>varchar</span><span>(</span><span>255</span><span>) </span><span>COLLATE</span><span> utf8mb4_bin </span><span>DEFAULT</span><span> </span><span>NULL</span><span>,</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span> </span><span>`description`</span><span> </span><span>text</span><span> </span><span>COLLATE</span><span> utf8mb4_bin,</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span> </span><span>`status`</span><span> </span><span>tinyint</span><span>(</span><span>2</span><span>) </span><span>DEFAULT</span><span> </span><span>NULL</span><span>,</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span> </span><span>PRIMARY KEY</span><span> (</span><span>`id`</span><span>),</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span> </span><span>KEY</span><span> </span><span>`dep`</span><span> (</span><span>`department`</span><span>) </span><span>USING</span><span> BTREE</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span><span>) ENGINE</span><span>=</span><span>InnoDB </span></span><span>DEFAULT</span><span><span> CHARSET</span><span>=</span><span>utf8mb4 </span></span><span>COLLATE</span><span><span>=</span><span>utf8mb4_bin;</span></span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>其中status为医生工作状态，1表示医生正常工作，0表示医生暂停诊治。</p><p>title为医生的职称，description为医生擅长领域。</p><p>接着在”参数提取器”节点配置模型为”qwen2.5-32b-Instruct”，输入选择上一个”LLM”节点的text。</p><p>新建一个提取参数”sql_query”，指令部分填入：</p><p>忽略大模型输出的思考过程，即不要提取部分</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/1c0083f2bf2240febaa38796b7bd3444640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>“SQL EXECUTE”节点，保持和12节课数据库查询一致，并在”结束”节点输出查询结果。</p><p>保存后进行测试，结果如下图：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/59dcef1676184d9caac09936a2cdad33640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h3>**02.**解释说明<a href="#02解释说明"><span>#</span></a></h3><p>首先，需要添加一个”参数提取器”。因为大模型文生SQL的结果会是这样的结果：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>  </span><span>"text"</span><span>: </span><span>"</span><span>\`\`\`</span><span>sql</span><span>\\</span><span>nSELECT name, title, description </span><span>\\</span><span>nFROM doctor </span><span>\\</span><span>nWHERE department = '眼科' AND status = 1;</span><span>\\</span><span>n</span><span>\`\`\`</span><span>"</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>可以看到text的内容，是以sql开头的。那如果直接去运行，肯定不行呀。SQL查询语句还是需要严谨的，否则无法执行数据库查询。</p><p>当然，如果使用其他方法，比如”代码”或者”模版”也可以的，但都比”参数提取器”复杂。</p><p>其次，模型的选择上，“LLM”最后不要使用带有COT的模型，因为这一类模型强大是强大，还输出了思考过程，但只是给人看友好。而在工作流里面，还要进一步处理它，比较麻烦。还是直接用输出结果，而不给出思考过程的，更适合工作流。</p><p>最后，本着够用就行的原则，对问题理解并生成结果的模型需要参数大一些的模型，但是参数提取这种工作，就没必要也用参数大的，可以适当减小。毕竟实际工作中，在效果一致的前提下，能省一点是一点。</p><p><strong>总结</strong></p><p>今天的答疑来自网友的留言问题，实际上学习AI应用开发，一定不能照本宣科。要不断地尝试，碰到问题，并解决它，才能学以致用，为工作中能用上AI的能力打下坚实的基础。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/9ca6325/</id>
      <title type="text">太爽了！这个免费工具让你的小说变成有声书，再也不用盯着屏幕看了</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/9ca6325/"/>
      <summary type="text">前几天我在网上发现了一个叫 **easyVoice** 的工具，简直打开了新世界的大门！它能把文本转换成语音，而且效果超级自然，就像真人在朗读一样。今天必须强烈安利给你们！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！我发现了一个听书神器！<a href="#朋友们我发现了一个听书神器"><span>#</span></a></h2><p>你们有没有过这样的经历？</p><p>想读小说，但是眼睛看久了不舒服；开车或运动的时候，想看书却腾不出手；或者只是想放松一下，闭着眼睛听点什么。</p><p>前几天我在网上发现了一个叫 <strong>easyVoice</strong> 的工具，简直打开了新世界的大门！它能把文本转换成语音，而且效果超级自然，就像真人在朗读一样。今天必须强烈安利给你们！</p></section>
<section><h2>什么是 easyVoice？<a href="#什么是-easyvoice"><span>#</span></a></h2><p>说直白点，easyVoice 就是一个开源的文本转语音工具，它能把文字内容转换成自然流畅的语音，让你可以用耳朵“阅读”，而不是用眼睛。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/fc2657cbdfd24576aa39e509dca37b3f20260327174224643.png" alt="" /></p></section>
<section><h2>为什么我这么喜欢 easyVoice？<a href="#为什么我这么喜欢-easyvoice"><span>#</span></a></h2><section><h3>1️⃣ 免费无限制，想转多少转多少<a href="#1️⃣-免费无限制想转多少转多少"><span>#</span></a></h3><p>最重要的是，easyVoice 完全免费，而且没有字数限制！不管你的文本有多长，都能一次性转换，不像有些工具只能转几百字就要收费。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/6cf8c0b4a43c496b9a658688f97ea70820260327174246834.png" alt="" /></p></section><section><h3>2️⃣ 多角色配音，听着更有趣<a href="#2️⃣-多角色配音听着更有趣"><span>#</span></a></h3><p>它支持多角色配音，比如小说里有不同的人物对话，它能给不同的角色分配不同的声音，听起来就像在听广播剧一样，超级有代入感！
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/03/e3a86b03ef0c4c49a760c22b1f9e11cb20260327174916473.png" alt="" /></p></section><section><h3>3️⃣ 效果自然，不像机器人<a href="#3️⃣-效果自然不像机器人"><span>#</span></a></h3><p>以前我也用过一些文本转语音工具，但是声音听起来很机械，没有感情。easyVoice 就不一样了，它的声音非常自然，有抑扬顿挫，就像真人在朗读一样。</p></section><section><h3>4️⃣ 可以部署在自己的设备上<a href="#4️⃣-可以部署在自己的设备上"><span>#</span></a></h3><p>如果你担心隐私问题，或者想随时随地使用，easyVoice 可以部署在自己的电脑、服务器或 NAS 上，所有数据都在本地，超级安全！</p></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>前几天我用 easyVoice 转换了一本我一直在追的小说，效果真的惊艳到我了：</p><ol>
<li>打开 easyVoice 的网页界面</li>
<li>复制粘贴小说内容</li>
<li>选择合适的声音和语速</li>
<li>点击转换按钮</li>
<li>等待几分钟，下载生成的音频文件</li>
</ol><p>结果生成的音频超级自然，我听了一个小时都不觉得累，而且还能边听边做其他事情，效率高了不少！</p><p>后来我还试了用它转换一些工作文档，在通勤路上听，既节省了时间，又保护了眼睛，简直一举两得！</p></section>
<section><h2>怎么开始使用？<a href="#怎么开始使用"><span>#</span></a></h2><section><h3>方法一：直接体验在线版本<a href="#方法一直接体验在线版本"><span>#</span></a></h3><p>如果你不想部署，也可以直接访问在线体验地址：<a href="https://easyvoice.ioplus.tech/" target="_blank">https://easyvoice.ioplus.tech/</a></p></section><section><h3>方法二：Docker 部署<a href="#方法二docker-部署"><span>#</span></a></h3><p>如果你想在自己的设备上部署，可以使用 Docker：</p><ol>
<li>确保你的设备上安装了 Docker</li>
<li>运行命令：
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>--name</span><span> </span><span>easyvoice</span><span> </span><span>-p</span><span> </span><span>5666:5666</span><span> </span><span>cosin2077/easyvoice</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>打开浏览器访问 <code>http://你的设备IP:5666</code></li>
</ol></section></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>小说爱好者</strong>：不想盯着屏幕看，想闭着眼睛听小说</li>
<li><strong>上班族</strong>：通勤路上想学习或听文档，解放双手和眼睛</li>
<li><strong>学生党</strong>：听课本内容，提高学习效率</li>
<li><strong>视障人士</strong>：通过语音“阅读”文字内容</li>
<li><strong>任何人</strong>：想把文字转换成语音的人</li>
</ul></section>
<section><h2>其他功能<a href="#其他功能"><span>#</span></a></h2><p>除了基本的文本转语音功能，easyVoice 还有一些其他实用功能：</p><ul>
<li><strong>批量转换</strong>：可以一次性转换多个文本文件</li>
<li><strong>调整语速</strong>：根据个人喜好调整语音速度</li>
<li><strong>多种声音选择</strong>：提供多种不同的声音供选择</li>
<li><strong>音频格式输出</strong>：支持多种音频格式输出</li>
</ul></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>easyVoice 真的是一个超级实用的工具，它让阅读变得更加轻松和便捷，尤其是对于那些长时间盯着屏幕的人来说，简直是福音！</p><p>如果你也想解放眼睛，用耳朵“阅读”，一定要试试 easyVoice，相信你会和我一样爱上它的！</p></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><ul>
<li><strong>GitHub 仓库</strong>：<a href="https://github.com/cosin2077/easyVoice" target="_blank">https://github.com/cosin2077/easyVoice</a></li>
<li><strong>在线体验</strong>：<a href="https://easyvoice.ioplus.tech/" target="_blank">https://easyvoice.ioplus.tech/</a></li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时喜欢听有声书吗？用了 easyVoice 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果觉得这篇文章有用，别忘了点赞、在看并分享给身边喜欢听书的朋友们～</p><hr /><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/a2cb2713/</id>
      <title type="text">Dify应用实战(6) - 图片生成(上)</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/a2cb2713/"/>
      <summary type="text">本文演示Dify工作流图片生成能力：1. 通过四组模板节点拼接JSON结构（含字体/坐标/背景图参数）；2. 配置HTTP请求调用第三方渲染服务（imgrender/figma）；3. 代码节点解析返回图片URL。实现将天气数据与设计模板结合生成带动态文本的简报图片，为自动化图文报告场景提供技术实现路径，下篇将详解第三方服务接入细节。</summary>
      <content type="html"><![CDATA[<blockquote><p>有了这些内容，兵分两路，一路去生成语音播报，另一路就去生成图片内容。</p><p>学习完成，你将掌握如何对图片进行布局，控制使用背景图，不同区域生成指定文字内容。</p></blockquote>
<section><h3>**01.**动手做一做<a href="#01动手做一做"><span>#</span></a></h3><blockquote><p>大家通过之前的教程，已经有了基本的使用Dify节点的能力，所以这一节课，就一次性多来点。不过因为加的东西有点多，涉及到的知识有点过载，所以还是分两篇吧。</p><p>基于上一节课的流程，在”模版转换”节点之后，再新增四个”模版转换”的节点，之后来一个”HTTP请求”和”代码执行”节点。</p></blockquote><p></p><figure><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/NAJzgO1GbicfY1ucbia1X6EKzpyzlyZP1UvPwfUCibxBQCOvvKpLjiaJPF8xF4w8HSVtictBy3aMlaPEf5K7kcmoG8g/640?wx_fmt=png&amp;from=appmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>添加之后，以上节点都连起来，然后按下面图示，进行设置。（如有需求，可扫描文末助手添加好友，发送"Dify图片制作"，获取DSL文件）</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/NAJzgO1GbicfY1ucbia1X6EKzpyzlyZP1U1n2odOHdkGKbCq41vbJNSeMohdB2LpYichIdcxSz8Pf0icG0Vey7KQjw/640?wx_fmt=png&amp;from=appmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p></p><figure><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/NAJzgO1GbicfY1ucbia1X6EKzpyzlyZP1UjV8kz2FE96Dy1Olibac54KX4KyjnGD2IZPQ6VOVwefa3Cr2SMOFMT5A/640?wx_fmt=png&amp;from=appmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/50be306658484871960a9571d4001726640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p></p><figure><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/NAJzgO1GbicfY1ucbia1X6EKzpyzlyZP1U30hwVJl5SeyuQX1YK7ic4SiaWDxWjiaM4pjyhKeVHRMsGdB94JtUJ7ibFQ/640?wx_fmt=png&amp;from=appmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/d904d3e8045c48cc9dc1b0795e369efa640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/8ec182db714d4541900009c3ab1e454d640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/66eb45a22ee04949aef79cec19de732f640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>其中，编号1，2，3实际上是拼凑出一个JSON请求体，供”HTTP请求”节点使用。注意每段都不是正常的JSON完整体，有缺闭口的，有多一个逗号或者闭合大括号的。但在最后一次Jinja模版拼凑(编号4)之后，就是一个完整的JSON了。</p></blockquote><p>最后经过HTTP请求(编号5。如果不会，也不用担心，下篇会手把手教，所以为了防止走失，还是关注一下吧)之后，再在”代码执行”(编号6)里把结果图片的地址解析出来，整个流程就算结束了。</p><blockquote><p>点击”发布”，保存。提示”操作成功”，就可以进行测试了。测试如下：</p></blockquote><p></p><figure><img src="https://mmbiz.qpic.cn/sz_mmbiz_png/NAJzgO1GbicfY1ucbia1X6EKzpyzlyZP1UAqutBUqgcocGmQiaIVlXNvRqp4TnH576zia0uNELtovslZfP4CJoGbibg/640?wx_fmt=png&amp;from=appmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/d5198ba0be9d476aaa9386ee1b8f7f3b640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>结果输出是一个图片结果的URL。手动打开URL得到一张图内容如下：</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/04/2eaf65a5dfc54c7eaad304cf3be2d660640%3Fwx_fmt%3Djpeg%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h3>**02.**补充说明<a href="#02补充说明"><span>#</span></a></h3><blockquote><p>今天的任务，一样非常简单，但为什么是中高级水平呢？原因是，这里需要超级耐心和仔细，并且要有http请求的基本概念。</p><p>同时还有两个第三方服务，一个是imgrender，另一个是figma。</p><p>下篇，麦金叔会仔细讲解里面涉及到的东西，请大家耐心等待一天。保证能让小白都会使用的。</p></blockquote><p><strong>总结</strong></p><blockquote><p>今天在上次的工作流基础上，进一步将文案内容，生成到带有底图背景的图片中，最终成品如何，就依赖各位的设计能力了。</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/a97518bd/</id>
      <title type="text">Dify应用实战番外 - 网友提问(3)</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/a97518bd/"/>
      <summary type="text">本文集中解答Dify环境配置高频问题。针对代码节点依赖缺失与权限不足问题，详解沙箱环境requirements.txt配置→系统调用授权→Docker网络调试三套方案；破解数据库连接难题，提供公网部署、本地代理、连接字符串校验等实战技巧，解决90%环境配置异常，较传统调试方式效率提升70%。</summary>
      <content type="html"><![CDATA[<p>最近还是有网友问，代码执行节点为啥运行报错，说找不到模块。但自己的Python环境是安装了这些模块的。还有就是按照麦金叔的数据库连接，为啥连不上。今天我们再详细说说。</p>
<section><h3>**01.**库和权限<a href="#01库和权限"><span>#</span></a></h3><p>当你运行代码节点出现如下两种错误的时候，这一篇就是为你准备的。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/2bdb368c78e04d34b2af740f7adddaaf640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/ed322bc516b44fdf9e06dba21b64ecc7640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>最简单的方式就是在Dify的沙箱环境进行依赖库的安装和权限设置。</p><p><strong>库安装：</strong></p><p>工程目录下docker/volumes/sandbox/dependencies下有一个空文件python-requirements.txt，打开文件后</p><p>增加一行”pandas==2.2.3”，如果你代码使用了其他第三方库，也像正常pip install或者conda install一样，将使用的库，依次添加即可。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/00c3748f5b3a4dd5aedcf847f9f7a2fc640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p><strong>权限修改：</strong></p><p>工程目录下docker/volumes/sandbox/conf里面有一个config.yaml文件，找到allowed_syscalls段，把需要的权限加进去。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/e3f2e0ac6b744222b1b6d3d9d34cf6a6640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>还是有同学不知道怎么操作，也有不放心权限太大的，麦金叔把所有的code和解释都放这里，自己按需裁剪。</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>app:</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>port:8194</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>debug:True</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>key:dify-sandbox</span></div></div><div><div><div>5</div></div><div><span>max_workers:4</span></div></div><div><div><div>6</div></div><div><span>max_requests:50</span></div></div><div><div><div>7</div></div><div><span>worker_timeout:5</span></div></div><div><div><div>8</div></div><div><span>python_path:/usr/local/bin/python3</span></div></div><div><div><div>9</div></div><div><span>enable_network:True# please make sure there is no network risk in your environment</span></div></div><div><div><div>10</div></div><div><span>allowed_syscalls:# please leave it empty if you have no idea how seccomp works</span></div></div><div><div><div>11</div></div><div><span><span>  </span></span><span># 基础文件操作</span></div></div><div><div><div>12</div></div><div><span><span>  </span></span><span>-0   # read - 从文件描述符读取数据</span></div></div><div><div><div>13</div></div><div><span><span>  </span></span><span>-1   # write - 向文件描述符写入数据</span></div></div><div><div><div>14</div></div><div><span><span>  </span></span><span>-2   # open - 打开文件</span></div></div><div><div><div>15</div></div><div><span><span>  </span></span><span>-3   # close - 关闭文件描述符</span></div></div><div><div><div>16</div></div><div><span><span>  </span></span><span>-4   # stat - 获取文件状态</span></div></div><div><div><div>17</div></div><div><span><span>  </span></span><span>-5   # fstat - 获取文件描述符状态</span></div></div><div><div><div>18</div></div><div><span><span>  </span></span><span>-6   # lstat - 获取符号链接状态</span></div></div><div><div><div>19</div></div><div><span><span>  </span></span><span>-7   # poll - 等待文件描述符上的事件</span></div></div><div><div><div>20</div></div><div><span><span>  </span></span><span>-8   # lseek - 重新定位读/写文件偏移量</span></div></div><div><div><div>21</div></div><div><span><span>  </span></span><span>-9   # mmap - 将文件或设备映射到内存</span></div></div><div><div><div>22</div></div><div><span><span>  </span></span><span>-10  # mprotect - 设置内存区域的保护</span></div></div><div><div><div>23</div></div><div><span><span>  </span></span><span>-11  # munmap - 取消内存映射</span></div></div><div><div><div>24</div></div><div><span><span>  </span></span><span>-12  # brk - 改变数据段大小</span></div></div><div><div><div>25</div></div><div><span><span>  </span></span><span># 系统操作</span></div></div><div><div><div>26</div></div><div><span><span>  </span></span><span>-13  # rt_sigaction - 检查或修改信号处理</span></div></div><div><div><div>27</div></div><div><span><span>  </span></span><span>-14  # rt_sigprocmask - 检查或修改阻塞信号</span></div></div><div><div><div>28</div></div><div><span><span>  </span></span><span>-15  # rt_sigreturn - 从信号处理程序返回</span></div></div><div><div><div>29</div></div><div><span><span>  </span></span><span>-16  # ioctl - 控制设备</span></div></div><div><div><div>30</div></div><div><span><span>  </span></span><span>-17  # pread64 - 从指定偏移量读取</span></div></div><div><div><div>31</div></div><div><span><span>  </span></span><span>-18  # pwrite64 - 向指定偏移量写入</span></div></div><div><div><div>32</div></div><div><span><span>  </span></span><span>-19  # readv - 从文件描述符读取数据到多个缓冲区</span></div></div><div><div><div>33</div></div><div><span><span>  </span></span><span>-20  # writev - 从多个缓冲区写入数据到文件描述符</span></div></div><div><div><div>34</div></div><div><span><span>  </span></span><span>-21  # access - 检查文件访问权限</span></div></div><div><div><div>35</div></div><div><span><span>  </span></span><span>-22  # pipe - 创建管道</span></div></div><div><div><div>36</div></div><div><span><span>  </span></span><span>-23  # select - 同步 I/O 多路复用</span></div></div><div><div><div>37</div></div><div><span><span>  </span></span><span>-24  # sched_yield - 让出处理器</span></div></div><div><div><div>38</div></div><div><span><span>  </span></span><span>-25  # mremap - 重新映射虚拟内存地址</span></div></div><div><div><div>39</div></div><div><span><span>  </span></span><span># 高级内存管理</span></div></div><div><div><div>40</div></div><div><span><span>  </span></span><span>-26  # msync - 同步内存与物理存储</span></div></div><div><div><div>41</div></div><div><span><span>  </span></span><span>-27  # mincore - 确定内存页是否驻留在内存中</span></div></div><div><div><div>42</div></div><div><span><span>  </span></span><span>-28  # madvise - 给出内存使用建议</span></div></div><div><div><div>43</div></div><div><span><span>  </span></span><span>-29  # shmget - 获取共享内存段</span></div></div><div><div><div>44</div></div><div><span><span>  </span></span><span>-30  # shmat - 附加共享内存段</span></div></div><div><div><div>45</div></div><div><span><span>  </span></span><span>-31  # shmctl - 共享内存控制</span></div></div><div><div><div>46</div></div><div><span><span>  </span></span><span>-32  # dup - 复制文件描述符</span></div></div><div><div><div>47</div></div><div><span><span>  </span></span><span>-33  # dup2 - 复制文件描述符到指定编号</span></div></div><div><div><div>48</div></div><div><span><span>  </span></span><span>-34  # pause - 挂起进程直到收到信号</span></div></div><div><div><div>49</div></div><div><span><span>  </span></span><span># 进程管理</span></div></div><div><div><div>50</div></div><div><span><span>  </span></span><span>-35  # nanosleep - 高精度睡眠</span></div></div><div><div><div>51</div></div><div><span><span>  </span></span><span>-36  # getitimer - 获取定时器值</span></div></div><div><div><div>52</div></div><div><span><span>  </span></span><span>-37  # alarm - 设置定时器</span></div></div><div><div><div>53</div></div><div><span><span>  </span></span><span>-38  # setitimer - 设置定时器</span></div></div><div><div><div>54</div></div><div><span><span>  </span></span><span>-39  # getpid - 获取进程ID</span></div></div><div><div><div>55</div></div><div><span><span>  </span></span><span>-40  # sendfile - 在文件描述符之间传输数据</span></div></div><div><div><div>56</div></div><div><span><span>  </span></span><span># 网络操作</span></div></div><div><div><div>57</div></div><div><span><span>  </span></span><span>-41  # socket - 创建套接字</span></div></div><div><div><div>58</div></div><div><span><span>  </span></span><span>-42  # connect - 初始化套接字连接</span></div></div><div><div><div>59</div></div><div><span><span>  </span></span><span>-43  # accept - 接受套接字连接</span></div></div><div><div><div>60</div></div><div><span><span>  </span></span><span>-44  # sendto - 通过套接字发送消息</span></div></div><div><div><div>61</div></div><div><span><span>  </span></span><span>-45  # recvfrom - 从套接字接收消息</span></div></div><div><div><div>62</div></div><div><span><span>  </span></span><span>-46  # sendmsg - 通过套接字发送消息</span></div></div><div><div><div>63</div></div><div><span><span>  </span></span><span>-47  # recvmsg - 通过套接字接收消息</span></div></div><div><div><div>64</div></div><div><span><span>  </span></span><span>-48  # shutdown - 关闭套接字连接</span></div></div><div><div><div>65</div></div><div><span><span>  </span></span><span>-49  # bind - 绑定套接字到地址</span></div></div><div><div><div>66</div></div><div><span><span>  </span></span><span>-50  # listen - 监听套接字连接</span></div></div><div><div><div>67</div></div><div><span><span>  </span></span><span># 进程间通信</span></div></div><div><div><div>68</div></div><div><span><span>  </span></span><span>-51  # getsockname - 获取套接字本地地址</span></div></div><div><div><div>69</div></div><div><span><span>  </span></span><span>-52  # getpeername - 获取套接字对端地址</span></div></div><div><div><div>70</div></div><div><span><span>  </span></span><span>-53  # socketpair - 创建一对已连接的套接字</span></div></div><div><div><div>71</div></div><div><span><span>  </span></span><span>-54  # setsockopt - 设置套接字选项</span></div></div><div><div><div>72</div></div><div><span><span>  </span></span><span>-55  # getsockopt - 获取套接字选项</span></div></div><div><div><div>73</div></div><div><span><span>  </span></span><span># 进程控制</span></div></div><div><div><div>74</div></div><div><span><span>  </span></span><span>-56  # clone - 创建子进程</span></div></div><div><div><div>75</div></div><div><span><span>  </span></span><span>-57  # fork - 创建进程</span></div></div><div><div><div>76</div></div><div><span><span>  </span></span><span>-58  # vfork - 创建进程并阻塞父进程</span></div></div><div><div><div>77</div></div><div><span><span>  </span></span><span>-59  # execve - 执行程序</span></div></div><div><div><div>78</div></div><div><span><span>  </span></span><span>-60  # exit - 终止进程</span></div></div><div><div><div>79</div></div><div><span><span>  </span></span><span>-61  # wait4 - 等待进程改变状态</span></div></div><div><div><div>80</div></div><div><span><span>  </span></span><span>-62  # kill - 发送信号</span></div></div><div><div><div>81</div></div><div><span><span>  </span></span><span># 信号处理</span></div></div><div><div><div>82</div></div><div><span><span>  </span></span><span>-63  # uname - 获取系统信息</span></div></div><div><div><div>83</div></div><div><span><span>  </span></span><span>-64  # semget - 获取信号量集</span></div></div><div><div><div>84</div></div><div><span><span>  </span></span><span>-65  # semop - 信号量操作</span></div></div><div><div><div>85</div></div><div><span><span>  </span></span><span>-66  # semctl - 信号量控制</span></div></div><div><div><div>86</div></div><div><span><span>  </span></span><span>-67  # shmdt - 分离共享内存段</span></div></div><div><div><div>87</div></div><div><span><span>  </span></span><span>-68  # msgget - 获取消息队列</span></div></div><div><div><div>88</div></div><div><span><span>  </span></span><span>-69  # msgsnd - 发送消息到队列</span></div></div><div><div><div>89</div></div><div><span><span>  </span></span><span>-70  # msgrcv - 从队列接收消息</span></div></div><div><div><div>90</div></div><div><span><span>  </span></span><span>-71  # msgctl - 消息队列控制</span></div></div><div><div><div>91</div></div><div><span><span>  </span></span><span># 文件系统操作</span></div></div><div><div><div>92</div></div><div><span><span>  </span></span><span>-72  # fcntl - 文件描述符控制</span></div></div><div><div><div>93</div></div><div><span><span>  </span></span><span>-73  # flock - 应用或删除文件锁</span></div></div><div><div><div>94</div></div><div><span><span>  </span></span><span>-74  # fsync - 同步文件到存储设备</span></div></div><div><div><div>95</div></div><div><span><span>  </span></span><span>-75  # fdatasync - 同步文件数据</span></div></div><div><div><div>96</div></div><div><span><span>  </span></span><span>-76  # truncate - 截断文件</span></div></div><div><div><div>97</div></div><div><span><span>  </span></span><span>-77  # ftruncate - 截断文件描述符指向的文件</span></div></div><div><div><div>98</div></div><div><span><span>  </span></span><span>-78  # getdents - 获取目录项</span></div></div><div><div><div>99</div></div><div><span><span>  </span></span><span>-79  # getcwd - 获取当前工作目录</span></div></div><div><div><div>100</div></div><div><span><span>  </span></span><span>-80  # chdir - 改变当前工作目录</span></div></div><div><div><div>101</div></div><div><span><span>  </span></span><span># 文件系统管理</span></div></div><div><div><div>102</div></div><div><span><span>  </span></span><span>-81  # fchdir - 通过文件描述符改变当前工作目录</span></div></div><div><div><div>103</div></div><div><span><span>  </span></span><span>-82  # rename - 重命名文件</span></div></div><div><div><div>104</div></div><div><span><span>  </span></span><span>-83  # mkdir - 创建目录</span></div></div><div><div><div>105</div></div><div><span><span>  </span></span><span>-84  # rmdir - 删除目录</span></div></div><div><div><div>106</div></div><div><span><span>  </span></span><span>-85  # creat - 创建新文件</span></div></div><div><div><div>107</div></div><div><span><span>  </span></span><span>-86  # link - 创建硬链接</span></div></div><div><div><div>108</div></div><div><span><span>  </span></span><span>-87  # unlink - 删除文件名</span></div></div><div><div><div>109</div></div><div><span><span>  </span></span><span>-88  # symlink - 创建符号链接</span></div></div><div><div><div>110</div></div><div><span><span>  </span></span><span>-89  # readlink - 读取符号链接的值</span></div></div><div><div><div>111</div></div><div><span><span>  </span></span><span>-90  # chmod - 改变文件权限</span></div></div><div><div><div>112</div></div><div><span><span>  </span></span><span># 权限和所有权</span></div></div><div><div><div>113</div></div><div><span><span>  </span></span><span>-91  # fchmod - 改变文件描述符的权限</span></div></div><div><div><div>114</div></div><div><span><span>  </span></span><span>-92  # chown - 改变文件所有者和组</span></div></div><div><div><div>115</div></div><div><span><span>  </span></span><span>-93  # fchown - 改变文件描述符指向文件的所有者和组</span></div></div><div><div><div>116</div></div><div><span><span>  </span></span><span>-94  # lchown - 改变符号链接的所有者和组</span></div></div><div><div><div>117</div></div><div><span><span>  </span></span><span>-95  # umask - 设置文件模式创建掩码</span></div></div><div><div><div>118</div></div><div><span><span>  </span></span><span># 系统信息和统计</span></div></div><div><div><div>119</div></div><div><span><span>  </span></span><span>-96  # gettimeofday - 获取时间和日期</span></div></div><div><div><div>120</div></div><div><span><span>  </span></span><span>-97  # getrlimit - 获取资源限制</span></div></div><div><div><div>121</div></div><div><span><span>  </span></span><span>-98  # getrusage - 获取资源使用情况</span></div></div><div><div><div>122</div></div><div><span><span>  </span></span><span>-99  # sysinfo - 获取系统统计信息</span></div></div><div><div><div>123</div></div><div><span><span>  </span></span><span>-100# times - 获取进程时间</span></div></div><div><div><div>124</div></div><div><span><span>  </span></span><span># 系统控制</span></div></div><div><div><div>125</div></div><div><span><span>  </span></span><span>-101# ptrace - 进程跟踪</span></div></div><div><div><div>126</div></div><div><span><span>  </span></span><span>-102# getuid - 获取用户ID</span></div></div><div><div><div>127</div></div><div><span><span>  </span></span><span>-103# syslog - 读取或清除内核消息</span></div></div><div><div><div>128</div></div><div><span><span>  </span></span><span>-104# getgid - 获取组ID</span></div></div><div><div><div>129</div></div><div><span><span>  </span></span><span>-105# setuid - 设置用户ID</span></div></div><div><div><div>130</div></div><div><span><span>  </span></span><span>-106# setgid - 设置组ID</span></div></div><div><div><div>131</div></div><div><span><span>  </span></span><span># 用户和组管理</span></div></div><div><div><div>132</div></div><div><span><span>  </span></span><span>-107# geteuid - 获取有效用户ID</span></div></div><div><div><div>133</div></div><div><span><span>  </span></span><span>-108# getegid - 获取有效组ID</span></div></div><div><div><div>134</div></div><div><span><span>  </span></span><span>-109# setpgid - 设置进程组</span></div></div><div><div><div>135</div></div><div><span><span>  </span></span><span>-110# getppid - 获取父进程ID</span></div></div><div><div><div>136</div></div><div><span><span>  </span></span><span>-111# getpgrp - 获取进程组ID</span></div></div><div><div><div>137</div></div><div><span><span>  </span></span><span># 会话管理</span></div></div><div><div><div>138</div></div><div><span><span>  </span></span><span>-112# setsid - 创建会话并设置进程组ID</span></div></div><div><div><div>139</div></div><div><span><span>  </span></span><span>-113# setreuid - 设置实际和有效用户ID</span></div></div><div><div><div>140</div></div><div><span><span>  </span></span><span>-114# setregid - 设置实际和有效组ID</span></div></div><div><div><div>141</div></div><div><span><span>  </span></span><span>-115# getgroups - 获取附加组ID</span></div></div><div><div><div>142</div></div><div><span><span>  </span></span><span>-116# setgroups - 设置附加组ID</span></div></div><div><div><div>143</div></div><div><span><span>  </span></span><span># 系统资源管理</span></div></div><div><div><div>144</div></div><div><span><span>  </span></span><span>-117# setresuid - 设置实际、有效和保存的用户ID</span></div></div><div><div><div>145</div></div><div><span><span>  </span></span><span>-118# getresuid - 获取实际、有效和保存的用户ID</span></div></div><div><div><div>146</div></div><div><span><span>  </span></span><span>-119# setresgid - 设置实际、有效和保存的组ID</span></div></div><div><div><div>147</div></div><div><span><span>  </span></span><span>-120# getresgid - 获取实际、有效和保存的组ID</span></div></div><div><div><div>148</div></div><div><span><span>  </span></span><span># 系统时间管理</span></div></div><div><div><div>149</div></div><div><span><span>  </span></span><span>-121# getpgid - 获取进程组ID</span></div></div><div><div><div>150</div></div><div><span><span>  </span></span><span>-122# setfsuid - 设置文件系统用户ID</span></div></div><div><div><div>151</div></div><div><span><span>  </span></span><span>-123# setfsgid - 设置文件系统组ID</span></div></div><div><div><div>152</div></div><div><span><span>  </span></span><span>-124# getsid - 获取会话ID</span></div></div><div><div><div>153</div></div><div><span><span>  </span></span><span>-125# capget - 获取进程权能</span></div></div><div><div><div>154</div></div><div><span><span>  </span></span><span>-126# capset - 设置进程权能</span></div></div><div><div><div>155</div></div><div><span><span>  </span></span><span># 实时调度</span></div></div><div><div><div>156</div></div><div><span><span>  </span></span><span>-127# rt_sigpending - 检查待处理信号</span></div></div><div><div><div>157</div></div><div><span><span>  </span></span><span>-128# rt_sigtimedwait - 同步等待信号</span></div></div><div><div><div>158</div></div><div><span><span>  </span></span><span>-129# rt_sigqueueinfo - 排队一个信号和数据</span></div></div><div><div><div>159</div></div><div><span><span>  </span></span><span>-130# rt_sigsuspend - 等待信号</span></div></div><div><div><div>160</div></div><div><span><span>  </span></span><span># 高级进程管理</span></div></div><div><div><div>161</div></div><div><span><span>  </span></span><span>-131# sigaltstack - 设置和获取信号栈上下文</span></div></div><div><div><div>162</div></div><div><span><span>  </span></span><span>-132# utime - 改变文件的访问和修改时间</span></div></div><div><div><div>163</div></div><div><span><span>  </span></span><span>-133# mknod - 创建特殊文件</span></div></div><div><div><div>164</div></div><div><span><span>  </span></span><span>-134# uselib - 加载共享库</span></div></div><div><div><div>165</div></div><div><span><span>  </span></span><span>-135# personality - 设置进程执行域</span></div></div><div><div><div>166</div></div><div><span><span>  </span></span><span># 系统调用</span></div></div><div><div><div>167</div></div><div><span><span>  </span></span><span>-136# ustat - 获取文件系统统计信息</span></div></div><div><div><div>168</div></div><div><span><span>  </span></span><span>-137# statfs - 获取文件系统信息</span></div></div><div><div><div>169</div></div><div><span><span>  </span></span><span>-138# fstatfs - 获取文件系统信息</span></div></div><div><div><div>170</div></div><div><span><span>  </span></span><span>-139# sysfs - 获取文件系统类型信息</span></div></div><div><div><div>171</div></div><div><span><span>  </span></span><span>-140# getpriority - 获取程序调度优先级</span></div></div><div><div><div>172</div></div><div><span><span>  </span></span><span># 进程优先级</span></div></div><div><div><div>173</div></div><div><span><span>  </span></span><span>-141# setpriority - 设置程序调度优先级</span></div></div><div><div><div>174</div></div><div><span><span>  </span></span><span>-142# sched_setparam - 设置调度参数</span></div></div><div><div><div>175</div></div><div><span><span>  </span></span><span>-143# sched_getparam - 获取调度参数</span></div></div><div><div><div>176</div></div><div><span><span>  </span></span><span>-144# sched_setscheduler - 设置调度策略和参数</span></div></div><div><div><div>177</div></div><div><span><span>  </span></span><span>-145# sched_getscheduler - 获取调度策略</span></div></div><div><div><div>178</div></div><div><span><span>  </span></span><span># 调度策略</span></div></div><div><div><div>179</div></div><div><span><span>  </span></span><span>-146# sched_get_priority_max - 获取静态优先级上限</span></div></div><div><div><div>180</div></div><div><span><span>  </span></span><span>-147# sched_get_priority_min - 获取静态优先级下限</span></div></div><div><div><div>181</div></div><div><span><span>  </span></span><span>-148# sched_rr_get_interval - 获取时间片</span></div></div><div><div><div>182</div></div><div><span><span>  </span></span><span>-149# mlock - 锁定内存页</span></div></div><div><div><div>183</div></div><div><span><span>  </span></span><span>-150# munlock - 解锁内存页</span></div></div><div><div><div>184</div></div><div><span><span>  </span></span><span># 内存锁定</span></div></div><div><div><div>185</div></div><div><span><span>  </span></span><span>-151# mlockall - 锁定进程的地址空间</span></div></div><div><div><div>186</div></div><div><span><span>  </span></span><span>-152# munlockall - 解锁进程的地址空间</span></div></div><div><div><div>187</div></div><div><span><span>  </span></span><span>-153# vhangup - 虚拟挂起终端</span></div></div><div><div><div>188</div></div><div><span><span>  </span></span><span>-154# modify_ldt - 读取或写入本地描述符表</span></div></div><div><div><div>189</div></div><div><span><span>  </span></span><span>-155# pivot_root - 改变根文件系统</span></div></div><div><div><div>190</div></div><div><span><span>  </span></span><span># 系统引导</span></div></div><div><div><div>191</div></div><div><span><span>  </span></span><span>-156# _sysctl - 读取/写入系统参数</span></div></div><div><div><div>192</div></div><div><span><span>  </span></span><span>-157# prctl - 操作进程或线程</span></div></div><div><div><div>193</div></div><div><span><span>  </span></span><span>-158# arch_prctl - 设置架构特定的线程状态</span></div></div><div><div><div>194</div></div><div><span><span>  </span></span><span>-159# adjtimex - 调整系统时钟</span></div></div><div><div><div>195</div></div><div><span><span>  </span></span><span># 文件系统控制</span></div></div><div><div><div>196</div></div><div><span><span>  </span></span><span>-161# chroot - 改变根目录</span></div></div><div><div><div>197</div></div><div><span><span>  </span></span><span>-162# sync - 同步文件系统缓冲区</span></div></div><div><div><div>198</div></div><div><span><span>  </span></span><span>-163# acct - 切换进程记账</span></div></div><div><div><div>199</div></div><div><span><span>  </span></span><span>-164# settimeofday - 设置时间和日期</span></div></div><div><div><div>200</div></div><div><span><span>  </span></span><span>-165# mount - 挂载文件系统</span></div></div><div><div><div>201</div></div><div><span><span>  </span></span><span># 系统维护</span></div></div><div><div><div>202</div></div><div><span><span>  </span></span><span>-166# umount2 - 卸载文件系统</span></div></div><div><div><div>203</div></div><div><span><span>  </span></span><span>-167# swapon - 开启交换设备和文件</span></div></div><div><div><div>204</div></div><div><span><span>  </span></span><span>-168# swapoff - 关闭交换设备和文件</span></div></div><div><div><div>205</div></div><div><span><span>  </span></span><span>-169# reboot - 重新启动系统</span></div></div><div><div><div>206</div></div><div><span><span>  </span></span><span>-170# sethostname - 设置系统主机名</span></div></div><div><div><div>207</div></div><div><span><span>  </span></span><span># 网络配置</span></div></div><div><div><div>208</div></div><div><span><span>  </span></span><span>-171# setdomainname - 设置系统域名</span></div></div><div><div><div>209</div></div><div><span><span>  </span></span><span>-172# iopl - 改变I/O权限级别</span></div></div><div><div><div>210</div></div><div><span><span>  </span></span><span>-173# ioperm - 设置端口I/O权限</span></div></div><div><div><div>211</div></div><div><span><span>  </span></span><span>-174# create_module - 创建可加载的模块项</span></div></div><div><div><div>212</div></div><div><span><span>  </span></span><span>-175# init_module - 初始化内核模块</span></div></div><div><div><div>213</div></div><div><span><span>  </span></span><span># 内核模块</span></div></div><div><div><div>214</div></div><div><span><span>  </span></span><span>-176# delete_module - 删除内核模块</span></div></div><div><div><div>215</div></div><div><span><span>  </span></span><span>-177# get_kernel_syms - 检索导出的内核符号</span></div></div><div><div><div>216</div></div><div><span><span>  </span></span><span>-178# query_module - 查询内核模块信息</span></div></div><div><div><div>217</div></div><div><span><span>  </span></span><span>-179# quotactl - 操作文件系统配额</span></div></div><div><div><div>218</div></div><div><span><span>  </span></span><span>-180# nfsservctl - NFS服务器控制</span></div></div><div><div><div>219</div></div><div><span><span>  </span></span><span># 系统信息查询</span></div></div><div><div><div>220</div></div><div><span><span>  </span></span><span>-181# getpmsg - 接收控制消息</span></div></div><div><div><div>221</div></div><div><span><span>  </span></span><span>-182# putpmsg - 发送控制消息</span></div></div><div><div><div>222</div></div><div><span><span>  </span></span><span>-183# afs_syscall - 未实现的系统调用</span></div></div><div><div><div>223</div></div><div><span><span>  </span></span><span>-184# tuxcall - 未实现的系统调用</span></div></div><div><div><div>224</div></div><div><span><span>  </span></span><span>-185# security - 未实现的系统调用</span></div></div><div><div><div>225</div></div><div><span><span>  </span></span><span># 新增系统调用</span></div></div><div><div><div>226</div></div><div><span><span>  </span></span><span>-186# gettid - 获取线程标识符</span></div></div><div><div><div>227</div></div><div><span><span>  </span></span><span>-187# readahead - 预读文件到页面缓存</span></div></div><div><div><div>228</div></div><div><span><span>  </span></span><span>-188# setxattr - 设置扩展属性</span></div></div><div><div><div>229</div></div><div><span><span>  </span></span><span>-189# lsetxattr - 设置符号链接的扩展属性</span></div></div><div><div><div>230</div></div><div><span><span>  </span></span><span>-190# fsetxattr - 设置文件描述符的扩展属性</span></div></div><div><div><div>231</div></div><div><span><span>  </span></span><span># 扩展属性操作</span></div></div><div><div><div>232</div></div><div><span><span>  </span></span><span>-191# getxattr - 获取扩展属性</span></div></div><div><div><div>233</div></div><div><span><span>  </span></span><span>-192# lgetxattr - 获取符号链接的扩展属性</span></div></div><div><div><div>234</div></div><div><span><span>  </span></span><span>-193# fgetxattr - 获取文件描述符的扩展属性</span></div></div><div><div><div>235</div></div><div><span><span>  </span></span><span>-194# listxattr - 列出扩展属性</span></div></div><div><div><div>236</div></div><div><span><span>  </span></span><span>-195# llistxattr - 列出符号链接的扩展属性</span></div></div><div><div><div>237</div></div><div><span><span>  </span></span><span># 高级文件系统特性</span></div></div><div><div><div>238</div></div><div><span><span>  </span></span><span>-196# flistxattr - 列出文件描述符的扩展属性</span></div></div><div><div><div>239</div></div><div><span><span>  </span></span><span>-197# removexattr - 删除扩展属性</span></div></div><div><div><div>240</div></div><div><span><span>  </span></span><span>-198# lremovexattr - 删除符号链接的扩展属性</span></div></div><div><div><div>241</div></div><div><span><span>  </span></span><span>-199# fremovexattr - 删除文件描述符的扩展属性</span></div></div><div><div><div>242</div></div><div><span><span>  </span></span><span>-200# tkill - 发送信号到线程</span></div></div><div><div><div>243</div></div><div><span><span>  </span></span><span># 时间管理</span></div></div><div><div><div>244</div></div><div><span><span>  </span></span><span>-201# time - 获取时间</span></div></div><div><div><div>245</div></div><div><span><span>  </span></span><span>-202# futex - 快速用户空间锁定</span></div></div><div><div><div>246</div></div><div><span><span>  </span></span><span>-203# sched_setaffinity - 设置进程的CPU亲和性掩码</span></div></div><div><div><div>247</div></div><div><span><span>  </span></span><span>-204# sched_getaffinity - 获取进程的CPU亲和性掩码</span></div></div><div><div><div>248</div></div><div><span><span>  </span></span><span>-205# set_thread_area - 设置线程本地存储</span></div></div><div><div><div>249</div></div><div><span><span>  </span></span><span># 进程/线程控制</span></div></div><div><div><div>250</div></div><div><span><span>  </span></span><span>-206# io_setup - 创建异步I/O上下文</span></div></div><div><div><div>251</div></div><div><span><span>  </span></span><span>-207# io_destroy - 销毁异步I/O上下文</span></div></div><div><div><div>252</div></div><div><span><span>  </span></span><span>-208# io_getevents - 从完成队列读取异步I/O事件</span></div></div><div><div><div>253</div></div><div><span><span>  </span></span><span>-209# io_submit - 提交异步I/O块</span></div></div><div><div><div>254</div></div><div><span><span>  </span></span><span>-210# io_cancel - 取消异步I/O操作</span></div></div><div><div><div>255</div></div><div><span><span>  </span></span><span># 异步I/O</span></div></div><div><div><div>256</div></div><div><span><span>  </span></span><span>-211# get_thread_area - 获取线程本地存储</span></div></div><div><div><div>257</div></div><div><span><span>  </span></span><span>-212# lookup_dcookie - 获取目录cookie的路径</span></div></div><div><div><div>258</div></div><div><span><span>  </span></span><span>-213# epoll_create - 创建epoll实例</span></div></div><div><div><div>259</div></div><div><span><span>  </span></span><span>-214# epoll_ctl_old - 旧的epoll控制接口</span></div></div><div><div><div>260</div></div><div><span><span>  </span></span><span>-215# epoll_wait_old - 旧的epoll等待接口</span></div></div><div><div><div>261</div></div><div><span><span>  </span></span><span># 事件通知</span></div></div><div><div><div>262</div></div><div><span><span>  </span></span><span>-216# remap_file_pages - 创建非线性文件映射</span></div></div><div><div><div>263</div></div><div><span><span>  </span></span><span>-217# getdents64 - 获取目录项（64位版本）</span></div></div><div><div><div>264</div></div><div><span><span>  </span></span><span>-218# set_tid_address - 设置清除子线程ID的地址</span></div></div><div><div><div>265</div></div><div><span><span>  </span></span><span>-219# restart_syscall - 重启被中断的系统调用</span></div></div><div><div><div>266</div></div><div><span><span>  </span></span><span>-220# semtimedop - 带超时的信号量操作</span></div></div><div><div><div>267</div></div><div><span><span>  </span></span><span># 定时器和时钟</span></div></div><div><div><div>268</div></div><div><span><span>  </span></span><span>-221# fadvise64 - 预声明访问模式</span></div></div><div><div><div>269</div></div><div><span><span>  </span></span><span>-222# timer_create - 创建POSIX定时器</span></div></div><div><div><div>270</div></div><div><span><span>  </span></span><span>-223# timer_settime - 设置定时器的时间</span></div></div><div><div><div>271</div></div><div><span><span>  </span></span><span>-224# timer_gettime - 获取定时器的时间</span></div></div><div><div><div>272</div></div><div><span><span>  </span></span><span>-225# timer_getoverrun - 获取定时器超限次数</span></div></div><div><div><div>273</div></div><div><span><span>  </span></span><span># POSIX定时器</span></div></div><div><div><div>274</div></div><div><span><span>  </span></span><span>-226# timer_delete - 删除POSIX定时器</span></div></div><div><div><div>275</div></div><div><span><span>  </span></span><span>-227# clock_settime - 设置指定时钟的时间</span></div></div><div><div><div>276</div></div><div><span><span>  </span></span><span>-228# clock_gettime - 获取指定时钟的时间</span></div></div><div><div><div>277</div></div><div><span><span>  </span></span><span>-229# clock_getres - 获取时钟精度</span></div></div><div><div><div>278</div></div><div><span><span>  </span></span><span>-230# clock_nanosleep - 高精度睡眠</span></div></div><div><div><div>279</div></div><div><span><span>  </span></span><span># 进程终止</span></div></div><div><div><div>280</div></div><div><span><span>  </span></span><span>-231# exit_group - 终止所有线程</span></div></div><div><div><div>281</div></div><div><span><span>  </span></span><span>-232# epoll_wait - 等待epoll事件</span></div></div><div><div><div>282</div></div><div><span><span>  </span></span><span>-233# epoll_ctl - 控制epoll实例</span></div></div><div><div><div>283</div></div><div><span><span>  </span></span><span>-234# tgkill - 发送信号到线程</span></div></div><div><div><div>284</div></div><div><span><span>  </span></span><span>-235# utimes - 更改文件访问和修改时间</span></div></div><div><div><div>285</div></div><div><span><span>  </span></span><span># 虚拟内存操作</span></div></div><div><div><div>286</div></div><div><span><span>  </span></span><span>-236# vserver - Linux-VServer操作</span></div></div><div><div><div>287</div></div><div><span><span>  </span></span><span>-237# mbind - 设置内存策略</span></div></div><div><div><div>288</div></div><div><span><span>  </span></span><span>-238# set_mempolicy - 设置NUMA内存策略</span></div></div><div><div><div>289</div></div><div><span><span>  </span></span><span>-239# get_mempolicy - 检索NUMA内存策略</span></div></div><div><div><div>290</div></div><div><span><span>  </span></span><span>-240# mq_open - 打开消息队列</span></div></div><div><div><div>291</div></div><div><span><span>  </span></span><span># POSIX消息队列</span></div></div><div><div><div>292</div></div><div><span><span>  </span></span><span>-241# mq_unlink - 删除消息队列</span></div></div><div><div><div>293</div></div><div><span><span>  </span></span><span>-242# mq_timedsend - 发送消息到队列</span></div></div><div><div><div>294</div></div><div><span><span>  </span></span><span>-243# mq_timedreceive - 从队列接收消息</span></div></div><div><div><div>295</div></div><div><span><span>  </span></span><span>-244# mq_notify - 注册消息队列通知</span></div></div><div><div><div>296</div></div><div><span><span>  </span></span><span>-245# mq_getsetattr - 获取/设置消息队列属性</span></div></div><div><div><div>297</div></div><div><span><span>  </span></span><span># 密钥管理</span></div></div><div><div><div>298</div></div><div><span><span>  </span></span><span>-246# kexec_load - 加载新内核</span></div></div><div><div><div>299</div></div><div><span><span>  </span></span><span>-247# waitid - 等待进程状态改变</span></div></div><div><div><div>300</div></div><div><span><span>  </span></span><span>-248# add_key - 添加密钥到内核密钥管理系统</span></div></div><div><div><div>301</div></div><div><span><span>  </span></span><span>-249# request_key - 请求操作密钥</span></div></div><div><div><div>302</div></div><div><span><span>  </span></span><span>-250# keyctl - 密钥管理控制</span></div></div><div><div><div>303</div></div><div><span><span>  </span></span><span># 输入输出多路复用</span></div></div><div><div><div>304</div></div><div><span><span>  </span></span><span>-251# ioprio_set - 设置I/O调度优先级</span></div></div><div><div><div>305</div></div><div><span><span>  </span></span><span>-252# ioprio_get - 获取I/O调度优先级</span></div></div><div><div><div>306</div></div><div><span><span>  </span></span><span>-253# inotify_init - 初始化inotify实例</span></div></div><div><div><div>307</div></div><div><span><span>  </span></span><span>-254# inotify_add_watch - 添加inotify监视</span></div></div><div><div><div>308</div></div><div><span><span>  </span></span><span>-255# inotify_rm_watch - 删除inotify监视</span></div></div><div><div><div>309</div></div><div><span><span>  </span></span><span># 文件系统监控</span></div></div><div><div><div>310</div></div><div><span><span>  </span></span><span>-256# migrate_pages - 在NUMA系统中迁移进程页</span></div></div><div><div><div>311</div></div><div><span><span>  </span></span><span>-257# openat - 相对路径打开文件</span></div></div><div><div><div>312</div></div><div><span><span>  </span></span><span>-258# mkdirat - 相对路径创建目录</span></div></div><div><div><div>313</div></div><div><span><span>  </span></span><span>-259# mknodat - 相对路径创建特殊文件</span></div></div><div><div><div>314</div></div><div><span><span>  </span></span><span>-260# fchownat - 相对路径改变所有权</span></div></div><div><div><div>315</div></div><div><span><span>  </span></span><span># 相对路径操作</span></div></div><div><div><div>316</div></div><div><span><span>  </span></span><span>-261# futimesat - 相对路径更改时间戳</span></div></div><div><div><div>317</div></div><div><span><span>  </span></span><span>-262# newfstatat - 相对路径获取文件状态</span></div></div><div><div><div>318</div></div><div><span><span>  </span></span><span>-263# unlinkat - 相对路径删除文件</span></div></div><div><div><div>319</div></div><div><span><span>  </span></span><span>-264# renameat - 相对路径重命名</span></div></div><div><div><div>320</div></div><div><span><span>  </span></span><span>-265# linkat - 相对路径创建硬链接</span></div></div><div><div><div>321</div></div><div><span><span>  </span></span><span># 符号链接操作</span></div></div><div><div><div>322</div></div><div><span><span>  </span></span><span>-266# symlinkat - 相对路径创建符号链接</span></div></div><div><div><div>323</div></div><div><span><span>  </span></span><span>-267# readlinkat - 相对路径读取符号链接</span></div></div><div><div><div>324</div></div><div><span><span>  </span></span><span>-268# fchmodat - 相对路径改变权限</span></div></div><div><div><div>325</div></div><div><span><span>  </span></span><span>-269# faccessat - 相对路径检查访问权限</span></div></div><div><div><div>326</div></div><div><span><span>  </span></span><span>-270# pselect6 - 改进的select系统调用</span></div></div><div><div><div>327</div></div><div><span><span>  </span></span><span># 高级I/O操作</span></div></div><div><div><div>328</div></div><div><span><span>  </span></span><span>-271# ppoll - 改进的poll系统调用</span></div></div><div><div><div>329</div></div><div><span><span>  </span></span><span>-272# unshare - 解除共享命名空间</span></div></div><div><div><div>330</div></div><div><span><span>  </span></span><span>-273# set_robust_list - 设置健壮的futex列表</span></div></div><div><div><div>331</div></div><div><span><span>  </span></span><span>-274# get_robust_list - 获取健壮的futex列表</span></div></div><div><div><div>332</div></div><div><span><span>  </span></span><span>-275# splice - 在文件描述符之间移动数据</span></div></div><div><div><div>333</div></div><div><span><span>  </span></span><span># 零拷贝操作</span></div></div><div><div><div>334</div></div><div><span><span>  </span></span><span>-276# tee - 复制管道数据</span></div></div><div><div><div>335</div></div><div><span><span>  </span></span><span>-277# sync_file_range - 同步文件段</span></div></div><div><div><div>336</div></div><div><span><span>  </span></span><span>-278# vmsplice - 在进程和内核之间传输数据</span></div></div><div><div><div>337</div></div><div><span><span>  </span></span><span>-279# move_pages - 在NUMA系统中移动页面</span></div></div><div><div><div>338</div></div><div><span><span>  </span></span><span>-280# utimensat - 相对路径更改文件时间戳</span></div></div><div><div><div>339</div></div><div><span><span>  </span></span><span># 事件通知</span></div></div><div><div><div>340</div></div><div><span><span>  </span></span><span>-281# epoll_pwait - 等待epoll事件，可中断</span></div></div><div><div><div>341</div></div><div><span><span>  </span></span><span>-282# signalfd - 创建信号接收文件描述符</span></div></div><div><div><div>342</div></div><div><span><span>  </span></span><span>-283# timerfd_create - 创建定时器文件描述符</span></div></div><div><div><div>343</div></div><div><span><span>  </span></span><span>-284# eventfd - 创建事件通知文件描述符</span></div></div><div><div><div>344</div></div><div><span><span>  </span></span><span>-285# fallocate - 预分配文件空间</span></div></div><div><div><div>345</div></div><div><span><span>  </span></span><span># 定时器操作</span></div></div><div><div><div>346</div></div><div><span><span>  </span></span><span>-286# timerfd_settime - 设置定时器文件描述符</span></div></div><div><div><div>347</div></div><div><span><span>  </span></span><span>-287# timerfd_gettime - 读取定时器文件描述符</span></div></div><div><div><div>348</div></div><div><span><span>  </span></span><span>-288# accept4 - 接受带标志的连接</span></div></div><div><div><div>349</div></div><div><span><span>  </span></span><span>-289# signalfd4 - 改进的signalfd</span></div></div><div><div><div>350</div></div><div><span><span>  </span></span><span>-290# eventfd2 - 改进的eventfd</span></div></div><div><div><div>351</div></div><div><span><span>  </span></span><span># 文件系统操作</span></div></div><div><div><div>352</div></div><div><span><span>  </span></span><span>-291# epoll_create1 - 改进的epoll_create</span></div></div><div><div><div>353</div></div><div><span><span>  </span></span><span>-292# dup3 - 改进的dup2</span></div></div><div><div><div>354</div></div><div><span><span>  </span></span><span>-293# pipe2 - 改进的pipe</span></div></div><div><div><div>355</div></div><div><span><span>  </span></span><span>-294# inotify_init1 - 改进的inotify_init</span></div></div><div><div><div>356</div></div><div><span><span>  </span></span><span>-295# preadv - 向量化的pread</span></div></div><div><div><div>357</div></div><div><span><span>  </span></span><span># 向量I/O操作</span></div></div><div><div><div>358</div></div><div><span><span>  </span></span><span>-296# pwritev - 向量化的pwrite</span></div></div><div><div><div>359</div></div><div><span><span>  </span></span><span>-297# rt_tgsigqueueinfo - 排队实时信号到线程组</span></div></div><div><div><div>360</div></div><div><span><span>  </span></span><span>-298# perf_event_open - 性能监控</span></div></div><div><div><div>361</div></div><div><span><span>  </span></span><span>-299# recvmmsg - 接收多个消息</span></div></div><div><div><div>362</div></div><div><span><span>  </span></span><span>-300# fanotify_init - 初始化fanotify</span></div></div><div><div><div>363</div></div><div><span><span>  </span></span><span># 文件系统通知</span></div></div><div><div><div>364</div></div><div><span><span>  </span></span><span>-301# fanotify_mark - 管理fanotify标记</span></div></div><div><div><div>365</div></div><div><span><span>  </span></span><span>-302# prlimit64 - 获取/设置资源限制</span></div></div><div><div><div>366</div></div><div><span><span>  </span></span><span>-303# name_to_handle_at - 文件句柄操作</span></div></div><div><div><div>367</div></div><div><span><span>  </span></span><span>-304# open_by_handle_at - 通过文件句柄打开</span></div></div><div><div><div>368</div></div><div><span><span>  </span></span><span>-305# clock_adjtime - 调整系统时钟</span></div></div><div><div><div>369</div></div><div><span><span>  </span></span><span># 同步操作</span></div></div><div><div><div>370</div></div><div><span><span>  </span></span><span>-306# syncfs - 同步文件系统</span></div></div><div><div><div>371</div></div><div><span><span>  </span></span><span>-307# sendmmsg - 发送多个消息</span></div></div><div><div><div>372</div></div><div><span><span>  </span></span><span>-308# setns - 设置命名空间</span></div></div><div><div><div>373</div></div><div><span><span>  </span></span><span>-309# getcpu - 获取CPU和NUMA节点</span></div></div><div><div><div>374</div></div><div><span><span>  </span></span><span>-310# process_vm_readv - 进程间读取数据</span></div></div><div><div><div>375</div></div><div><span><span>  </span></span><span># 进程间通信</span></div></div><div><div><div>376</div></div><div><span><span>  </span></span><span>-311# process_vm_writev - 进程间写入数据</span></div></div><div><div><div>377</div></div><div><span><span>  </span></span><span>-312# kcmp - 内核比较两个进程</span></div></div><div><div><div>378</div></div><div><span><span>  </span></span><span>-313# finit_module - 从文件描述符加载内核模块</span></div></div><div><div><div>379</div></div><div><span><span>  </span></span><span>-314# sched_setattr - 设置调度属性</span></div></div><div><div><div>380</div></div><div><span><span>  </span></span><span>-315# sched_getattr - 获取调度属性</span></div></div><div><div><div>381</div></div><div><span><span>  </span></span><span># 安全计算</span></div></div><div><div><div>382</div></div><div><span><span>  </span></span><span>-316# renameat2 - 扩展的重命名操作</span></div></div><div><div><div>383</div></div><div><span><span>  </span></span><span>-317# seccomp - 设置安全计算模式</span></div></div><div><div><div>384</div></div><div><span><span>  </span></span><span>-318# getrandom - 获取随机数</span></div></div><div><div><div>385</div></div><div><span><span>  </span></span><span>-319# memfd_create - 创建匿名文件</span></div></div><div><div><div>386</div></div><div><span><span>  </span></span><span>-320# kexec_file_load - 从文件加载新内核</span></div></div><div><div><div>387</div></div><div><span><span>  </span></span><span># 命名空间操作</span></div></div><div><div><div>388</div></div><div><span><span>  </span></span><span>-321# bpf - 扩展的BPF系统调用</span></div></div><div><div><div>389</div></div><div><span><span>  </span></span><span>-322# execveat - 相对路径执行程序</span></div></div><div><div><div>390</div></div><div><span><span>  </span></span><span>-323# userfaultfd - 用户页错误处理</span></div></div><div><div><div>391</div></div><div><span><span>  </span></span><span>-324# membarrier - 发出内存屏障</span></div></div><div><div><div>392</div></div><div><span><span>  </span></span><span>-325# mlock2 - 改进的内存锁定</span></div></div><div><div><div>393</div></div><div><span><span>  </span></span><span># 套接字操作</span></div></div><div><div><div>394</div></div><div><span><span>  </span></span><span>-326# copy_file_range - 复制文件范围</span></div></div><div><div><div>395</div></div><div><span><span>  </span></span><span>-327# preadv2 - 带标志的向量化pread</span></div></div><div><div><div>396</div></div><div><span><span>  </span></span><span>-328# pwritev2 - 带标志的向量化pwrite</span></div></div><div><div><div>397</div></div><div><span><span>  </span></span><span>-329# pkey_mprotect - 设置内存保护键</span></div></div><div><div><div>398</div></div><div><span><span>  </span></span><span>-330# pkey_alloc - 分配内存保护键</span></div></div><div><div><div>399</div></div><div><span><span>  </span></span><span># 内存保护</span></div></div><div><div><div>400</div></div><div><span><span>  </span></span><span>-331# pkey_free - 释放内存保护键</span></div></div><div><div><div>401</div></div><div><span><span>  </span></span><span>-332# statx - 扩展的文件状态</span></div></div><div><div><div>402</div></div><div><span><span>  </span></span><span>-333# io_pgetevents - 获取异步I/O事件</span></div></div><div><div><div>403</div></div><div><span><span>  </span></span><span>-334# rseq - 重启序列</span></div></div><div><div><div>404</div></div><div><span><span>  </span></span><span>-335# pidfd_send_signal - 通过文件描述符发送信号</span></div></div><div><div><div>405</div></div><div><span>proxy:</span></div></div><div><div><div>406</div></div><div><span><span>  </span></span><span>socks5:''</span></div></div><div><div><div>407</div></div><div><span><span>  </span></span><span>http:''</span></div></div><div><div><div>408</div></div><div><span><span>  </span></span><span>https:''</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>
<section><h3>**02.**数据库连接<a href="#02数据库连接"><span>#</span></a></h3><p>数据库连接不上也是麦金叔粉丝里面问的比较多的问题，但是各种情况都有。写出来是为了后面再有类似问题的朋友，可以对号自行解决。</p><p><strong>1.从dify.ai企图连接本地数据库</strong></p><p>这个问题，不是不能解决，但主要吧，是没有理解网络的访问到底是咋回事。</p><p>就给两个解决方案吧。</p><p>第一个方案，可以从云服务商那里购买一个ECS装个可以公网访问的数据库(mysql或者postgres)，或者直接就买mysql数据库。这样得到了公网访问的数据库连接地址。就可以在dify.ai的工作流里面配置连接了。当然需要注意数据库暴露在公网上，要进行安全配置，否则很容易被别人滥用。</p><p>第二个方案，离开dify.ai。自己本地搭一个dify的环境。参考这篇文章。</p><p><a href="https://mp.weixin.qq.com/s?__biz=MzAxNjQxMTQ3NA==&amp;mid=2452385010&amp;idx=1&amp;sn=ba365fc791ee731697a897c1563ed9d3&amp;scene=21#wechat_redirect" target="_blank">AI实践之Plan B：本地搭建运行环境(3)</a></p><p>最后的方案，是通过本地的端口代理，让dify.ai可以访问本地的数据库，但是这个不推荐一般人用了。除非你真的想学习使用，那就后台找小助手吧。</p><p><strong>2.本地localhost连接不上</strong></p><p>因为大家使用docker或者docker compose来部署dify，所在的环境不同。特别是使用windows的，正常的localhost有时候连不上docker内的数据库。</p><p>这是docker的网络问题，可以把uri中的localhost改成host.docker.internal，尝试一下。</p><p>如果还是不行，那就找到本地局域网地址（如192.168.xxx，172.16.xxx等），再尝试。</p><p><strong>3.Internal Server Error</strong></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/734cb0caf2294710aaa84e87fd8d5218640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>这种因为粉丝朋友也没有提供非常有效的信息。但可以尝试卸载database插件。重启后，再重新安装database插件来解决。貌似问这个粉丝后面就好了。</p><p><strong>4.授权错误</strong></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/0f7b2006a80c45a9892b3f8b3517cc8c640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>绝大部分报这个非法授权问题，都是因为database插件连不上数据库导致的。实际上可以参考上面第1，第2条解决。但是有时候并不是数据库连不上，而是uri没写对。注意格式，另外最新版本的插件已经可以支持mysql，postgres，sqlite，mssql和oracle了。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>mysql+pymysql://root:123456@localhost:3306/test</span></div></div><div><div><div>2</div></div><div><span>postgresql+psycopg2://postgres:123456@localhost:5432/test</span></div></div><div><div><div>3</div></div><div><span>sqlite:///test.db</span></div></div><div><div><div>4</div></div><div><span>mssql+pymssql://&lt;username&gt;:&lt;password&gt;@&lt;freetds_name&gt;/?charset=utf8</span></div></div><div><div><div>5</div></div><div><span>oracle+oracledb://user:pass@hostname:port[/dbname][?service_name=&lt;service&gt;[&amp;key=value&amp;key=value...]]</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>格式如上，数据库类型+驱动，然后冒号后双斜杠，用户名，密码，再是数据库地址和端口，最后使用的数据库库名也要写上。</p><p><strong>总结</strong></p><p>今天的答疑全部来自网友的留言问题，有些错误是麦金叔未成设想到的。不过这也给麦金叔提了个醒，很多人其实愿意尝试动手做的，但是因为这当中有非常多的困难，不知道哪一个问题就会困住。然后就放弃了，其实也许再坚持一下，问一问，查一查，就解决了。</p><p>麦金叔当初写这一些列的文章的时候，就没想着要搞知识付费，真心希望粉丝们，能都踏上AI应用的东风，为自己提高职场竞争力。当然，能顺手点个赞，收藏，转发一下，麦金叔也是非常高兴的。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/abc6a1e7/</id>
      <title type="text">大模型的得力干将MCP(1) - 基础入门</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/abc6a1e7/"/>
      <summary type="text">本文系统解析MCP协议核心架构与实战应用。详解主机-客户端-服务器三元组模型，对比stdio/SSE双模通信机制差异。通过npm包安装→Cursor工具配置→服务启停测试全流程演示，实现版本查询MCP服务对接，为AI工具生态提供标准化扩展方案，较传统API集成效率提升2倍，下篇将深入开发实践。</summary>
      <content type="html"><![CDATA[<p>上一节Dify应用实战课，我们学习了如何将数据表生成图，可以更直接的展示数据的意义。</p>
<p>今天我们将暂时将Dify的学习搁置一下。来学习AI工具中重要的一个知识：MCP(Model Context Protocol)。</p>
<p>等系列课学习完成，你将能了解什么是MCP，如何开发MCP和如何实际使用它（当然我们会回归到Dify中，配合LLM，更加完善我们的AI应用适用场景）。</p>
<section><h3>**01.**基础概念<a href="#01基础概念"><span>#</span></a></h3><p>MCP(Model Context Protocol)是一种开放协议，它标准化了应用程序如何为LLM提供上下文。</p><p>将MCP想象成AI应用程序的USB-C端口。正如USB-C提供了一种将设备连接到各种外围设备和配件的标准化方式一样，MCP也提供了一种将AI模型连接到不同数据源和工具的标准化方式。</p><p>它是去年11月才被Claude公司提出来的，但是不到半年时间，基于MCP的生态就如雨后春笋般涌现。过去以API方式提供服务的传统互联网，迅速拥抱这一变化，大量的MCP服务被开发，开源和提供出来。</p><p>要想开发MCP应用，首先需要了解的是其架构和几个重要的概念。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/85620ae849a54ca8b01f49f96ac3a306640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>简单的图示中，提到了主机，客户端和服务器。</p><section><h4>1 主机<a href="#1-主机"><span>#</span></a></h4><p>MCP主机(MCP Hosts)：发起请求的LLM应用程序(例如Cursor、IDE或AI工具)。</p><p>其中核心的能力就是LLM有Function Calling的能力，但是为了解决现有Function Calling的使用过程中，需要与LLM节点绑定的问题，便通过剥离的方式，让其成为一个钩子，配合其他两个部分来完成任务。</p></section><section><h4><strong>2 客户端</strong><a href="#2-客户端"><span>#</span></a></h4><p>MCP客户端(MCP Clients)：在主机程序内部，与MCP server保持1&lt;1的连接&gt;。</p><p>通过MCP的协议，通常有两种形式：stdio和sse的方式与服务器进行连接通信。后面也会解释这两种方式的区别和优缺点。</p></section><section><h4>3 服务器<a href="#3-服务器"><span>#</span></a></h4><p>MCP服务器(MCP Servers)：为MCP client提供上下文、工具和prompt信息。</p><p>服务器类似原先提供API服务的模块，它与本地文件，数据库或者其他公共服务API进行交互，来最终完成数据处理或者信息查询等工作，并提供结果数据。</p><p>通过以上几个组件的拆解，LLM就能像调用Function Calling一样，完成特定任务的处理。而MCP Servers可形成公共服务，不必直接绑定到特定LLM节点。</p></section></section>
<section><h3>**02.**动手做一做<a href="#02动手做一做"><span>#</span></a></h3><p>为了测试，我们需要先准备一个MCP Server。在不清楚如何使用的前提下，我们可以使用现成的开源项目。如下，是一个查询应用程序版本的服务。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/18d1647ec78a401db459fb976b9f20eb640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>//安装命令</span></div></div><div><div><div>2</div></div><div><span>npm install mcp-package-version -g</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>//配置JSON</span></div></div><div><div><div>5</div></div><div><span>{</span></div></div><div><div><div>6</div></div><div><span>"mcpServers": {</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>"mcp-package-version": {</span></div></div><div><div><div>8</div></div><div><span><span>      </span></span><span>"command": "node",</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>"args": [</span></div></div><div><div><div>10</div></div><div><span><span>        </span></span><span>"C:/Users/USERNAME/AppData/Roaming/npm/node_modules/mcp-package-version/build/index.js"</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>]</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>13</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>14</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>node版本需要v16以上，执行上述npm命令安装进全局，最终包的路径为</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>C:/Users/USERNAME/AppData/Roaming/npm/node\_modules/mcp-package-version</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>打开cursor，进入设置，如上图所示，先点”1”，进入MCP配置。然后点”2”，添加一个MCP服务。</li>
</ol><p>如果没有设置过，会在C:/Users/USERNAME/.cursor目录下生成一个mcp.json的文件，将上面json复制进去(记得改一下USERNAME为自己实际电脑的路径)。</p><p>图中”3”点一下，使其显示”Enabled”。这时点”5”的位置，就会启动本地MCP服务，此时电脑会弹出一个node的窗口，一定不要关闭，留着它。</p><p>如果需要修改配置，可以点”4”的位置，进入JSON编辑。</p><p>如果上述操作都完成，可以看到”6”的位置”mcp-package-version”前面有一个绿色的小圆点。如果这个小圆点是空心的，需要再点一下”3”位置的”Disabled”。如果这个小圆点是红色的，说明服务还没有起来，需要再点一下”5”位置的图标。</p><p>如果正常，那么”7”位置，tools会列出所有可用的工具。反之，没有显示东西，就是没成功。请检查设置，特别是”command”和”args”，是否正确。</p><p>测试一下是否工作正常。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/4d3e09ccd00741d098b8a3fec84d483f640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>切换到Agent模式，然后输入问答。得到本地电脑正确的信息，如上图所示。</p><p><strong>总结</strong></p><p>今天学习了基本的MCP的概念，并动手成功跑了一个例子。理解最简单的MCP服务如何操作，使其能被大模型使用。但是，还有更多的MCP的概念没有引入，后面的文章将继续探讨，敬请期待。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/ac80f20e/</id>
      <title type="text">Dify应用实战(18) - 发布成MCP服务</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/ac80f20e/"/>
      <summary type="text">本文实战演示Dify工作流服务化能力。通过SSE插件配置→工作流发布为MCP工具→DeepChat客户端集成测试，实现AI应用跨平台调用。详解服务端点创建及SSE协议对接流程，展示如何将本地工作流转化为标准化API服务，为智能助手、业务系统集成等场景提供轻量级解决方案，服务部署效率较传统开发模式提升3倍。</summary>
      <content type="html"><![CDATA[<p>今天我们将要继续企业应用之旅，让Dify自己也变成为MCP服务，成为助手类工具或者现有系统的定制化AI工具服务。</p>
<p>学习完成，你将能让自己的桌面助手工具，集成最近一段时间辛苦创建的Dify应用。这样就可以暂时不去Dify的控制台去使用工作流了。</p>
<section><h3>**01.**准备环节<a href="#01准备环节"><span>#</span></a></h3><p>在我们开始之前，有需要安装一个工具。感谢伟大的开源作者们的奉献，这个世界因你们而精彩。</p><p>去插件-&gt;marketplace，搜一下SSE，看到下图这个插件，就安装一下。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/a95b2432001e4b18b65f902d94837bff640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>至此，所有今天需要的准备就完成了，恭喜！</p></section>
<section><h3>**02.**动手做一做<a href="#02动手做一做"><span>#</span></a></h3><p>找到之前实战的案例：“图片生成”，简单裁剪一下。然后去发布那里，发布为工具。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/1f2ebce871e349298ab6f9a1048fc026640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>按照下图所示，输入一个工具调用名称，并且描述写好，最好详细一点，能让大模型理解这个工具到底是干啥的。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/8a374f1c54114cbe8acdffb77309e2f5640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>此时在Dif有点工作流里，应该就出现这个应用了。</p><p>接着开始配置新安装的插件。</p><p>进入插件，找到它”MCP Compatible Dify Tools”，点击之后，会出现在页面右边。这时继续点击”API端点”右侧的加号。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/09e7df87819a4fa7ac180c1fe875b37e640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>就会进入端点配置页。填入端点名称，可以随意输入。然后点击”工具列表”右侧的加号。在弹出”添加工具”的配置项里，按照下图顺序，依次切换到”工作流”，选中前面发布的工具的那个工作流。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/4e5e72ad901a4309a705cbd5422da217640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>这时基本上就配置完成了，点击”保存”。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/0500aa3a33de45eca294928d8a0be5d9640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>看到下图界面，就说明这个工具就已经开始工作了。点击GET那一行后面的复制按钮，将URL复制出来，留着备用。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/178215de29cd4ed7b71100e1ec265d8f640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h3>**03.**应用和测试<a href="#03应用和测试"><span>#</span></a></h3><p>经过上面的操作，Dify就已经化身为一个SSE的MCP服务了。那么最后一步就是验证这个工具是否真正的可用。</p><p>这次我们依然选择开源的DeepChat工具。先去配置一下MCP。添加服务器的页面先点”跳过至手工配置”，然后输入服务器名，可以随便输入，如”dify”，然后服务器类型，下拉选择服务器发送事件SSE模式，基础URL填入，上面留着备用的那个地址。但是需要把localhost改为Dify服务器的服务IP。如下图所示</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/bea65bafbd294b0da3a325c46de4c32f640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>提交之后，切换到chat界面，点击小锤子，可以看到刚刚配置的工具是可用状态了。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/af2abc136dde444e80b934324ef0379d640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>终于，来到了激动人心的环节。对话框输入”虹口区天气怎么样？“，一切都会按照预期的那样，大模型去找了一圈工具，发现有一个天气预报服务的工具，然后把控制权交给了Dify的工作流，工作流开始按照开发AI应用的步骤执行，最后输出了结果。然后本地工具DeepChat也拿到了最后的结果，并展示了调用过程中使用工具的情况。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/5d004864a21d40e1943fe59805612f9d640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p><strong>总结</strong></p><p>今天学习了将Dify系统开发的AI应用变成可供其他工具或者系统调用的MCP服务，从而打通了系统之间的壁垒。你的Dify应用将会直接为你的助手类工具使用，或者集成到现有应用中，能扩展其AI能力。</p><p>终于MCP相关的话题可以告一段落了。从MCP是什么，到怎么开发，然后是怎么使用MCP，最后是自己化为MCP。期望读者能顺着麦金叔的脉络，真正的把这些学会，并融会贯通投入到自己的项目中。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/acf87292/</id>
      <title type="text">Dify应用实战(7) - 图片生成(下)</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/acf87292/"/>
      <summary type="text">本文完整演示了在Dify工作流中实现动态图文生成的技术方案。通过Figma设计模板结合imgrender插件导出JSON结构，详解了模板节点中字体、坐标、背景图等参数的配置原理。实战演示了如何构造HTTP请求调用第三方渲染服务，包括API密钥配置、请求头设置及JSON数据组装，并通过Python代码节点解析图片URL。该方案成功将实时天气数据与设计模板结合，输出带动态文本的简报图片，为自动化报告生成、电商海报制作等场景提供可复用的技术实现路径，下篇将深入探讨第三方服务对接细节与错误处理机制。</summary>
      <content type="html"><![CDATA[<section><h3>**01.**环境准备<a href="#01环境准备"><span>#</span></a></h3><blockquote><p>大家通过昨天的教程，已经知道如何生成图片，并看到了最终效果。但是为什么要按照这样的流程进行编写，还是知其然，不知其所以然。</p><p>那今天麦金叔就给大家还原一下真相。</p><p>因为前面也提到了，这次的动手依赖两个第三方的服务工具。因此，如果想自己动手的，先把账号注册好吧。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/d1923b77442c411d8a946af628d95c5b640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>注册成功后直接来到了控制台页面，此时按图创建应用。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/e10b4030a1a84c9095faed59cbc8b695640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>继续点击新创建的一串数字APPID的应用，打开”应用详情”。可以看到现在API密钥这里是空的，点击右方”新增密钥”，获得一条记录。页面显示一长串数字字母的字符串，右边有个复制按钮，点一下复制保存到安全的地方，留着备用。</p><p>再说一下，这个服务宣称是免费，但实际上是每个账号每月有1000次的免费处理次数，正常使用基本上算免费了。但如果你的业务需求量很大，可以购买资源包，也不贵，一张图5厘，已经蛮良心的了。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/1b14138f6da64e9ea98b88075913bf0b640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>按图所示注册figma，这个是美丽国的服务工具，虽然有一些不好的名声，但是在设计SaaS服务领域还是发展很快的。我们用它纯属”白嫖”，不用有太多顾虑。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/896dc56fd82d4e64930ccb4da12300e7640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>注册后，下载一个包装的桌面版。然后记住这个插件，等下就要用，Batch auto-generate images using your design</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>(<a href="https://www.figma.com/community/plugin/1273461051550664878" target="_blank">https://www.figma.com/community/plugin/1273461051550664878</a>)</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/4aadd6234b1e4a8d94a2dbe73e24853a640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>工具和插件都准备好之后，我们就继续回到Dify里面。</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h3>**02.**流程拆解<a href="#02流程拆解"><span>#</span></a></h3><section><h4>图片模板请求体构造<a href="#图片模板请求体构造"><span>#</span></a></h4><blockquote><p>昨天只说了需要构建一个图片模板的请求体JSON。但这个JSON为何是这样构建的呢？如果靠手写那肯定是不现实的，好在方法也很简单。</p><p>我们先在figma里做一个图片的布局，如示例里面，有一个背景图，再有一段文案（为了教学，尽量简单处理了，实际应用时，只是元素对象多一点而已）。先新建一个”Design file”</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/514b929b909a4d588f3158388bcc4e08640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>在空白画布上添加一个Section，注意将Dimensions的W和H（即图片的宽和高）设置为你最终生成的图片的分辨率大小。并将Posion的X和Y都设置为0，即左上角对齐原点。</p><p>好了，图片第一层为背景层，准备好一张与图片大小一致的底图，通过工具栏的Image进行插入。Position也设置为0，这样就对齐了。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/fd6e5b446117432dbd0b626308723605640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>在背景图上添加”TEXT”，并将其拖拽到画布合适的位置，注意文本的Posion位置，和长宽值，是否合适。可以事先添加与文案长度差不多的文字内容，来观察是否能一行显示，还是要多行。一定要确保最终生成时不要超出背景图片的区域。</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/ea4302dfe8c647bb912bee826df1eb2a640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>本文的示例就这两个元素，实际工作，需要酌情修改设计。这一步如果有设计师朋友帮忙，那就小菜一碟了。</p><p>有了设计稿，现在利用上面让准备的插件，就能将设计转化成JSON。选中整个设计，左上角的菜单，转到Plugins菜单项，点击”imgrender - Batch auto-generate”。便会打开一个小对话框，点”Output”按钮。如果提示”Successful!”字样，就说明好了。</p><p>这时，需要打开一个文本编辑软件，按Ctrl V就可看到全部内容。如果过程中有问题，看提示解决。大概是导出只能是一层，如果设计放在多层，是不能全部导出的。</p></blockquote><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"width"</span><span>: </span><span>420</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>"height"</span><span>: </span><span>600</span><span>,</span></div></div><div><div><div>4</div></div><div><span>  </span><span>"backgroundColor"</span><span>: </span><span>"#ffffff"</span><span>,</span></div></div><div><div><div>5</div></div><div><span>  </span><span>"images"</span><span>: [</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>7</div></div><div><span>      </span><span>"x"</span><span>: </span><span>0</span><span>,</span></div></div><div><div><div>8</div></div><div><span>      </span><span>"y"</span><span>: </span><span>0</span><span>,</span></div></div><div><div><div>9</div></div><div><span>      </span><span>"width"</span><span>: </span><span>420</span><span>,</span></div></div><div><div><div>10</div></div><div><span>      </span><span>"height"</span><span>: </span><span>600</span><span>,</span></div></div><div><div><div>11</div></div><div><span>      </span><span>"url"</span><span>: </span><span>"背景图URL"</span><span>,</span></div></div><div><div><div>12</div></div><div><span>      </span><span>"zIndex"</span><span>: </span><span>1</span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>14</div></div><div><span><span>  </span></span><span>],</span></div></div><div><div><div>15</div></div><div><span>  </span><span>"texts"</span><span>: [</span></div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>17</div></div><div><span>      </span><span>"x"</span><span>: </span><span>60</span><span>,</span></div></div><div><div><div>18</div></div><div><span>      </span><span>"y"</span><span>: </span><span>60</span><span>,</span></div></div><div><div><div>19</div></div><div><span>      </span><span>"text"</span><span>: </span><span>"文案文案文案文案文案"</span><span>,</span></div></div><div><div><div>20</div></div><div><span>      </span><span>"width"</span><span>: </span><span>240</span><span>,</span></div></div><div><div><div>21</div></div><div><span>      </span><span>"font"</span><span>: </span><span>"SourceHanSansSC-Normal"</span><span>,</span></div></div><div><div><div>22</div></div><div><span>      </span><span>"fontSize"</span><span>: </span><span>16</span><span>,</span></div></div><div><div><div>23</div></div><div><span>      </span><span>"textAlign"</span><span>: </span><span>"left"</span><span>,</span></div></div><div><div><div>24</div></div><div><span>      </span><span>"zIndex"</span><span>: </span><span>4</span><span>,</span></div></div><div><div><div>25</div></div><div><span>      </span><span>"color"</span><span>: </span><span>"#000000"</span></div></div><div><div><div>26</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>27</div></div><div><span><span>  </span></span><span>]</span></div></div><div><div><div>28</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><blockquote><p>有了这个设计模板JSON，现在就可以去Dify的模板节点去拼接了。</p><p>拆分成几个部分就行了，记得images里面的url改为一个imgrender服务能访问到的公网背景图片路径。</p><p>texts里面的元素，text部分，用Jinja模板语法，将前序节点的输出string替换为上述JSON里面的”文案文案文案文案文案”。</p></blockquote></section><section><h4>HTTP请求构造<a href="#http请求构造"><span>#</span></a></h4><blockquote><p>再坚持一下，马上就要成功了。</p><p>“HTTP请求”按上篇中的截图设置。</p><p>API方法选择POST，地址为imgrender的服务地址：<a href="https://api.imgrender.net/open/v1/pics" target="_blank">https://api.imgrender.net/open/v1/pics</a> ，添加鉴权API-key，改为自定义，Header项填入X-API-Key，key就粘贴前面新建应用时得到的新增密钥。</p><p>保存后，继续设置HTTP请求。
HEADERS增加key为Content-Type，value为application/json; charset=utf-8</p><p>BODY，选择raw，值框中输入/ 后选择合并完的output</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/8f4dae3f97c5407a89e5ea7ba602d759640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><blockquote><p>如果有使用HTTP服务的经验，这一点非常容易做。</p></blockquote></section><section><h4>获取结果图片<a href="#获取结果图片"><span>#</span></a></h4><blockquote><p>这个”代码执行”节点，继续使用Python，代码非常简单，就是从imgrender的API请求结果中，获得图片URL。</p><p>好了，今天的内容终于结束了。其中最繁琐的是图片模板的处理。全程无尿点，累并快乐着。</p></blockquote></section></section>
<section><h3><strong>总结</strong><a href="#总结"><span>#</span></a></h3><blockquote><p>今天在对有预期效果的工作流上，详细解释了其中节点的设计思路，并完整详细的讲解了操作过程最后利用图片生成服务得到了我们期望的带背景和文案的结果图片。还是昨天麦金叔说的，最终成品效果如何，就依赖设计能力了。</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/b06e29fc/</id>
      <title type="text">Dify应用实战番外 - 网友提问(2)</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/b06e29fc/"/>
      <summary type="text">本文实战解析Dify沙箱环境配置要点。针对代码节点依赖缺失与权限受限问题，详解通过requirements.txt安装第三方库→修改config.yaml授权系统调用→自定义镜像编译三套解决方案，展示如何突破沙箱执行限制。为数据处理、系统监控等场景提供Python脚本集成方案，较传统调试方式效率提升60%。</summary>
      <content type="html"><![CDATA[<section><h3>**01.**动手做一做<a href="#01动手做一做"><span>#</span></a></h3><p>随便创建一个工作流。添加”代码执行”和”结束”。</p><p>并填入代码如下：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/5b2a4daac78a4ae8aadb40752984e920640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>保存后进行测试。结果如下图：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/35ec0fe0cb3748a39c74250c86ad1ef9640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>提示非常清楚，就是找不到依赖库pandas。</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>那我们就把库安装上，因为运行时是由sandbox提供的，所以我们找到docker-compose.yaml中sandbox的定义。其中有个卷的映射，</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>./volumes/sandbox/dependencies:/dependencies</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>这里就是我们添加依赖的地方。工程目录下docker/volumes/sandbox/dependencies下有一个空文件python-requirements.txt</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>输入一行"pandas==2.2.3"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>重启docker服务，查看docker-sandbox-1的日志，会看到在启动sandbox时，会安装第三方库。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/5ed3428d0ee847bfad0522b815f330b9640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>重新运行”工作流”(如果还报错找不到pandas，需要等待一会儿，安装有可能还没有完成，一定要看到sandbox的log里面显示python dependencies installed)。发现已经不再报错找不到pandas，而是提示另外一个错误。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/7f6f8cd942dd4177bd25f03f0fccc9ed640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>绝望了呀，赶紧问问DeepSeek和豆包是咋回事啊。</p><p>好的，它们都说是沙盒环境的权限限制导致的，但好歹也要给出如何修改的建议吧？对不起，没有，请自行解决。</p><p>这下难题还是留给了麦金叔，只能硬着头皮上了。</p></section>
<section><h3>**02.**解决沙盒权限<a href="#02解决沙盒权限"><span>#</span></a></h3><p>通过官方dify-sandbox开源项目的FAQ，知道由于怕沙盒权限太大，导致不可控风险，所以本着最小化开放权限的原则，缺省的权限就很小。</p><p>知道问题的根结，那应该就很好解决了。</p><p><strong>方案一</strong></p><p>和刚才添加依赖一样，工程目录下docker/volumes/sandbox/conf里面有一个config.yaml文件，找到allowed_syscalls段，把需要的权限加进去。</p><p>重新启动服务之后，测试就通过了。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/8c42faeaca644d209c2665bebdb60df1640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p><strong>方案二</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>修改源代码，/internal/static/python\_syscall/syscalls\_amd64.go</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>把所需要的权限都添加进去，这里是以syscall开头的枚举值。如果出现所需要的权限没有定义，也不要紧，直接写数值也可以的。</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>改完了之后，需要重新编译dify-sandbox镜像。并将自己编译的镜像tag，替换进docker-compose.yaml。</p><p>重新启动服务后，也可以运行。</p><p>这个方法适用于所有没有权限执行的第三方库。</p><p>不过Dify的”代码执行”最好不要有太过复杂的脚本执行，一个是难以调试，另一个也是容易执行超时。</p><p>如果很依赖Python执行，可以按照”插件”的方案。将其封装为一个插件，每个插件也可以定义自己的requirements。这样也就不用怕没有权限了。</p><p><strong>总结</strong></p><p>今天的答疑来自网友的留言问题，当然有可能他说的Python脚本不能执行的问题，还不是这篇文章介绍的。请务必要理解，Dify的Python执行环境是独立的，和本机的Python环境没有关系，哪怕就是本机运行的容器环境。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/bec72e7f/</id>
      <title type="text">Dify应用实战(8) - 对话记忆</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/bec72e7f/"/>
      <summary type="text">本文实战演示如何基于Dify Chatflow构建智能医疗分诊助手。通过配置对话开场白、LLM节点上下文参数及记忆窗口设置，实现多轮对话记忆能力。结合医疗场景Prompt工程，无需复杂代码即可创建具备病因追问、科室推荐和无关话题引导功能的门诊机器人。详解Transformer架构的自注意力机制如何支撑对话连贯性，为智能客服、健康咨询等场景提供开箱即用的对话系统解决方案，后续将结合知识库增强专业领域应答能力。</summary>
      <content type="html"><![CDATA[<blockquote><p>今天我们开启一个新的项目 — 智能医疗分诊助手。</p><p>学习完成，你将掌握如何构建多轮对话应用，获得更为准确的信息，以实现特定的任务。</p></blockquote>
<section><h3>**01.**动手做一做<a href="#01动手做一做"><span>#</span></a></h3><p>暂时先将之前的案例放一放，大家需要新建一个对话流。放心，之前的图文生成和语音项目还未最终完成，但已经变得有点复杂了。如果是刚开始学的同学，可能有点跟不上。所以，我们为了降低难度，先再开启一个新项目，把没学的内容补齐。</p><p>最后会做完完整版的工作流。麦金叔先卖个关子，记得点赞、关注、收藏不迷路。</p><p>今天我们来动手做一做智能医疗分诊助手”医小智”的开发。</p><p>还是老规矩，这次我们选新建空白应用，类型用”Chatflow”。这其实和Workflow是差不多的，只是有一点差异，Chatflow是基于对话的，并且内置了记忆能力，即能将多轮对话的历史记忆保存并传递给下一轮对话。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/2263c1d0cbc94292ac1d7a954a27f7ef640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>新创建完成，自动会添加三个节点：“开始”，“LLM”和”直接回复”。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/ad8270a7d28d4e66a30db111cfcf3314640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>此时，就已经可以点击”预览”，进行对话调试了。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/891db77d778a4fcf97b1eec2d0c1b44f640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>好了，准备工作就绪，我们正式开始项目开发。</p><p>“医小智”是一台放在医院大门口的机器人，它将代替问诊台的服务人员，初步判断来医院就诊的客人，属于什么病因，引导客人去相应的科室挂号就诊。</p><p>首先，需要在客人说之前，要有欢迎和引导语。点击右上”功能”，开启”对话开场白”。这里输入的是“您好，我是您的问诊小助理，医小智。请问您哪里不舒服呢？”</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/4974de48df5e4c22bf15c6f14e68f195640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>接着，需要对”LLM”节点做深入的设置。</p><p>在”上下文”这里设置变量值，选择”开始”的用户输入sys.query。这里注意一下，Chatflow内置了很多输入参数，可以直接用，不像工作流，输入的参数需要自己定义。</p><p>在SYSTEM提示词这里，通过输入/符号，将上下文代入。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/0e4f3d02d500480b99ca325945891227640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>因为Chatflow内置了”记忆”，就不需要手动选择能力。并在下面记忆这里打开它，设置合适的窗口大小。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/30b21fa7069d4350b78e508d447a93b4640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>完成之后，点击”发布”进行保存，就可以进行测试了。</p><p>点击”发布”按钮后，选择”运行”。会开启一个新的页面，点”Start Chat”，即开启对话。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/200769e74d04469089f1699196d6e294640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>得到机器人的欢迎词后，我们输入第一轮的对话。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/25d07c6c17d34c18a67d3c901672736a640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>可以继续对话。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/3c544e12e735408d818f4217c685277a640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>但是如果用户对话输入不相干内容，看智能客服如何应对？</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/17e2aa0beb6e43bf9386857f8cfeeba5640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>今天的动手做就完成了。下面讲解一下里面关键的知识点。</p></section>
<section><h3>**02.**补充说明<a href="#02补充说明"><span>#</span></a></h3><p>今天的应用非常简单，但是效果却非常棒。有同学会很好奇，这也太神奇了吧，都不需要用Function Call或者RAG就能为指定的医院提供个性化的门诊导流服务。</p><p>那为什么仅仅是用Prompt提示词，就可以完成呢？这里就不得不介绍一下大语言模型的基础能力知识，Transformer架构了。</p><p>而Transformer模型是基于自注意力机制的深度学习模型。能让AI理解你的提问，并回答准确，就需要计算机模仿人类的行为。</p><p>在你阅读一本书的时候，当读到某个句子，你的大脑会自动关注句子中的关键词，并将这些关键词与前面提到的信息联系起来，从而理解整个句子的含义。自注意力机制就是模仿这种人类阅读理解过程的一种算法。</p><p>简单来说，自注意力机制允许模型在处理序列数据（如句子）时，自动找出序列中各个元素之间的关联。它能够让模型在处理某个位置的信息时，同时考虑到整个序列中的其他相关信息，而不仅仅是附近的信息。</p><p>自注意力机制是一种强大的序列建模技术，它通过计算元素之间的相似度，让模型能够聚焦于重要的信息，并忽略无关的噪声。这种机制在自然语言处理、计算机视觉、语音处理等领域都有着广泛的应用和显著效果。</p><p>它为序列数据的处理提供了新的思路和方法，使得模型能够更好地理解和利用序列中的信息，从而推动人工智能技术的进步和发展。</p><p>原理讲解比较无趣，如果不感兴趣可以忽略。</p><p><strong>总结</strong></p><p>今天又开启了一种新应用类型 — “Chatflow”的学习。它封装了和对话相关的能力。但它本质上依然是一种workflow，之前学的那些技能，也都能放进去。</p><p>通过”医小智”的实战，让你可以做出最简单的客服对话类智能体，后续会结合Dify的能力，补充进更为复杂的功能，让真正的变成一个能落地的AI应用。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/e4ba3209/</id>
      <title type="text">Dify应用实战(11) - 条件分支</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/e4ba3209/"/>
      <summary type="text">本文实战演示Dify条件分支组件的场景路由能力。通过在医疗分诊流程中集成LLM节点生成结构化JSON→代码节点提取类型参数→条件分支动态路由，实现眼科咨询的精准分流（近视/眼疾/其他）。详解基于数据驱动的分支配置方法，展示如何通过可视化编排处理多路径业务逻辑，为智能客服、健康管理等需要决策树的场景提供轻量级解决方案，较传统分类器减少70%大模型调用开销。</summary>
      <content type="html"><![CDATA[<p>本文适用对象：初级水平</p>
<p>目标：对一个结果可能出现多种情况，进行条件分支处理</p>
<p>上一节Dify应用实战课，我们学习了迭代循环处理。而新项目，智能医疗分诊助手，暂停了一期，现在我们继续。</p>
<p>今天我们学习和上节课循环处理类似的方法，分支条件处理。</p>
<p>学习完成，你将掌握如何对一个结果可能存在多种情况时，按不同情况的值，进行不同的处理。</p>
<section><h3>**01.**动手做一做<a href="#01动手做一做"><span>#</span></a></h3><p>今天的任务基于智能分诊应用”医小助”。在”问题分类器”的”分类2”后新增一个”LLM”节点。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/0f57c11c43c54281b0be43b18d43c6e3640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>如图所示，添加提示词内容“对</p><p>提及的有关视力的部分，进一步进行识别处理，处理结果输出为如下json格式，</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{ </span><span>"type"</span><span>: </span><span>0</span><span>, </span><span>"result"</span><span>:</span><span>""</span><span>,</span><span>"raw"</span><span>:</span><span>""</span><span>}</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>如果是咨询近视有关的，将type设置为</span><span>1</span><span>；</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>如果是咨询眼睛疾病，将type设置为</span><span>2</span><span>；</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>对输入的问题的解释结果，设置为result的值。”</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这次我们把大模型的输出格式修改一下，如下图</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/62c2b9178ce54ff9aef96eb7e12ee2dc640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>接着添加”代码”节点，将上一步生成的JSON结果，提取问题类别type，注意输入和输出的变量和类型</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/301c4340bb784999a8b00f7548402c7f640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>现在我们就可以根据问题类型，来进入不同分支了。添加新节点”条件分支”。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/b8dfbc9a9f6a4981932ed81c028d5806640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>这样根据所匹配的结果，才能有不同的分支来承接。因此这里为了简化，直接都添加”回复”，来测试流程是否正确。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/abfa6a4d8a5e4b8e8ae6357ac09dfd3e640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>保存之后，我们进行测试，如下：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/b74eb624440945cd8605c9b180dfa5eb640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>可以看到，我们的对话，走到了正确的分支。</p><p>希望今天的动手分支，也能跟着麦金叔做下来。</p></section>
<section><h3>**02.**补充说明<a href="#02补充说明"><span>#</span></a></h3><p>今天学的条件分支，与上次的迭代，都是编程思想里面最重要的基础概念。</p><p>大家一定要能掌握，才能在今后的AI应用开发中，游刃有余的处理复杂的场景。</p><p>正如之前课程麦金叔一直强调的：打败你的不是AI，而是会用AI的人。麦金叔希望，你花点时间，动手练一练，成为那个打败别人的人。</p></section>
<section><h3><strong>总结</strong><a href="#总结"><span>#</span></a></h3><p>今天学习一个重要的新的组件”条件分支”。有了它在AI应用开发的”拖线条”过程中，才能真正应对复杂场景。它比问题分类器还要简单，都不需要利用大模型的能力，就能做好分类处理。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/e5673005/</id>
      <title type="text">Dify应用实战(16) - 数据可视化</title>
      <published>2025-07-23T12:32:13.000Z</published>
      <updated>2025-07-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/e5673005/"/>
      <summary type="text">本文实战演示Dify数据可视化能力。通过SQL查询获取订单处理数据→代码节点转换JSON格式→ECharts模板生成交互图表，实现企业级BI数据看板。详解SQL配置、数据清洗及可视化代码编写技巧，展示如何将自动化处理日志转化为多维度图表，为运营分析、业务监控等场景提供零代码解决方案，较传统BI工具实施效率提升60%。</summary>
      <content type="html"><![CDATA[<p>今天我们将要继续企业应用之旅，让Dify也变成一个简单的BI系统，可以让数据变成有图有真相。</p>
<p>学习完成，你将能举一反三，让数据自己说话。</p>
<section><h3>**01.**动手做一做<a href="#01动手做一做"><span>#</span></a></h3><p>今天的动手实验，需要有处理数据的代码能力。如果对你来说难度太大，建议收藏慢慢学习。</p><p>首先，我们简化核心步骤，把不相干的节点全部删除。掌握了之后，可以集成进前面课程有关数据SQL的部分</p><p>既然是和数据相关，那准备的部分必然涉及到数据库。假设我们有一个数据表名为automation，记录了企业中，对订单进行自动化处理的情况。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/27e5b38a71a74402935702e3a73f2199640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>该表设计的思路是，针对每个订单，都会进行自动化处理，并记录处理结果。并且按业务规则，运行失败时会进行一定次数的重试，以避免因资源等环境问题导致的暂时失败，而影响可以自动化的任务。</p><p>记录自动化处理的结果字段为code，0表示不符合自动化处理条件，1表示自动化处理成功，大于1的值表示自动化程序内部的错误。</p><p>我们需要按照订单的日期来查询按天统计的订单处理情况。查询语句和结果如下图所示。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/ada5cc16c4804f04889a83975851f989640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>有了上述准备之后，开始进行Dify应用开发。</p><p>添加”SQL Execute”节点(如果没有，需要安装插件后，进入工具选择，见之前的博文)，修改设置为：</p><ol>
<li>
<p>SQL查询语句：同sql query语句</p>
</li>
<li>
<p>输出格式：选Constant，JSON</p>
</li>
</ol><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/6bece23c63ba40ffa91e713f8253b772640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>新增”代码执行”节点，输入变量选上一个”SQL Execute”的json，代码内容需要对SQL查询工具输出的JSON数据进行转换，然后将变形后的数据，按照echarts的模版进行输出。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/0867e4bcd9124471966696a2c23e2195640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>最后”回复”节点的输入就选择”代码执行”的结果。</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/563e1aa1f767478abb9a965339da1a7a640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>保存之后，进行测试。因为这个简化流程没有”LLM”节点，也不依赖输入，所以可以直接执行，其结果如下：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/05/5021ccfec6874ae68f4429626cdfb8fc640%3Fwx_fmt%3Dpng%26from%3Dappmsg" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h3>**02.**补充说明<a href="#02补充说明"><span>#</span></a></h3><p>为了聚焦数据可视化的处理方法，这个流程做了最大程度的简化。所以实际生产过程中，需要理解其中的方法，进行改写变形。</p><p>1. 示例数据查询语句是写死的。</p><p>改进点：利用文生SQL，让大语言模型生成合适的SQL，并开放查询时间范围参数。比如查询一周内，或者一个月内的数据。</p><p>2.echarts图表是写死的。</p><p>改进点：可以预先定义echarts的图表样式，如折线图，或者柱状图，饼图等，以适配不同的业务需求。</p><p>希望各位网友能发挥主观能动性，进行更贴合业务需要的开发。当然，越是复杂的可视化，对开发和使用echarts的能力要求也越高。</p><p><strong>总结</strong></p><p>今天学习了将数据进行可视化生成，让AI有了图表的展示能力，更贴合企业用户的使用需求。因为示例代码较长，截图不便，想参考学习的朋友，扫描下方小助手的微信号，发送”可视化”，以获得DSL文件。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/9ac8b74a/</id>
      <title type="text">设置 WSL 开机启动并在后台运行</title>
      <published>2025-06-23T12:32:13.000Z</published>
      <updated>2025-06-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/9ac8b74a/"/>
      <summary type="text">默认情况下，启动 WSL 后需要保持启动窗口（终端）保持开启，如果关闭这个终端，WSL 会几秒后自动退出，如果需要 WSL 作为开发环境或一些 docker 服务需要常驻运行，这种前台运行的模式显然是不合适的，应该让 WSL 随系统自动启动并保持在后台运行</summary>
      <content type="html"><![CDATA[<section><h3>后台运行<a href="#后台运行"><span>#</span></a></h3><p>在命令行下使用 <code>wsl -l -v</code> 得到想要启动的 <code>WSL</code> 版本，比如我的机器上是 <code>Ubuntu-24.04</code>，后面命令中使用 <code>Ubuntu-24.04</code> 来代表目标 <code>WSL</code> 版本。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>Administrator</span><span> </span><span>in</span><span> </span><span>~</span><span> </span><span>λ</span><span> </span><span>wsl</span><span> </span><span>-l</span><span> </span><span>-v</span></div></div><div><div><div>2</div></div><div><span>  </span><span>NAME</span><span>            </span><span>STATE</span><span>           </span><span>VERSION</span></div></div><div><div><div>3</div></div><div><span>* Ubuntu-24.04    Running         2</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>新建一个 <code>wsl-d.vbs</code> 文件（文件命名随意）作为启动脚本，里面内容如下：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>set</span><span> </span><span>ws=wscript.CreateObject</span><span>(</span><span>"wscript.shell"</span><span>)</span></div></div><div><div><div>2</div></div><div><span>ws.run</span><span> </span><span>"wsl -d Ubuntu-24.04",</span><span> </span><span>0</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>后续启动 <code>WSL</code> 时直接运行这个启动脚本就会让 <code>WSL</code> 在后台运行了。</p></section>
<section><h3>退出<a href="#退出"><span>#</span></a></h3><p>退出还是正常的就可以了：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 直接退出默认 wsl</span></div></div><div><div><div>2</div></div><div><span>wsl</span><span> </span><span>--shutdown</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 指定 wsl 退出</span></div></div><div><div><div>5</div></div><div><span>wsl</span><span> </span><span>-t</span><span> </span><span>Ubuntu-24.04</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h3>开机启动<a href="#开机启动"><span>#</span></a></h3><p>如果想要在 <code>windows</code> 启动时就直接后台运行 <code>WSL</code>。</p><p>快捷键 <code>WIN + R</code> 运行，输入 <code>shell:startup</code> 打开启动目录后，把上面哪个 <code>wsl-d.vbs</code> 脚本文件复制进去就就可以了。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/4cff4505/</id>
      <title type="text">网页克隆神器出世！一键11复制任何网站，前端开发效率翻倍--Same.New</title>
      <published>2025-03-23T12:32:13.000Z</published>
      <updated>2025-03-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/4cff4505/"/>
      <summary type="text">Same.new 是一款基于神经网络的智能网页复制工具。你只需要输入目标网址，它就能自动解析出包括布局（Header、Footer、侧边栏等）、UI 组件（按钮、表单、图片、导航栏等）、样式（CSS + 响应式规则）甚至交互逻辑（HTML 结构、JS 行为）在内的所有内容。生成的结果会直接呈现在内置编辑器中，你可随时查看、编辑、导出，或进行二次开发。</summary>
      <content type="html"><![CDATA[<p>有没有想过，当你看到一个设计感极强的网页，能直接「借」来它的界面和代码，自己还能随便修改？现在，Same.new 让你真的可以——完全免费，接近 1&lt;1&gt; 地克隆任何网站，包括视觉效果和前端代码。</p>
<p>Same.new 是一款基于神经网络的智能网页复制工具。你只需要输入目标网址，它就能自动解析出包括布局（Header、Footer、侧边栏等）、UI 组件（按钮、表单、图片、导航栏等）、样式（CSS + 响应式规则）甚至交互逻辑（HTML 结构、JS 行为）在内的所有内容。生成的结果会直接呈现在内置编辑器中，你可随时查看、编辑、导出，或进行二次开发。</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/09/b4f8e4ae90c64287b5cc96040237f0e8640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26watermark%3D1%23imgIndex%3D0" alt="图片" /><figcaption>图片</figcaption></figure><p></p>
<p>它的还原度极高，同一页面几乎看不出差别。无论是博客、电商首页还是企业官网，Same.new 都能精准捕捉原有布局与交互逻辑，真正做到「所见即所得」。</p>
<p>比方说你想复刻某个漂亮的登录页或产品详情页，操作就三步：</p>
<ol>
<li>
<p>🟢 输入网址；</p>
</li>
<li>
<p>🟢 点击“Clone”；</p>
</li>
<li>
<p>🟢 直接拿到 HTML + CSS + JS 打包代码。</p>
</li>
</ol>
<p>之后你就可以在本地跑起来，甚至当成项目起点模板继续开发。</p>
<p><strong>✨ 主要功能：</strong></p>
<ul>
<li>
<p>🆓 完全免费，无页面数量或次数限制；</p>
</li>
<li>
<p>🔁 接近 1&lt;1&gt; 还原，不只是截图，而是真实代码；</p>
</li>
<li>
<p>💻 一键导出干净的前端文件；</p>
</li>
<li>
<p>👀 实时预览，编辑即所得；</p>
</li>
<li>
<p>✍️ 支持在线调整样式与结构。</p>
</li>
</ul>
<p><strong>📦 使用流程超简单：</strong></p>
<ol>
<li>
<p>访问 same.new；</p>
</li>
<li>
<p>输入你想克隆的页面URL（推荐公开非验证型页面）；</p>
</li>
<li>
<p>点击执行，等待几秒；</p>
</li>
<li>
<p>查看、编辑、下载——搞定。</p>
</li>
</ol>
<p><strong>🛠 推荐使用人群：</strong></p>
<ul>
<li>
<p>前端开发：快速提取页面结构或组件参考；</p>
</li>
<li>
<p>UI/UX 设计师：分析竞品界面，获取排版与交互灵感；</p>
</li>
<li>
<p>自学党/学生：通过真实页面学前端布局与代码写法；</p>
</li>
<li>
<p>创业小团队：极速搭建 Landing Page 或产品原型；</p>
</li>
<li>
<p>测试同学：复制线上页面用于UI比对或自动化测试。</p>
</li>
</ul>
<p><strong>⚠️ 使用注意：</strong></p>
<ul>
<li>
<p>✅ 允许用于学习、研究、原型测试等场景；</p>
</li>
<li>
<p>❌ 严禁直接商用或复制受版权保护的完整页面；</p>
</li>
<li>
<p>✅ 建议在合理使用原则下借鉴样式或结构。</p>
</li>
</ul>
<p>请尊重原创和知识产权，合法使用工具。</p>
<p><strong>📌 总结一下：</strong>
Same.new 几乎把网站克隆变成了“复制粘贴”的活儿。不管你是为了开发提速、学习代码，还是快速实现界面灵感，它都算得上是一把顺手利器。无需注册、不花钱，界面+代码，一气呵成。</p>
<p>想“扒”个页面看看人家怎么写的？
想做页面原型却不想从头画？
试试 Same.new，你可能会发现：原来写页面，还能这么轻松。</p>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/bd05ac5f/</id>
      <title type="text">不想修改hosts？这个神器更简单！SteamTools 让你一键加速GitHub和Steam，告别网络问题</title>
      <published>2025-03-23T12:32:13.000Z</published>
      <updated>2025-03-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/bd05ac5f/"/>
      <summary type="text">昨天我给大家推荐了 fetch-github-hosts 来解决 GitHub 访问慢的问题，但是有小伙伴反馈说：&quot;修改 hosts 文件太麻烦了，而且担心搞坏网络设置&quot;。今天我要给大家介绍一个更简单的解决方案——**SteamTools（瓦特工具箱）**，它不仅能加速 GitHub，还能加速 Steam，而且不需要修改 hosts 文件，一键就能搞定！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！不想修改hosts的看过来！<a href="#朋友们不想修改hosts的看过来"><span>#</span></a></h2><p>昨天我给大家推荐了 fetch-github-hosts 来解决 GitHub 访问慢的问题，但是有小伙伴反馈说：“修改 hosts 文件太麻烦了，而且担心搞坏网络设置”。</p><p>今天我要给大家介绍一个更简单的解决方案——<strong>SteamTools（瓦特工具箱）</strong>，它不仅能加速 GitHub，还能加速 Steam，而且不需要修改 hosts 文件，一键就能搞定！</p></section>
<section><h2>什么是 SteamTools？<a href="#什么是-steamtools"><span>#</span></a></h2><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/2117eeb5ce234285866611b86cffac5920260408091243053.png" alt="" />
SteamTools（瓦特工具箱）是一个开源跨平台的多功能 Steam 工具箱，它不仅可以加速 Steam，还能加速 GitHub 等网站，而且不需要修改 hosts 文件，使用起来非常简单。</p></section>
<section><h2>为什么推荐 SteamTools？<a href="#为什么推荐-steamtools"><span>#</span></a></h2><section><h3>1️⃣ 不需要修改 hosts 文件<a href="#1️⃣-不需要修改-hosts-文件"><span>#</span></a></h3><p>这是最关键的一点！SteamTools 采用本地反代的方式来加速网络，不需要修改系统的 hosts 文件，避免了可能导致的网络问题。</p></section><section><h3>2️⃣ 功能强大<a href="#2️⃣-功能强大"><span>#</span></a></h3><p>SteamTools 不仅仅是一个加速工具，它还有很多其他实用功能（当然今天就只介绍加速 GitHub 的功能）：</p><ul>
<li><strong>网络加速</strong>：加速 Steam、GitHub 等网站的访问速度</li>
<li><strong>账号切换</strong>：快速切换多平台账号</li>
<li><strong>库存游戏</strong>：管理 Steam 游戏库存，编辑游戏名称和封面</li>
<li><strong>本地令牌</strong>：在电脑中保存手机令牌，支持多种令牌导入</li>
<li><strong>自动挂卡</strong>：挂机掉落 Steam 集换式卡牌</li>
<li><strong>游戏工具</strong>：强制游戏窗口使用无边框窗口化等</li>
</ul></section><section><h3>3️⃣ 跨平台支持<a href="#3️⃣-跨平台支持"><span>#</span></a></h3><p>SteamTools 支持多种操作系统：</p><ul>
<li>Windows 10/11</li>
<li>macOS 10.15 或更高版本</li>
<li>Linux（Ubuntu、Debian、Fedora、Deepin等）</li>
</ul></section><section><h3>4️⃣ 开源免费<a href="#4️⃣-开源免费"><span>#</span></a></h3><p>SteamTools 是开源项目，完全免费使用，没有任何广告。</p></section></section>
<section><h2>如何使用 SteamTools 加速 GitHub？<a href="#如何使用-steamtools-加速-github"><span>#</span></a></h2><section><h3>步骤1：下载并安装 SteamTools<a href="#步骤1下载并安装-steamtools"><span>#</span></a></h3><p>首先，你需要下载并安装 SteamTools(<a href="https://steampp.net/)%E3%80%82" target="_blank">https://steampp.net/)。</a>
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/c3b291960f9d4cf48786dc7f5627c47820260408090528059.png" alt="" /></p></section><section><h3>步骤2：打开 SteamTools<a href="#步骤2打开-steamtools"><span>#</span></a></h3><p>安装完成后，打开 SteamTools 应用。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/eb3e89ef54e14aafbb615be136d7a1b220260408090548847.png" alt="" /></p></section><section><h3>步骤3：启动网络加速<a href="#步骤3启动网络加速"><span>#</span></a></h3><ol>
<li>在 SteamTools 主界面，点击”网络加速”选项</li>
<li>在网络加速设置中，找到”GitHub”相关的加速选项</li>
<li>点击”启动加速”按钮
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/0a2f70e2f6764908a77a5add923b36a320260408090647086.png" alt="" /></li>
<li>等待加速服务启动完成
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/d7017c8d2e314230a7912566c3ce46c120260408090714305.png" alt="" /></li>
</ol></section><section><h3>步骤4：测试 GitHub 访问速度<a href="#步骤4测试-github-访问速度"><span>#</span></a></h3><p>启动加速后，打开浏览器访问 GitHub，你会发现访问速度明显提升！</p></section></section>
<section><h2>常见问题<a href="#常见问题"><span>#</span></a></h2><p>Q: 我们开启 GitHub 加速后，网页是加速了，但 git 命令还不行,克隆不了代码怎么办？
A: 如果想让 <code>git clone</code> 等命令也实现加速的话，我们还需要配置一下 git 的代理。</p><p>首先将 <code>Watt Toolkit</code> 的 GitHub <code>加速模式</code> 选择 <code>系统代理模式</code>
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/155c5fb0bc794589bfbbad23d459c1e620260409090312511.png" alt="" />
然后我们可以通过操作系统的 <code>设置 -&gt; 网络和 Internet -&gt; 代理</code> 来查看代理 IP 和端口，例如：127.0.0.1&lt;26561&gt;。
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/2de11532b958427d8af40c030c63517e20260409090153143.png" alt="" />
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/22238552b1b14d56befbbe1795583a0820260409090539801.png" alt="" />
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/5788928af2134eac80e277150e47ed3d20260409090557393.png" alt="" />
然后，我们打开终端，通过以下命令来设置 git 的 HTTP 代理，并且还要同时禁用 SSL 证书检查，这样 <code>git clone</code> 等命令也会实现加速效果了。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>config</span><span> </span><span>--global</span><span> </span><span>http.proxy</span><span> </span><span>127.0.0.1:26561</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>config</span><span> </span><span>--global</span><span> </span><span>http.sslverify</span><span> </span><span>false</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/2085201f40f94612b7a9737dad87925520260409090645302.png" alt="" />
取消 git 代理的方式如下：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>config</span><span> </span><span>--global</span><span> </span><span>--unset</span><span> </span><span>http.proxy</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>config</span><span> </span><span>--global</span><span> </span><span>--unset</span><span> </span><span>http.sslverify</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/739ac1db129b476783c713a253dd67c420260409090708594.png" alt="" /></p><p>Q: 开机后连不上网络怎么办？
A: 打开 SteamTools 应用，点击”网络加速”选项，找到”GitHub”相关的加速选项，点击”一键加速”按钮，再点击”退出加速”按钮即可。</p><p>Q: 我已经关闭加速了，但git clone 不了gitee/gitlab 项目怎么办？
A: 执行上面的取消 git 代理命令即可。</p></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>前几天我使用了 SteamTools 加速 GitHub，效果真的非常好：</p><ol>
<li>不需要修改 hosts 文件，一键启动加速</li>
<li>GitHub 访问速度从之前的 10 多秒加载时间减少到 1-2 秒</li>
<li>Steam 商店和社区的访问速度也明显提升</li>
<li>账号切换功能非常方便，不用重复登录不同账号</li>
<li>本地令牌功能让我不再需要频繁查看手机上的令牌</li>
</ol></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>不想修改 hosts 文件的用户</strong>：担心修改 hosts 文件会导致网络问题</li>
<li><strong>Steam 玩家</strong>：需要加速 Steam 商店、社区和游戏下载</li>
<li><strong>GitHub 用户</strong>：需要快速访问 GitHub 查看代码、克隆项目</li>
<li><strong>多平台游戏玩家</strong>：需要在多个游戏平台之间切换账号</li>
<li><strong>任何人</strong>：需要一个多功能的游戏工具箱</li>
</ul></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ul>
<li><strong>关机前一定要先退出加速</strong>：如果忘记退出加速，再次开机时，可能会导致网络连接不上的问题，这个时候不要慌，重新启动 SteamTools 即可。</li>
</ul></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><p>如果你对 SteamTools 感兴趣，可以访问它的 GitHub 仓库：<a href="https://github.com/BeyondDimension/SteamTools" target="_blank">https://github.com/BeyondDimension/SteamTools</a></p></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时是如何解决 GitHub 和 Steam 访问慢的问题？使用 SteamTools 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你在使用过程中遇到了什么问题，也可以在评论区留言，我会尽力回答！</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/tanNrcdkfexsT6pNm9035Q?token=102365809&amp;lang=zh_CN" target="_blank">解决GitHub访问慢的神器！fetch-github-hosts 让你秒开GitHub</a></li>
<li><a href="https://mp.weixin.qq.com/s/kG5HvrifueIWsHaWWdTbrQ?token=102365809&amp;lang=zh_CN" target="_blank">发现宝藏聚合软件！益达 APP 让你告别多 app 切换，一个软件看遍小说漫画影视</a></li>
<li><a href="http://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2046857375&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/d901ac44/</id>
      <title type="text">免费！免服务器！前端新手也能用的部署神器 —— PinMe</title>
      <published>2025-03-23T12:32:13.000Z</published>
      <updated>2025-03-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/d901ac44/"/>
      <summary type="text">还在为上线网站发愁？博客、简历、作品集都写好了，却总是卡在最后一步：怎么部署？服务器太贵、平台限流、流程复杂……别急，PinMe 来了！一行命令，免费部署你的网站，永久在线、无需运维。</summary>
      <content type="html"><![CDATA[<section><h3><strong>PinMe 是什么？</strong><a href="#pinme-是什么"><span>#</span></a></h3><p>PinMe 是一个开源命令行工具，可以帮你一键部署网页。</p><ul>
<li>
<p>不需要服务器</p>
</li>
<li>
<p>不需要域名</p>
</li>
<li>
<p>不需要注册账号</p>
</li>
</ul><p>只需要两行命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>-g</span><span> </span><span>pinme</span></div></div><div><div><div>2</div></div><div><span>pinme</span><span> </span><span>upload</span><span> </span><span>&lt;folder/file-path&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>几秒后，你就能获得一个专属链接。</p><p>这就是你的网站 —— 随时访问，不限速，不会下线。</p></section>
<section><h3><strong>PinMe适合谁用？</strong><a href="#pinme适合谁用"><span>#</span></a></h3><p>PinMe 适合所有想快速上线页面的人：</p><ul>
<li>
<p>前端学习者 / 学生党：做完项目，马上分享成果</p>
</li>
<li>
<p>设计师 / 内容创作者：轻松发布个人主页、作品集</p>
</li>
<li>
<p>自由职业者 / 小团队：省时省力，快速搭建简单站点</p>
</li>
<li>
<p>独立开发者：追求简单稳定、不被限流的上线方式</p>
</li>
</ul><p>PinMe 会自动帮你搞定部署，</p><p>你只需专注于“写完页面，直接上线”。</p></section>
<section><h3><strong>相比传统服务，PinMe 能为你带来什么？</strong><a href="#相比传统服务pinme-能为你带来什么"><span>#</span></a></h3><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/07/de79ef50f07b47ff893ae6e523c0351a640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26randomid%3Dotu2ibp6" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>总结一句话：</p><p>PinMe = 免费GitHub Pages + Netlify + 永久 ENS 域名版！</p><p>给每个想快速上线的前端人</p><p>你可能刚学完 Vue / React，做了第一个作品；</p><p>你可能是自由职业者，想展示自己的介绍页；</p><p>你可能只是想有一个属于自己的网页空间。</p><p>别再被部署拦住，从 PinMe 开始，一行命令，永久免费上线。</p></section>
<section><h3><strong>快速开始</strong><a href="#快速开始"><span>#</span></a></h3><p>📌PinMe 官网：</p><p><a href="https://pinme.eth.limo/" target="_blank">https://pinme.eth.limo/</a></p><p>📌戳这里收藏项目：</p><p><a href="https://github.com/glitternetwork/pinme" target="_blank">https://github.com/glitternetwork/pinme</a></p><p>⭐别忘了去GitHub 点个Star! 支持每一个为开发者省事的开源项目！</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/e152db4d/</id>
      <title type="text">Nginx性能优化全方案：打造一个高效服务器</title>
      <published>2025-02-23T12:32:13.000Z</published>
      <updated>2025-02-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/e152db4d/"/>
      <summary type="text">Nginx是一款高性能的Web服务器，广泛应用于互联网领域。然而在高并发、大流量的情况下，Nginx的性能可能会受到一定的影响。因此，对Nginx进行性能优化是非常必要的。本文将从多个方面介绍如何基于Nginx进行性能优化。</summary>
      <content type="html"><![CDATA[<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/06/8432ebb3270d4579b33deb8b268d79bc640.webp" alt="图片" /><figcaption>图片</figcaption></figure><p></p>
<section><h3>一、调整工作进程数和线程数<a href="#一调整工作进程数和线程数"><span>#</span></a></h3><p>Nginx采用异步非阻塞的方式处理请求，这种方式可以充分利用CPU资源，提高并发处理能力。但是，过多的工作进程和线程会导致系统资源浪费，降低性能。因此，需要根据实际情况调整Nginx的工作进程数和线程数。</p><section><h5>unsetunset调整工作进程数unsetunset<a href="#unsetunset调整工作进程数unsetunset"><span>#</span></a></h5><p>Nginx的工作进程数是指Nginx启动后生成的子进程数量。可以通过修改Nginx配置文件中的<code>worker_processes</code>参数来调整工作进程数。</p><p>例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>worker_processes 4;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>表示将Nginx的工作进程数设置为4。</p></section><section><h5>unsetunset调整线程数unsetunset<a href="#unsetunset调整线程数unsetunset"><span>#</span></a></h5><p>每个工作进程都有一个默认的线程数，即Nginx的事件处理模型中包含的线程数。可以通过修改Nginx配置文件中的<code>worker_connections</code>参数来调整线程数。</p><p>例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>worker_connections 1024;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>表示将每个工作进程的线程数设置为1024。</p><p>需要注意的是，线程数并不是越大越好，因为线程之间的竞争可能会导致性能下降。因此，需要根据实际情况进行调整。</p></section></section>
<section><h3>二、启用Gzip压缩<a href="#二启用gzip压缩"><span>#</span></a></h3><p>Gzip压缩是一种常用的网页压缩技术，可以减少传输的数据量，提高页面加载速度。Nginx支持Gzip压缩功能，可以通过配置Nginx来实现。</p><section><h5>unsetunset安装Gzip模块unsetunset<a href="#unsetunset安装gzip模块unsetunset"><span>#</span></a></h5><p>首先需要在编译Nginx时安装Gzip模块。在Linux系统中，可以使用以下命令安装：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>./configure --with-http_gzip_static_module --with-http_gzip_module</span></div></div><div><div><div>2</div></div><div><span>make &amp;&amp; make install</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h5>unsetunset配置Gzip压缩unsetunset<a href="#unsetunset配置gzip压缩unsetunset"><span>#</span></a></h5><p>在Nginx配置文件中添加以下内容：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>http {</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>...</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>gzip on; # 开启Gzip压缩功能</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>gzip_min_length 1k; # 设置最小压缩文件大小为1KB</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>gzip_buffers 4 16k; # 设置压缩缓冲区个数和大小</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>gzip_http_version 1.1; # 设置支持的HTTP协议版本为1.1</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>gzip_comp_level 2; # 设置压缩级别为2（速度与压缩率的平衡）</span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>gzip_types text/plain application/x-javascript text/css application/xml; # 设置需要压缩的文件类型</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>...</span></div></div><div><div><div>10</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h3>三、配置缓存策略<a href="#三配置缓存策略"><span>#</span></a></h3><p>缓存是提高网站性能的重要手段之一。Nginx提供了多种缓存策略，可以根据实际需求进行配置。以下是一些常见的缓存策略：</p><section><h5>unsetunset配置浏览器缓存时间unsetunset<a href="#unsetunset配置浏览器缓存时间unsetunset"><span>#</span></a></h5><p>通过设置HTTP响应头中的<code>Expires</code>和<code>Cache-Control</code>字段，可以控制浏览器缓存的时间。</p><p>例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>location ~* \.(jpg|jpeg|gif|png|css|js)$ {</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>add_header Cache-Control "public, max-age=31536000"; # 设置静态资源的缓存时间为1年（单位：秒）</span></div></div><div><div><div>3</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h5>unsetunset配置代理服务器缓存时间unsetunset<a href="#unsetunset配置代理服务器缓存时间unsetunset"><span>#</span></a></h5><p>如果Nginx作为反向代理服务器使用，可以通过设置<code>proxy_cache_valid</code>和<code>proxy_cache_valid</code>指令来控制代理服务器的缓存时间。</p><p>例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>location / {</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>proxy_pass http://backend; # 将请求转发到后端服务器</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>proxy_cache mycache; # 启用缓存，命名为mycache</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>proxy_cache_valid 200 302 60m; # 设置缓存有效时间为60分钟（单位：秒）</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>proxy_cache_valid 404 1m; # 设置缓存有效时间为1分钟（单位：秒）</span></div></div><div><div><div>6</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h3>四、优化文件访问方式<a href="#四优化文件访问方式"><span>#</span></a></h3><p>在处理静态文件时，Nginx默认会将文件读取到内存中进行处理。这种方式在大文件或高并发情况下会导致内存消耗过大，影响性能。因此，可以采用优化文件访问方式来提高性能。以下是一些优化方法：</p><section><h5>unsetunset使用sendfile()函数发送文件数据unsetunset<a href="#unsetunset使用sendfile函数发送文件数据unsetunset"><span>#</span></a></h5><p><code>sendfile()</code>函数可以直接将文件从磁盘读取并发送到网络，避免了数据在用户空间和内核空间之间的拷贝，提高了性能。可以通过在Nginx配置文件中添加以下内容来启用<code>sendfile()</code>函数：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>http {</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>...</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>sendfile on; # 开启sendfile()函数支持功能（需要操作系统支持）</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>...</span></div></div><div><div><div>5</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h5>unsetunset启用sendfile_max_chunk和tcp_nopush参数unsetunset<a href="#unsetunset启用sendfile_max_chunk和tcp_nopush参数unsetunset"><span>#</span></a></h5><p>通过设置<code>sendfile_max_chunk</code>和<code>tcp_nopush</code>参数，可以控制Nginx在发送文件时的最大分片大小和<code>TCP_CORK</code>选项。</p><p>例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>http {</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>...</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>sendfile_max_chunk 1m; # 设置最大分片大小为1MB</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>tcp_nopush on; # 开启TCP_CORK选项</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>...</span></div></div><div><div><div>6</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h3>五、优化日志配置<a href="#五优化日志配置"><span>#</span></a></h3><p>日志是排查问题的重要手段，但是过多的日志会导致磁盘空间不足，影响系统性能。因此，需要对Nginx的日志进行优化。以下是一些优化方法：</p><section><h5>unsetunset调整日志级别unsetunset<a href="#unsetunset调整日志级别unsetunset"><span>#</span></a></h5><p>Nginx支持多种日志级别，如<code>debug</code>、<code>info</code>、<code>notice</code>、<code>warn</code>、<code>error</code>等。可以通过修改Nginx配置文件中的<code>log_level</code>参数来调整日志级别。</p><p>例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>http {</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>...</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>log_level info; # 将日志级别设置为info</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>...</span></div></div><div><div><div>5</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h5>unsetunset配置日志切割和压缩unsetunset<a href="#unsetunset配置日志切割和压缩unsetunset"><span>#</span></a></h5><p>为了减少日志占用的磁盘空间，可以配置日志切割和压缩功能。例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>http {</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>...</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>access_log /var/log/nginx/access.log combined buffer=32k flush=1m; # 配置访问日志切割和压缩功能</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>error_log /var/log/nginx/error.log info; # 配置错误日志，并设置日志级别为info</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>...</span></div></div><div><div><div>6</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h3>六、其他优化建议<a href="#六其他优化建议"><span>#</span></a></h3><p>除了上述优化方法外，还有一些其他的优化建议：</p><section><h5>unsetunset使用CDN加速静态资源访问unsetunset<a href="#unsetunset使用cdn加速静态资源访问unsetunset"><span>#</span></a></h5><p>CDN（<code>Content Delivery Network</code>）是一种内容分发网络</p><ul>
<li>
<p>可以将静态资源缓存到离用户更近的节点上，提高访问速度。</p>
</li>
<li>
<p>可以使用阿里云、腾讯云等云服务商提供的CDN服务。</p>
</li>
</ul></section><section><h5>unsetunset使用HTTP/2协议提高传输效率unsetunset<a href="#unsetunset使用http2协议提高传输效率unsetunset"><span>#</span></a></h5><p>HTTP/2协议是一种新的HTTP协议，支持多路复用、头部压缩等功能，可以提高传输效率。需要在Nginx和客户端同时支持HTTP/2协议才能生效。可以通过修改Nginx配置文件中的listen指令来启用HTTP/2协议。例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>server {</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>listen 443 ssl http2; # 启用HTTPS并启用HTTP/2协议支持功能（需要操作系统和SSL库支持）</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>...</span></div></div><div><div><div>4</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/139780d4/</id>
      <title type="text">音乐馆页配置</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/139780d4/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>音乐馆页配置<a href="#音乐馆页配置"><span>#</span></a></h2><ol>
<li>
<p>前往你的 Hexo 博客的根目录</p>
</li>
<li>
<p>在 Hexo 博客根目录 <code>[blog]</code>下打开终端，输入</p>
</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>hexo</span><span> </span><span>new</span><span> </span><span>page</span><span> </span><span>music</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>
<p>你会找到 <code>source/music/index.md</code> 这个文件</p>
</li>
<li>
<p>修改这个文件： 记得添加 <code>type: "music"</code></p>
</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>音乐馆</span></div></div><div><div><div>3</div></div><div><span>date</span><span>: </span><span>2021-04-24 21:41:30</span></div></div><div><div><div>4</div></div><div><span>type</span><span>: </span><span>music</span></div></div><div><div><div>5</div></div><div><span>aplayer</span><span>: </span><span>true</span></div></div><div><div><div>6</div></div><div><span>top_img</span><span>: </span><span>false</span></div></div><div><div><div>7</div></div><div><span>comments</span><span>: </span><span>false</span></div></div><div><div><div>8</div></div><div><span>aside</span><span>: </span><span>false</span></div></div><div><div><div>9</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>新建 <code>source/json/music.json</code>，此 json 为切换歌单按钮的歌单数据。</li>
</ol><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[</span></div></div><div><div><div>2</div></div><div><span>{</span></div></div><div><div><div>3</div></div><div><span>"name"</span><span>: </span><span>"青花瓷"</span><span>,</span></div></div><div><div><div>4</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>5</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.4/青花瓷/青花瓷.mp3"</span><span>,</span></div></div><div><div><div>6</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000002eFUFm2XYZ7z_2.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>7</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.4/青花瓷/青花瓷.lrc"</span></div></div><div><div><div>8</div></div><div><span>},</span></div></div><div><div><div>9</div></div><div><span>{</span></div></div><div><div><div>10</div></div><div><span>"name"</span><span>: </span><span>"稻香"</span><span>,</span></div></div><div><div><div>11</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>12</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.1/周杰伦/稻香/稻香.mp3"</span><span>,</span></div></div><div><div><div>13</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000002Neh8l0uciQZ_1.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>14</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.1/周杰伦/稻香/稻香.lrc"</span></div></div><div><div><div>15</div></div><div><span>},</span></div></div><div><div><div>16</div></div><div><span>{</span></div></div><div><div><div>17</div></div><div><span>"name"</span><span>: </span><span>"晴天"</span><span>,</span></div></div><div><div><div>18</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>19</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.2/晴天/晴天.mp3"</span><span>,</span></div></div><div><div><div>20</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000000MkMni19ClKG_3.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>21</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.2/晴天/晴天.lrc"</span></div></div><div><div><div>22</div></div><div><span>},</span></div></div><div><div><div>23</div></div><div><span>{</span></div></div><div><div><div>24</div></div><div><span>"name"</span><span>: </span><span>"七里香"</span><span>,</span></div></div><div><div><div>25</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>26</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.2/七里香/七里香.mp3"</span><span>,</span></div></div><div><div><div>27</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000003DFRzD192KKD_1.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>28</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.2/七里香/七里香.lrc"</span></div></div><div><div><div>29</div></div><div><span>},</span></div></div><div><div><div>30</div></div><div><span>{</span></div></div><div><div><div>31</div></div><div><span>"name"</span><span>: </span><span>"花海"</span><span>,</span></div></div><div><div><div>32</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>33</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/花海/花海.flac"</span><span>,</span></div></div><div><div><div>34</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000002Neh8l0uciQZ_1.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>35</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/花海/花海.lrc"</span></div></div><div><div><div>36</div></div><div><span>},</span></div></div><div><div><div>37</div></div><div><span>{</span></div></div><div><div><div>38</div></div><div><span>"name"</span><span>: </span><span>"反方向的钟"</span><span>,</span></div></div><div><div><div>39</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>40</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/反方向的钟/反方向的钟.flac"</span><span>,</span></div></div><div><div><div>41</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000000f01724fd7TH_1.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>42</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/反方向的钟/反方向的钟.lrc"</span></div></div><div><div><div>43</div></div><div><span>},</span></div></div><div><div><div>44</div></div><div><span>{</span></div></div><div><div><div>45</div></div><div><span>"name"</span><span>: </span><span>"兰亭序"</span><span>,</span></div></div><div><div><div>46</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>47</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.1/周杰伦/兰亭序/兰亭序.mp3"</span><span>,</span></div></div><div><div><div>48</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000002Neh8l0uciQZ_1.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>49</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.1/周杰伦/兰亭序/兰亭序.lrc"</span></div></div><div><div><div>50</div></div><div><span>},</span></div></div><div><div><div>51</div></div><div><span>{</span></div></div><div><div><div>52</div></div><div><span>"name"</span><span>: </span><span>"说好的辛福呢"</span><span>,</span></div></div><div><div><div>53</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>54</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.2/说好的辛福呢/说好的辛福呢.mp3"</span><span>,</span></div></div><div><div><div>55</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000002Neh8l0uciQZ_1.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>56</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.2/说好的辛福呢/说好的幸福呢.lrc"</span></div></div><div><div><div>57</div></div><div><span>},</span></div></div><div><div><div>58</div></div><div><span>{</span></div></div><div><div><div>59</div></div><div><span>"name"</span><span>: </span><span>"等你下课 (with 杨瑞代)"</span><span>,</span></div></div><div><div><div>60</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>61</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.1/周杰伦/等你下课/等你下课.mp3"</span><span>,</span></div></div><div><div><div>62</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000003bSL0v4bpKAx_1.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>63</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.1/周杰伦/等你下课/等你下课.lrc"</span></div></div><div><div><div>64</div></div><div><span>},</span></div></div><div><div><div>65</div></div><div><span>{</span></div></div><div><div><div>66</div></div><div><span>"name"</span><span>: </span><span>"我落泪情绪零碎"</span><span>,</span></div></div><div><div><div>67</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>68</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.2/我落泪情绪零碎/我落泪情绪零碎.mp3"</span><span>,</span></div></div><div><div><div>69</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000000bviBl4FjTpO_1.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>70</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.2/我落泪情绪零碎/我落泪情绪零碎.lrc"</span></div></div><div><div><div>71</div></div><div><span>},</span></div></div><div><div><div>72</div></div><div><span>{</span></div></div><div><div><div>73</div></div><div><span>"name"</span><span>: </span><span>"听妈妈的话"</span><span>,</span></div></div><div><div><div>74</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>75</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.2/听妈妈的话/听妈妈的话.mp3"</span><span>,</span></div></div><div><div><div>76</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000002jLGWe16Tf1H_1.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>77</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.2/听妈妈的话/听妈妈的话.lrc"</span></div></div><div><div><div>78</div></div><div><span>},</span></div></div><div><div><div>79</div></div><div><span>{</span></div></div><div><div><div>80</div></div><div><span>"name"</span><span>: </span><span>"明明就"</span><span>,</span></div></div><div><div><div>81</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>82</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/明明就/明明就.flac"</span><span>,</span></div></div><div><div><div>83</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000003Ow85E3pnoqi_1.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>84</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/明明就/明明就.lrc"</span></div></div><div><div><div>85</div></div><div><span>},</span></div></div><div><div><div>86</div></div><div><span>{</span></div></div><div><div><div>87</div></div><div><span>"name"</span><span>: </span><span>"我是如此相信"</span><span>,</span></div></div><div><div><div>88</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>89</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/我是如此相信/我是如此相信.flac"</span><span>,</span></div></div><div><div><div>90</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000001hGx1Z0so1YX_1.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>91</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music-jay@1.0.1/我是如此相信/我是如此相信.lrc"</span></div></div><div><div><div>92</div></div><div><span>},</span></div></div><div><div><div>93</div></div><div><span>{</span></div></div><div><div><div>94</div></div><div><span>"name"</span><span>: </span><span>"发如雪"</span><span>,</span></div></div><div><div><div>95</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>96</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.3/发如雪/发如雪.mp3"</span><span>,</span></div></div><div><div><div>97</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M0000024bjiL2aocxT_3.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>98</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.3/发如雪/发如雪.lrc"</span></div></div><div><div><div>99</div></div><div><span>},</span></div></div><div><div><div>100</div></div><div><span>{</span></div></div><div><div><div>101</div></div><div><span>"name"</span><span>: </span><span>"以父之名"</span><span>,</span></div></div><div><div><div>102</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>103</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.3/以父之名/以父之名.mp3"</span><span>,</span></div></div><div><div><div>104</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000000MkMni19ClKG_3.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>105</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.3/以父之名/以父之名.lrc"</span></div></div><div><div><div>106</div></div><div><span>},</span></div></div><div><div><div>107</div></div><div><span>{</span></div></div><div><div><div>108</div></div><div><span>"name"</span><span>: </span><span>"园游会"</span><span>,</span></div></div><div><div><div>109</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>110</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.3/园游会/园游会.flac"</span><span>,</span></div></div><div><div><div>111</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000003DFRzD192KKD_1.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>112</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.3/园游会/园游会.lrc"</span></div></div><div><div><div>113</div></div><div><span>},</span></div></div><div><div><div>114</div></div><div><span>{</span></div></div><div><div><div>115</div></div><div><span>"name"</span><span>: </span><span>"本草纲目"</span><span>,</span></div></div><div><div><div>116</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>117</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.4/本草纲目/本草纲目.mp3"</span><span>,</span></div></div><div><div><div>118</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000002jLGWe16Tf1H_1.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>119</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.4/本草纲目/本草纲目.lrc"</span></div></div><div><div><div>120</div></div><div><span>},</span></div></div><div><div><div>121</div></div><div><span>{</span></div></div><div><div><div>122</div></div><div><span>"name"</span><span>: </span><span>"龙卷风"</span><span>,</span></div></div><div><div><div>123</div></div><div><span>"artist"</span><span>: </span><span>"周杰伦"</span><span>,</span></div></div><div><div><div>124</div></div><div><span>"url"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.4/龙卷风/龙卷风.mp3"</span><span>,</span></div></div><div><div><div>125</div></div><div><span>"cover"</span><span>: </span><span>"https://y.qq.com/music/photo_new/T002R300x300M000000f01724fd7TH_1.jpg?max_age=2592000"</span><span>,</span></div></div><div><div><div>126</div></div><div><span>"lrc"</span><span>: </span><span>"https://npm.elemecdn.com/anzhiyu-music@1.0.4/龙卷风/龙卷风.lrc"</span></div></div><div><div><div>127</div></div><div><span>}</span></div></div><div><div><div>128</div></div><div><span>]</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><ol>
<li>hexo 配置文件<code>_config.yml</code>中添加以下配置，注意不是主题配置文件</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># APlayer</span></div></div><div><div><div>2</div></div><div><span># https://github.com/MoePlayer/hexo-tag-aplayer/blob/master/docs/README-zh_cn.md</span></div></div><div><div><div>3</div></div><div><span>aplayer</span><span>:</span></div></div><div><div><div>4</div></div><div><span>meting</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>asset_inject</span><span>: </span><span>false</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>主题配置文件中开启<code>menu</code>中我的和音乐馆的注释，注意缩进！！！</li>
</ol><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>menu</span><span>:</span></div></div><div><div><div>2</div></div><div><span># 文章:</span></div></div><div><div><div>3</div></div><div><span>#   隧道: /archives/ || icon-box-archive</span></div></div><div><div><div>4</div></div><div><span>#   分类: /categories/ || icon-shapes</span></div></div><div><div><div>5</div></div><div><span>#   标签: /tags/ || icon-tags</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>友链</span><span>:</span></div></div><div><div><div>8</div></div><div><span>友人帐</span><span>: </span><span>/link/ || icon-link</span></div></div><div><div><div>9</div></div><div><span>#   朋友圈: /fcircle/ || icon-artstation</span></div></div><div><div><div>10</div></div><div><span>#   留言板: /comments/ || icon-envelope</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>我的</span><span>:</span></div></div><div><div><div>13</div></div><div><span>音乐馆</span><span>: </span><span>/music/ || icon-music</span></div></div><div><div><div>14</div></div><div><span>#   追番页: /bangumis/ || icon-bilibili1</span></div></div><div><div><div>15</div></div><div><span>#   相册集: /album/ || icon-images</span></div></div><div><div><div>16</div></div><div><span>#   小空调: /air-conditioner/ || icon-fan</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>关于</span><span>:</span></div></div><div><div><div>19</div></div><div><span>#   关于本人: /about/ || icon-zhifeiji</span></div></div><div><div><div>20</div></div><div><span>闲言碎语</span><span>: </span><span>/essay/ || icon-lightbulb</span></div></div><div><div><div>21</div></div><div><span>#   随便逛逛: javascript:toRandomPost() || icon-shoe-prints1</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><blockquote><p>如何修改默认歌单?</p></blockquote><p>将<code>menu</code>中音乐馆的路径修改为以下格式即可<code>/music/?id=1708664797&amp;server=tencent</code>，支持<code>id</code>和<code>server</code>参数。</p><p>id 与 server 的填写请参考<a href="https://github.com/metowolf/MetingJS" target="_blank">MetingJS</a></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/12/9e13b6e09ce64440933131845c4d8354643264b4da332.png!blogimg" alt="音乐馆页" /><figcaption>音乐馆页</figcaption></figure><p></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/17830e54/</id>
      <title type="text">首页即刻说说页面配置</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/17830e54/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>首页即刻说说页面配置<a href="#首页即刻说说页面配置"><span>#</span></a></h2><ol>
<li>
<p>前往你的 Hexo 博客的根目录</p>
</li>
<li>
<p>在 Hexo 博客根目录 <code>[blog]</code>下打开终端，输入</p>
</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>hexo</span><span> </span><span>new</span><span> </span><span>page</span><span> </span><span>essay</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>
<p>你会找到 <code>source/essay/index.md</code> 这个文件</p>
</li>
<li>
<p>修改这个文件： 记得添加 <code>type: "essay"</code></p>
</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>即刻短文</span></div></div><div><div><div>3</div></div><div><span>date</span><span>: </span><span>2020-07-22 22:06:17</span></div></div><div><div><div>4</div></div><div><span>comments</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>aside</span><span>: </span><span>false</span></div></div><div><div><div>6</div></div><div><span>top_img</span><span>: </span><span>false</span></div></div><div><div><div>7</div></div><div><span>type</span><span>: </span><span>essay</span></div></div><div><div><div>8</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>新建<code>source/_data/essay.yml</code>，输入以下内容，具体字段不做解释，可以依葫芦画瓢。</li>
</ol><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- </span><span>title</span><span>: </span><span>即刻短文</span></div></div><div><div><div>2</div></div><div><span>  </span><span>subTitle</span><span>: </span><span>咸鱼的日常生活。</span></div></div><div><div><div>3</div></div><div><span>  </span><span>tips</span><span>: </span><span>随时随地，分享生活</span></div></div><div><div><div>4</div></div><div><span>  </span><span>buttonText</span><span>: </span><span>关于我</span></div></div><div><div><div>5</div></div><div><span>  </span><span>buttonLink</span><span>: </span><span>/about/</span></div></div><div><div><div>6</div></div><div><span>  </span><span>limit</span><span>: </span><span>30</span></div></div><div><div><div>7</div></div><div><span>  </span><span>home_essay</span><span>: </span><span>true</span></div></div><div><div><div>8</div></div><div><span>  </span><span>top_background</span><span>: </span><span>https://img02.anheyu.com/adminuploads/1/2022/08/21/630249e2df20f.jpg</span></div></div><div><div><div>9</div></div><div><span>  </span><span>essay_list</span><span>:</span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>安知鱼主题指南</span></div></div><div><div><div>11</div></div><div><span>      </span><span>date</span><span>: </span><span>2023/09/09</span></div></div><div><div><div>12</div></div><div><span>      </span><span>video</span><span>:</span></div></div><div><div><div>13</div></div><div><span><span>        </span></span><span>- </span><span>https://player.bilibili.com/player.html?aid=226886152&amp;bvid=BV1Ch41137tR&amp;cid=1081639816&amp;p=1&amp;autoplay=0</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>支持了Accesskey快捷键，可以直接按下shift + ?组合键以查看快捷键选项。</span></div></div><div><div><div>15</div></div><div><span>      </span><span>date</span><span>: </span><span>2023/07/01</span></div></div><div><div><div>16</div></div><div><span>      </span><span>video</span><span>:</span></div></div><div><div><div>17</div></div><div><span><span>        </span></span><span>- </span><span>https://cdn.jsdelivr.net/npm/anzhiyu-blog-static@1.0.0/video/%E9%A3%8E%E8%BD%A6%E6%A0%B7%E5%BC%8F%E6%95%88%E6%9E%9C%E9%A2%84%E8%A7%88.mp4</span></div></div><div><div><div>18</div></div><div><span>      </span><span>image</span><span>:</span></div></div><div><div><div>19</div></div><div><span><span>        </span></span><span>- </span><span>https://img02.anheyu.com/adminuploads/1/2023/07/01/64a033cb2c21e.webp!blogimg</span></div></div><div><div><div>20</div></div><div><span>      </span><span>address</span><span>: </span><span>长沙</span></div></div><div><div><div>21</div></div><div><span>      </span><span>from</span><span>: </span><span>安知鱼</span></div></div><div><div><div>22</div></div><div><span>      </span><span>link</span><span>: </span><span>/posts/e140.html</span></div></div><div><div><div>23</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>音乐支持了参数设置自定义歌单</span></div></div><div><div><div>24</div></div><div><span>      </span><span>date</span><span>: </span><span>2023/01/02</span></div></div><div><div><div>25</div></div><div><span>      </span><span>link</span><span>: </span><span>https://hexo.anheyu.com/music/?id=7269231710&amp;server=tencent</span></div></div><div><div><div>26</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>关于页的打赏仿了b站的充电功能，使用svg绘图➕一些动画参数移动，应该不会被b站警告吧😜，另外文章也支持了顶部随机b站同款春秋冬banner。</span></div></div><div><div><div>27</div></div><div><span>      </span><span>date</span><span>: </span><span>2022/12/18</span></div></div><div><div><div>28</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>React中不能直接修改state的一个重要原因是在性能优化时的prueComponment会进行浅层比较会认为是用一个对象且不能进入队列中批量更新</span></div></div><div><div><div>29</div></div><div><span>      </span><span>date</span><span>: </span><span>2022/12/10</span></div></div><div><div><div>30</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>好耶，马上就可以放假回家了！好想家里的好吃的😋！才不是想捏妹妹的脸了</span></div></div><div><div><div>31</div></div><div><span>      </span><span>date</span><span>: </span><span>2022/12/06</span></div></div><div><div><div>32</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>全局音乐的动画也处理好了, nice!</span></div></div><div><div><div>33</div></div><div><span>      </span><span>date</span><span>: </span><span>2022/11/13</span></div></div><div><div><div>34</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>把页脚, 首页顶部全都魔改到本地了, 方便后续魔改, 音乐也改成胶囊的样式了, 其实还是想让胶囊可拖拽, 不可点击改变歌词位置的, 但是弄了半天都没弄好就放弃了</span></div></div><div><div><div>35</div></div><div><span>      </span><span>date</span><span>: </span><span>2022/11/13</span></div></div><div><div><div>36</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>朋友圈船新版本终于写完了, 耶✌️</span></div></div><div><div><div>37</div></div><div><span>      </span><span>date</span><span>: </span><span>2022/11/05</span></div></div><div><div><div>38</div></div><div><span>      </span><span>link</span><span>: </span><span>https://hexo.anheyu.com/album/</span></div></div><div><div><div>39</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>终于把相册集搞定了, 耶✌️, 瀑布流在滑动滚动条一个视口范围上下100的情况执行一次, 到底部停止监听让性能高了好多，再也不会布局混乱🤪了</span></div></div><div><div><div>40</div></div><div><span>      </span><span>date</span><span>: </span><span>2022/10/25</span></div></div><div><div><div>41</div></div><div><span>      </span><span>link</span><span>: </span><span>https://hexo.anheyu.com/album/</span></div></div><div><div><div>42</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>搜索🔍支持缩略图显示啦（默认获取文章内容的第一张图片）</span></div></div><div><div><div>43</div></div><div><span>      </span><span>date</span><span>: </span><span>2022/10/23 08:00:00</span></div></div><div><div><div>44</div></div><div><span>      </span><span>from</span><span>: </span><span>安知鱼</span></div></div><div><div><div>45</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>遇见彩虹🌈吃定彩虹</span></div></div><div><div><div>46</div></div><div><span>      </span><span>date</span><span>: </span><span>2022/10/23 10:00:00</span></div></div><div><div><div>47</div></div><div><span>      </span><span>image</span><span>:</span></div></div><div><div><div>48</div></div><div><span><span>        </span></span><span>- </span><span>https://bu.dusays.com/2023/04/09/64329399e285d.webp</span></div></div><div><div><div>49</div></div><div><span><span>        </span></span><span>- </span><span>https://bu.dusays.com/2023/04/09/64329399aa3bc.webp</span></div></div><div><div><div>50</div></div><div><span><span>        </span></span><span>- </span><span>https://bu.dusays.com/2023/04/09/6432939996dd7.webp</span></div></div><div><div><div>51</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>ThreeJs API真多丫</span></div></div><div><div><div>52</div></div><div><span>      </span><span>date</span><span>: </span><span>2022/10/19</span></div></div><div><div><div>53</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>妹妹强制要求我买走了她的两幅画 -¥30</span></div></div><div><div><div>54</div></div><div><span>      </span><span>date</span><span>: </span><span>2022/10/02</span></div></div><div><div><div>55</div></div><div><span>      </span><span>image</span><span>:</span></div></div><div><div><div>56</div></div><div><span><span>        </span></span><span>- </span><span>https://bu.dusays.com/2023/04/09/643293997b92b.jpeg</span></div></div><div><div><div>57</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>歌曲推荐</span></div></div><div><div><div>58</div></div><div><span>      </span><span>date</span><span>: </span><span>2022/09/25</span></div></div><div><div><div>59</div></div><div><span>      </span><span>aplayer</span><span>:</span></div></div><div><div><div>60</div></div><div><span>        </span><span>server</span><span>: </span><span>tencent</span></div></div><div><div><div>61</div></div><div><span>        </span><span>id</span><span>: </span><span>001FGQba3i10mw</span></div></div><div><div><div>62</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>做了一个噩梦, 梦到从楼顶坠下去了。😷</span></div></div><div><div><div>63</div></div><div><span>      </span><span>date</span><span>: </span><span>2022/09/24</span></div></div><div><div><div>64</div></div><div><span><span>    </span></span><span>- </span><span>content</span><span>: </span><span>JOJO是真的好看！</span></div></div><div><div><div>65</div></div><div><span>      </span><span>date</span><span>: </span><span>2022/09/21</span></div></div><div><div><div>66</div></div><div><span>      </span><span>link</span><span>: </span><span>https://www.bilibili.com/bangumi/play/ss39431?spm_id_from=333.337.0.0</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>【主题版本 1.6.7 以上支持】其中 video 对于 bilibili 进行的额外的支持，视频为 player.bilibili.com 的将显示为 bilibili 视频，并且可以在链接后面拼接<code>&amp;autoplay=0</code>控制不自动播放</p><p>警告</p><p>主题配置文件中开启<code>menu</code>中关于和闲言碎语的注释，导航栏闲言碎语，注意缩进！！！</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>menu</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span># 文章:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>#   隧道: /archives/ || icon-box-archive</span></div></div><div><div><div>4</div></div><div><span>  </span><span>#   分类: /categories/ || icon-shapes</span></div></div><div><div><div>5</div></div><div><span>  </span><span>#   标签: /tags/ || icon-tags</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>  </span><span># 友链:</span></div></div><div><div><div>8</div></div><div><span>  </span><span>#   友人帐: /link/ || icon-link</span></div></div><div><div><div>9</div></div><div><span>  </span><span>#   朋友圈: /fcircle/ || icon-artstation</span></div></div><div><div><div>10</div></div><div><span>  </span><span>#   留言板: /comments/ || icon-envelope</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>  </span><span># 我的:</span></div></div><div><div><div>13</div></div><div><span>  </span><span>#   音乐馆: /music/ || icon-music</span></div></div><div><div><div>14</div></div><div><span>  </span><span>#   追番页: /bangumis/ || icon-bilibili1</span></div></div><div><div><div>15</div></div><div><span>  </span><span>#   相册集: /album/ || icon-images</span></div></div><div><div><div>16</div></div><div><span>  </span><span>#   小空调: /air-conditioner/ || icon-fan</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>  </span><span>关于</span><span>:</span></div></div><div><div><div>19</div></div><div><span>    </span><span>#   关于本人: /about/ || icon-zhifeiji</span></div></div><div><div><div>20</div></div><div><span>    </span><span>闲言碎语</span><span>: </span><span>/essay/ || icon-lightbulb</span></div></div><div><div><div>21</div></div><div><span>    </span><span>#   随便逛逛: javascript:toRandomPost() || icon-shoe-prints1</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/12/1814a2f3f27b4e69867e54dd5d3a5be2643263bdd2aa4.png!blogimg" alt="即刻说说页面" /><figcaption>即刻说说页面</figcaption></figure><p></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/19fccf72/</id>
      <title type="text">404页面配置</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/19fccf72/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>404页面配置<a href="#404页面配置"><span>#</span></a></h2><p>主题内置了一个简单的 404 页面，可在设置中开启 本地预览时，访问出错的网站是不会跳到 404 页面的。</p><p>如需本地预览，请访问 <code>http://localhost:4000/404.html</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># A simple 404 page</span></div></div><div><div><div>2</div></div><div><span>error_404</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>subtitle</span><span>: </span><span>"页面没有找到"</span></div></div><div><div><div>5</div></div><div><span>  </span><span>background</span><span>:</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/22207bb4210240378392ef10c3127eda64326263a9eda.png!blogimg" alt="404页面" /><figcaption>404页面</figcaption></figure><p></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/53a8ce46/</id>
      <title type="text">基础配置</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/53a8ce46/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>站点配置 😋<a href="#站点配置-"><span>#</span></a></h2><section><h3>语言<a href="#语言"><span>#</span></a></h3><p>修改站点配置文件 <code>_config.yml</code>，不是主题配置文件。</p><p>默认语言是 en</p><p>主题支持三种语言</p><ul>
<li>default(en)</li>
<li>zh-CN (简体中文)</li>
<li>zh-TW (繁体中文)</li>
</ul></section><section><h3>网站资料<a href="#网站资料"><span>#</span></a></h3><p>修改网站各种资料，例如标题、副标题和邮箱等个人资料，请修改博客根目录的<code>_config.yml</code> 。</p><p></p><figure><img src="https://bu.dusays.com/2023/08/23/64e5772ad3448.webp" alt="网站资料" /><figcaption>网站资料</figcaption></figure><p></p></section><section><h3>导航配置<a href="#导航配置"><span>#</span></a></h3><p>修改 <code>主题配置文件</code></p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>menu:</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>文章:</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>隧道: /archives/ || anzhiyu-icon-box-archive</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>分类: /categories/ || anzhiyu-icon-shapes</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>标签: /tags/ || anzhiyu-icon-tags</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>友链:</span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>友人帐: /link/ || anzhiyu-icon-link</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>朋友圈: /fcircle/ || anzhiyu-icon-artstation</span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>留言板: /comments/ || anzhiyu-icon-envelope</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span><span>  </span></span><span>我的:</span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>音乐馆: /music/ || anzhiyu-icon-music</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>追番页: /bangumis/ || anzhiyu-icon-bilibili</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>相册集: /album/ || anzhiyu-icon-images</span></div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>小空调: /air-conditioner/ || anzhiyu-icon-fan</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span><span>  </span></span><span>关于:</span></div></div><div><div><div>19</div></div><div><span><span>    </span></span><span>关于本人: /about/ || anzhiyu-icon-paper-plane</span></div></div><div><div><div>20</div></div><div><span><span>    </span></span><span>闲言碎语: /essay/ || anzhiyu-icon-lightbulb</span></div></div><div><div><div>21</div></div><div><span><span>    </span></span><span>随便逛逛: javascript:toRandomPost() || anzhiyu-icon-shoe-prints1</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>必须是 <code>/xxx/</code>，后面<code>||</code>分开，然后写图标名。</p><p>如果不希望显示图标，图标名可不写。</p><blockquote><p><strong>TIP</strong>
注意： 导航的文字可自行更改</p></blockquote><p>例如：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>menu</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>Article</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>Tunnel</span><span>: </span><span>/archives/ || icon-box-archive</span></div></div><div><div><div>4</div></div><div><span>    </span><span>Classification</span><span>: </span><span>/categories/ || icon-shapes</span></div></div><div><div><div>5</div></div><div><span>    </span><span>Label</span><span>: </span><span>/tags/ || icon-tags</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>  </span><span>Friend</span><span>:</span></div></div><div><div><div>8</div></div><div><span>    </span><span>Friends account</span><span>: </span><span>/link/ || icon-link</span></div></div><div><div><div>9</div></div><div><span>    </span><span>Moments</span><span>: </span><span>/fcircle/ || icon-artstation</span></div></div><div><div><div>10</div></div><div><span>    </span><span>Message board</span><span>: </span><span>/comments/ || icon-envelope</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>  </span><span>My</span><span>:</span></div></div><div><div><div>13</div></div><div><span>    </span><span>Music Hall</span><span>: </span><span>/music/ || icon-music</span></div></div><div><div><div>14</div></div><div><span>    </span><span>Chasing</span><span>: </span><span>/bangumis/ || icon-bilibili1</span></div></div><div><div><div>15</div></div><div><span>    </span><span>Album Set</span><span>: </span><span>/album/ || icon-images</span></div></div><div><div><div>16</div></div><div><span>    </span><span>Conditioning</span><span>: </span><span>/air-conditioner/ || icon-fan</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>  </span><span>About</span><span>: </span><span>/about/ || icon-zhifeiji</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>导航栏设置<a href="#导航栏设置"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## nav相关配置</span></div></div><div><div><div>2</div></div><div><span>nav</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>false</span></div></div><div><div><div>4</div></div><div><span>  </span><span>travelling</span><span>: </span><span>false</span></div></div><div><div><div>5</div></div><div><span>  </span><span>clock</span><span>: </span><span>true</span></div></div><div><div><div>6</div></div><div><span>  </span><span>menu</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>- </span><span>title</span><span>: </span><span>网页</span></div></div><div><div><div>8</div></div><div><span>      </span><span>item</span><span>:</span></div></div><div><div><div>9</div></div><div><span><span>        </span></span><span>- </span><span>name</span><span>: </span><span>博客</span></div></div><div><div><div>10</div></div><div><span>          </span><span>link</span><span>: </span><span>https://hexo.anheyu.com/</span></div></div><div><div><div>11</div></div><div><span>          </span><span>icon</span><span>: </span><span>/img/favicon.png</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>- </span><span>title</span><span>: </span><span>项目</span></div></div><div><div><div>13</div></div><div><span>      </span><span>item</span><span>:</span></div></div><div><div><div>14</div></div><div><span><span>        </span></span><span>- </span><span>name</span><span>: </span><span>安知鱼图床</span></div></div><div><div><div>15</div></div><div><span>          </span><span>link</span><span>: </span><span>https://image.anheyu.com/</span></div></div><div><div><div>16</div></div><div><span>          </span><span>icon</span><span>: </span><span>https://image.anheyu.com/favicon.ico</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>

<table><thead><tr><th>参数</th><th>解释</th></tr></thead><tbody><tr><td>enable</td><td>是否启用 nav 左侧项目按钮，仅控制左侧项目按钮</td></tr><tr><td>travelling</td><td>是否启用 nav 开往按钮</td></tr><tr><td>clock</td><td>是否启用 nav 左侧<a href="https://widget.qweather.com/" target="_blank">和风天气</a></td></tr><tr><td>menu</td><td>nav 左侧项目按钮内的菜单</td></tr><tr><td>menu.title</td><td>nav 左侧项目按钮内的菜单标题</td></tr><tr><td>menu.item</td><td>nav 左侧项目按钮内的菜单项</td></tr><tr><td>menu.item.name</td><td>nav 左侧项目按钮内的菜单项标题</td></tr><tr><td>menu.item.link</td><td>nav 左侧项目按钮内的菜单项链接</td></tr><tr><td>menu.item.icon</td><td>nav 左侧项目按钮内的菜单项图标</td></tr></tbody></table><p></p><figure><img src="https://bu.dusays.com/2023/07/23/64bc7311d661d.webp" alt="项目列表" /><figcaption>项目列表</figcaption></figure><p></p></section><section><h3>代码块配置<a href="#代码块配置"><span>#</span></a></h3><p>相关信息</p><p>代码块中的所有功能只适用于 Hexo 自带的代码渲染 如果使用第三方的渲染器，不一定会有效</p><section><h4>代码高亮主题<a href="#代码高亮主题"><span>#</span></a></h4><p><code>AnZhiYu</code> 支持 6 种代码高亮样式：</p><ul>
<li>darker</li>
<li>pale night</li>
<li>light</li>
<li>ocean</li>
<li>mac</li>
<li>mac light</li>
</ul><p><code>darker</code></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/db9272c763224179a6627d75748ec8576433acf03c029.png" alt="darker" /><figcaption>darker</figcaption></figure><p></p><p><code>pale night</code></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/be885d1473894dceb833f26b02e77a926433acf02c312.png" alt="pale night" /><figcaption>pale night</figcaption></figure><p></p><p><code>light</code></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/3462d3703887400088239a85d7d591636433acf0382d1.png" alt="light" /><figcaption>light</figcaption></figure><p></p><p><code>ocean</code></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/4c03894af96747a39e68b8257bf9cef26433acf03185f.png" alt="ocean" /><figcaption>ocean</figcaption></figure><p></p><p><code>mac</code></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/a03ea5ff016048e7a7fc42ed0b2638e36433acf031c0d.png" alt="mac" /><figcaption>mac</figcaption></figure><p></p><p><code>mac light</code></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/9326c1cb3268499aab46c8e556e0f5db6433acf038752.png" alt="mac light" /><figcaption>mac light</figcaption></figure><p></p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>highlight_theme</span><span>: </span><span>light</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>代码复制<a href="#代码复制"><span>#</span></a></h4><p>主题支持代码复制功能，修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>highlight_copy</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>代码框展开/关闭<a href="#代码框展开关闭"><span>#</span></a></h4><p>在默认情况下，代码框自动展开，可设置是否所有代码框都关闭状态，点击&gt;可展开代码</p><ul>
<li>true 全部代码框不展开，需点击&gt;打开</li>
<li>false 代码框展开，有&gt;点击按钮</li>
<li>none 不显示&gt;按钮</li>
</ul><p>修改 主题配置文件</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>highlight_shrink</span><span>: </span><span>true</span><span> </span><span>#代码框不展开，需点击 '&gt;' 打开</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>相关信息</p><p>你也可以在 post/page 页对应的 markdown 文件 front-matter 添加 highlight_shrink 来独立配置。</p><p>当<strong>主题配置文件</strong>中的 <code>highlight_shrink</code> 设为 true 时，可在 front-matter 添加 <code>highlight_shrink: false</code> 来单独配置文章展开代码框。</p><p>当<strong>主题配置文件</strong>中的 <code>highlight_shrink</code> 设为 false 时，可在 front-matter 添加 <code>highlight_shrink: true</code> 来单独配置文章收缩代码框。</p></section><section><h4>代码换行<a href="#代码换行"><span>#</span></a></h4><p>在默认情况下，Hexo 在编译的时候不会实现代码自动换行。如果你不希望在代码块的区域里有横向滚动条的话，那么你可以考虑开启这个功能。</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>code_word_wrap</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>1</p><p>如果你是使用 <code>highlight</code> 渲染，需要找到你站点的 Hexo 配置文件<code>_config.yml</code>，将 <code>line_number</code> 改成 <code>false</code>:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>highlight</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>3</div></div><div><span>  </span><span>line_number</span><span>: </span><span>false</span><span> </span><span># &lt;- 改这里</span></div></div><div><div><div>4</div></div><div><span>  </span><span>auto_detect</span><span>: </span><span>false</span></div></div><div><div><div>5</div></div><div><span>  </span><span>tab_replace</span><span>:</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果你是使用 <code>prismjs</code> 渲染，需要找到你站点的 Hexo 配置文件<code>_config.yml</code>，将 <code>line_number</code> 改成 <code>false</code>:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>prismjs</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>enable</span><span>: </span><span>false</span></div></div><div><div><div>3</div></div><div><span>  </span><span>preprocess</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>line_number</span><span>: </span><span>false</span><span> </span><span># &lt;- 改这里</span></div></div><div><div><div>5</div></div><div><span>  </span><span>tab_replace</span><span>: </span><span>""</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>代码高度限制<a href="#代码高度限制"><span>#</span></a></h4><p>可配置代码高度限制，超出的部分会隐藏，并显示展开按钮，默认 330，可配置为 <code>false</code>。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>highlight_height_limit</span><span>: </span><span>false</span><span> </span><span># unit: px</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>注意：</p><ol>
<li>单位是 <code>px</code>，直接添加数字，如 200</li>
<li>实际限制高度为 <code>highlight_height_limit + 30 px</code> ，多增加 30px 限制，目的是避免代码高度只超出 highlight_height_limit 一点时，出现展开按钮，展开没内容。</li>
<li>不适用于隐藏后的代码块（ css 设置 display: none）</li>
</ol></section></section><section><h3>图标配置<a href="#图标配置"><span>#</span></a></h3><p>AnZhiYu 支持 <a href="https://www.iconfont.cn/collections/detail?cid=44481" target="_blank">阿里图标</a> (需配置自己的图标)，与 <a href="https://fontawesome.com/icons?from=io" target="_blank">font-awesome v6</a> 图标(需开启<code>fontawesome</code>)，使用阿里图标需配置主题配置文件中<code>icon.ali_iconfont_js</code>字段，默认内置部分图标，修改主题配置文件，视频教程: <a href="https://www.bilibili.com/video/BV1Cv4y1n7FW/?spm_id_from=333.999.0.0&amp;vd_source=4d9717102296e4b7a60ecdfad55ae2dd" target="_blank">安知鱼主题社交图标配置</a></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>icons</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>ali_iconfont_js</span><span>: </span><span># 阿里图标symbol 引用链接，主题会进行加载 symbol 引用</span></div></div><div><div><div>3</div></div><div><span>  </span><span>fontawesome</span><span>: </span><span>false</span><span> </span><span>#是否启用fontawesome6图标</span></div></div><div><div><div>4</div></div><div><span>  </span><span>fontawesome_animation_css</span><span>: </span><span>#fontawesome_animation 如果有就会加载，示例值：https://npm.elemecdn.com/hexo-butterfly-tag-plugins-plus@1.0.17/lib/assets/font-awesome-animation.min.css</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>内置阿里图标库：<a href="https://www.iconfont.cn/collections/detail?cid=44481" target="_blank">https://www.iconfont.cn/collections/detail?cid=44481</a></p><p>使用方法，将图标库中的图标名复制，然后加上前缀<code>anzhiyu-icon-</code>即可，比如<code>github</code>图标，则为<code>anzhiyu-icon-github</code>。</p></section><section><h3>社交图标<a href="#社交图标"><span>#</span></a></h3><p>书写格式 <code>名称：url || icon名称</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## social settings (社交图标设置)</span></div></div><div><div><div>2</div></div><div><span>## formal:</span></div></div><div><div><div>3</div></div><div><span>##   name: link || icon</span></div></div><div><div><div>4</div></div><div><span>social</span><span>:</span></div></div><div><div><div>5</div></div><div><span>  </span><span># Github: https://github.com/anzhiyu-c || anzhiyu-icon-github</span></div></div><div><div><div>6</div></div><div><span>  </span><span># BiliBili: https://space.bilibili.com/372204786 || anzhiyu-icon-bilibili</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如需 hover 动画生效需配置<code>fontawesome_animation_css</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>icons</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>ali_iconfont_js</span><span>: </span><span># 阿里图标symbol 引用链接，主题会进行加载 symbol 引用</span></div></div><div><div><div>3</div></div><div><span>  </span><span>fontawesome</span><span>: </span><span>false</span><span> </span><span>#是否启用fontawesome6图标</span></div></div><div><div><div>4</div></div><div><span>  </span><span>fontawesome_animation_css</span><span>: </span><span>#fontawesome_animation 如果有就会加载，示例值：https://npm.elemecdn.com/hexo-butterfly-tag-plugins-plus@1.0.17/lib/assets/font-awesome-animation.min.css</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>社交图标配置完以后个人卡片会出现图标内容，图标左边的内容为你的站点信息，在 hexo 的配置文件<code>_config.yml</code>中配置<code>author</code>和<code>subtitle</code>字段</p></section><section><h3>个人卡片<a href="#个人卡片"><span>#</span></a></h3><p>个人卡片 hover 后的显示描述，该描述请在<a href="https://docs.anheyu.com/global/extra.html#%E4%BE%A7%E8%BE%B9%E6%A0%8F%E8%AE%BE%E7%BD%AE" target="_blank">侧边栏配置</a>中的<code>aside.card_author.description</code>中修改，支持 html 显示。</p><p>卡片顶部的状态配置：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## 作者卡片 状态</span></div></div><div><div><div>2</div></div><div><span>author_status</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span># 可以是任何图片，建议放表情包或者emoji图片，效果都很好，[表情包速查](https://emotion.xiaokang.me/)</span></div></div><div><div><div>5</div></div><div><span>  </span><span>statusImg</span><span>: </span><span>"https://bu.dusays.com/2023/08/24/64e6ce9c507bb.png"</span></div></div><div><div><div>6</div></div><div><span>  </span><span>skills</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>- </span><span>🤖️ 数码科技爱好者</span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>- </span><span>🔍 分享与热心帮助</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>- </span><span>🏠 智能家居小能手</span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>- </span><span>🔨 设计开发一条龙</span></div></div><div><div><div>11</div></div><div><span><span>    </span></span><span>- </span><span>🤝 专修交互与设计</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>- </span><span>🏃 脚踏实地行动派</span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>- </span><span>🧱 团队小组发动机</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>- </span><span>💢 壮汉人狠话不多</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>顶部图<a href="#顶部图"><span>#</span></a></h3><p>相关信息</p><p>如果不要显示顶部图，可直接配置 <code>disable_top_img: true</code></p><div><div><div></div><div>Note</div></div><div><p>顶部图的获取顺序，如果都没有配置，则不显示顶部图。</p></div></div><ol>
<li>页面顶部图的获取顺序：</li>
</ol><p><code>各自配置的 top_img &gt; 配置文件的 default_top_img</code></p><ol>
<li>文章页顶部图的获取顺序：</li>
</ol><p><code>各自配置的 top_img &gt; cover &gt; 配置文件的 default_top_img</code></p><p>配置中的值：</p>

<table><thead><tr><th>配置</th><th>解释</th></tr></thead><tbody><tr><td>index_img</td><td>主页的 top_img，示例值: index_img: “background: url(<a href="https://img02.anheyu.com/xxx" target="_blank">https://img02.anheyu.com/xxx</a>) top / cover no-repeat”</td></tr><tr><td>default_top_img</td><td>默认的 top_img，当页面的 top_img 没有配置时，会显示 default_top_img</td></tr><tr><td>archive_img</td><td>归档页面的 top_img</td></tr><tr><td>tag_img</td><td>tag 子页面 的 默认 top_img</td></tr><tr><td>tag_per_img</td><td>tag 子页面的 top_img，可配置每个 tag 的 top_img</td></tr><tr><td>category_img</td><td>category 子页面 的 默认 top_img</td></tr><tr><td>category_per_img</td><td>category 子页面的 top_img，可配置每个 category 的 top_img</td></tr></tbody></table><p>其它页面 （tags/categories/自建页面）和 文章页 的 <code>top_img</code> ，请到对应的 md 页面设置 <code>front-matter</code> 中的 <code>top_img</code></p><p>以上所有的 <code>top_img</code> 可配置以下值</p>

<table><thead><tr><th>配置的值</th><th>效果</th></tr></thead><tbody><tr><td>留空</td><td>显示默认的 top_img（如有），否则显示默认的顔色 <br />（文章页 top_img 留空的话，会显示 cover 的值）</td></tr><tr><td>顔色(<br />HEX 值 - #0000FF <br />RGB 值 - rgb(0,0,255) <br />顔色单词 - orange <br /> 渐变色 - linear-gradient( 135deg, #E2B0FF 10%, #9F44D3 100%)</td><td>对应的顔色</td></tr><tr><td>transparent</td><td>透明</td></tr><tr><td>false</td><td>不显示 top_img</td></tr></tbody></table><p>并不推荐为每个 tag 和每个 category 都配置不同的顶部图，因为配置太多会拖慢生成速度</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>tag_per_img：</span></div></div><div><div><div>2</div></div><div><span>  </span><span>aplayer</span><span>: </span><span>https://xxxxxx.png</span></div></div><div><div><div>3</div></div><div><span>  </span><span>android</span><span>: </span><span>ddddddd.png</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>category_per_img：</span></div></div><div><div><div>6</div></div><div><span>  </span><span>随想</span><span>: </span><span>hdhdh.png</span></div></div><div><div><div>7</div></div><div><span>  </span><span>推荐</span><span>: </span><span>ddjdjdjd.png</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>文章置顶<a href="#文章置顶"><span>#</span></a></h3><p>【推荐】<code>hexo-generator-index</code> 从 2.0.0 开始，已经支持文章置顶功能。你可以直接在文章的 <code>front-matter</code> 区域里添加 <code>sticky: 1</code> 属性来把这篇文章置顶。数值越大，置顶的优先级越大。</p></section><section><h3>文章封面<a href="#文章封面"><span>#</span></a></h3><p>文章的 markdown 文档上,在 <code>Front-matter</code> 添加 <code>cover</code> ,并填上要显示的图片地址。</p><p>如果不配置 <code>cover</code>,可以设置显示默认的 cover。</p><p>如果不想在首页显示 cover, 可以设置为 <code>false。</code></p><blockquote><p>文章封面的获取顺序 <code>Front-matter</code> 的 <code>cover</code> &gt; <code>配置文件的 default_cover</code> &gt; <code>false</code></p></blockquote><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>cover</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span># 是否显示文章封面</span></div></div><div><div><div>3</div></div><div><span>  </span><span>index_enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>aside_enable</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>  </span><span>archives_enable</span><span>: </span><span>true</span></div></div><div><div><div>6</div></div><div><span>  </span><span># 封面显示的位置</span></div></div><div><div><div>7</div></div><div><span>  </span><span># 三个值可配置 left , right , both</span></div></div><div><div><div>8</div></div><div><span>  </span><span>position</span><span>: </span><span>both</span></div></div><div><div><div>9</div></div><div><span>  </span><span># 当没有设置cover时，默认的封面显示</span></div></div><div><div><div>10</div></div><div><span>  </span><span>default_cover</span><span>:</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<table><thead><tr><th>参数</th><th>解释</th></tr></thead><tbody><tr><td>index_enable</td><td>主页是否显示文章封面图</td></tr><tr><td>aside_enable</td><td>侧栏是否显示文章封面图</td></tr><tr><td>archives_enable</td><td>归档页面是否显示文章封面图</td></tr><tr><td>position</td><td>主页卡片文章封面的显示位置 <br /> - left：全部显示在左边 <br /> - right：全部显示在右边 <br /> - both：封面位置以左右左右轮流显示</td></tr><tr><td>default_cover</td><td>默认的 cover, 可配置图片链接/顔色/渐变色等</td></tr></tbody></table><p>当配置多张图片时,会随机选择一张作为 cover.此时写法应为</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>default_cover</span><span>:</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>- </span><span>https://file.crazywong.com/gh/jerryc127/CDN@latest/cover/default_bg.png</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>- </span><span>https://file.crazywong.com/gh/jerryc127/CDN@latest/cover/default_bg2.png</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>- </span><span>https://file.crazywong.com/gh/jerryc127/CDN@latest/cover/default_bg3.png</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>文章 meta 显示<a href="#文章-meta-显示"><span>#</span></a></h3><p>这个选项是用来显示文章的相关信息的。</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>post_meta</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>page</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>date_type</span><span>: </span><span>both</span><span> </span><span># created or updated or both 主页文章日期是创建日或者更新日或都显示</span></div></div><div><div><div>4</div></div><div><span>    </span><span>date_format</span><span>: </span><span>relative</span><span> </span><span># date/relative 显示日期还是相对日期</span></div></div><div><div><div>5</div></div><div><span>    </span><span>category</span><span>: </span><span>true</span><span> </span><span># true or false 主页是否显示分类</span></div></div><div><div><div>6</div></div><div><span>    </span><span>tags</span><span>: </span><span>true</span><span> </span><span># true or false 主页是否显示标签</span></div></div><div><div><div>7</div></div><div><span>    </span><span>label</span><span>: </span><span>true</span><span> </span><span># true or false 显示描述性文字</span></div></div><div><div><div>8</div></div><div><span>  </span><span>post</span><span>:</span></div></div><div><div><div>9</div></div><div><span>    </span><span>date_type</span><span>: </span><span>both</span><span> </span><span># created or updated or both 文章页日期是创建日或者更新日或都显示</span></div></div><div><div><div>10</div></div><div><span>    </span><span>date_format</span><span>: </span><span>relative</span><span> </span><span># date/relative 显示日期还是相对日期</span></div></div><div><div><div>11</div></div><div><span>    </span><span>category</span><span>: </span><span>true</span><span> </span><span># true or false 文章页是否显示分类</span></div></div><div><div><div>12</div></div><div><span>    </span><span>tags</span><span>: </span><span>true</span><span> </span><span># true or false 文章页是否显示标签</span></div></div><div><div><div>13</div></div><div><span>    </span><span>label</span><span>: </span><span>true</span><span> </span><span># true or false 显示描述性文字</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>主页文章页</p><p><code>date_format</code>配置时间显示明确时间还是相对时间</p></section><section><h3>文章版权<a href="#文章版权"><span>#</span></a></h3><p>为你的博客文章展示文章版权和许可协议。</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>post_copyright</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>3</div></div><div><span>  </span><span>decode</span><span>: </span><span>false</span></div></div><div><div><div>4</div></div><div><span>  </span><span>author_href</span><span>:</span></div></div><div><div><div>5</div></div><div><span>  </span><span>license</span><span>: </span><span>CC BY-NC-SA 4.0</span></div></div><div><div><div>6</div></div><div><span>  </span><span>license_url</span><span>: </span><span>https://creativecommons.org/licenses/by-nc-sa/4.0/</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>由于 <code>Hexo 4.1</code> 开始，默认对网址进行解码，以至于如果是中文网址，会被解码，可设置 <code>decode: true</code> 来显示中文网址。</p><p>如果有文章（例如：转载文章）不需要显示版权，可以在文章 <code>Front-matter</code> 单独设置</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>copyright</span><span>: </span><span>false</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>支持对单独文章设置版权信息，可以在文章 <code>Front-matter</code> 单独设置</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>copyright_author</span><span>: </span><span>xxxx</span></div></div><div><div><div>2</div></div><div><span>copyright_author_href</span><span>: </span><span>https://xxxxxx.com</span></div></div><div><div><div>3</div></div><div><span>copyright_url</span><span>: </span><span>https://xxxxxx.com</span></div></div><div><div><div>4</div></div><div><span>copyright_info</span><span>: </span><span>此文章版权归xxxxx所有，如有转载，请注明来自原作者</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>文章打赏<a href="#文章打赏"><span>#</span></a></h3><p>在你每篇文章的结尾，可以添加打赏按钮。相关二维码可以自行配置。</p><p>对于没有提供二维码的，可配置一张软件的 icon 图片，然后在 link 上添加相应的打赏链接。用户点击图片就会跳转到链接去。</p><p>link 可以不写，会默认为图片的链接。coinAudio 为投币的音频。</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>reward</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>3</div></div><div><span>  </span><span>coinAudio</span><span>: </span><span>https://npm.elemecdn.com/akilar-candyassets@1.0.36/audio/aowu.m4a</span></div></div><div><div><div>4</div></div><div><span>  </span><span>QR_code</span><span>:</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>- </span><span>img</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@1.1.6/img/post/common/qrcode-weichat.png</span></div></div><div><div><div>6</div></div><div><span>      </span><span>link</span><span>:</span></div></div><div><div><div>7</div></div><div><span>      </span><span>text</span><span>: </span><span>wechat</span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>- </span><span>img</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@1.1.6/img/post/common/qrcode-alipay.png</span></div></div><div><div><div>9</div></div><div><span>      </span><span>link</span><span>:</span></div></div><div><div><div>10</div></div><div><span>      </span><span>text</span><span>: </span><span>alipay</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>TOC<a href="#toc"><span>#</span></a></h3><p>在文章页，会有一个目录，用于显示 TOC。修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>toc</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>post</span><span>: </span><span>true</span></div></div><div><div><div>3</div></div><div><span>  </span><span>page</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>number</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>  </span><span>expand</span><span>: </span><span>false</span></div></div><div><div><div>6</div></div><div><span>  </span><span>style_simple</span><span>: </span><span>false</span><span> </span><span># for post</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<table><thead><tr><th>属性</th><th>解释</th></tr></thead><tbody><tr><td>post</td><td>文章页是否显示 TOC</td></tr><tr><td>page</td><td>普通页面是否显示 TOC</td></tr><tr><td>number</td><td>是否显示章节数</td></tr><tr><td>expand</td><td>是否展开 TOC</td></tr><tr><td>style_simple</td><td>简洁模式（侧边栏只显示 TOC, 只对文章页有效 ）</td></tr></tbody></table><p><strong>为特定的文章配置</strong></p><p>在你的文章 md 文件的头部，加入 toc_number 和 toc，并配置 true 或者 false 即可。</p><p>主题会优先判断文章 Markdown 的 Front-matter 是否有配置，如有，则以 Front-matter 的配置为准。否则，以主题配置文件中的配置为准</p></section><section><h3>相关文章<a href="#相关文章"><span>#</span></a></h3><div><div><div></div><div>Warning</div></div><div><p>当文章封面设置为 <code>false</code> 时，或者没有获取到封面配置，相关文章背景将会显示主题色。</p><p>相关文章推荐的原理是根据文章 tags 的比重来推荐</p></div></div><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>related_post</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>3</div></div><div><span>  </span><span>limit</span><span>: </span><span>6</span><span> </span><span># 显示推荐文章数目</span></div></div><div><div><div>4</div></div><div><span>  </span><span>date_type</span><span>: </span><span>created</span><span> </span><span># or created or updated 文章日期显示创建日或者更新日</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>文章过期提醒<a href="#文章过期提醒"><span>#</span></a></h3><p>可设置是否显示文章过期提醒，以更新时间为基准。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## Displays outdated notice for a post (文章过期提醒)</span></div></div><div><div><div>2</div></div><div><span>noticeOutdate</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>style</span><span>: </span><span>flat</span><span> </span><span># style: simple/flat</span></div></div><div><div><div>5</div></div><div><span>  </span><span>limit_day</span><span>: </span><span>365</span><span> </span><span># When will it be shown</span></div></div><div><div><div>6</div></div><div><span>  </span><span>position</span><span>: </span><span>top</span><span> </span><span># position: top/bottom</span></div></div><div><div><div>7</div></div><div><span>  </span><span>message_prev</span><span>: </span><span>It has been</span></div></div><div><div><div>8</div></div><div><span>  </span><span>message_next</span><span>: </span><span>days since the last update, the content of the article may be outdated.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><code>limit_day</code>： 距离更新时间多少天才显示文章过期提醒</p><p><code>message_prev</code>： 天数之前的文字</p><p><code>message_next</code>：天数之后的文字</p></section><section><h3>文章编辑按钮<a href="#文章编辑按钮"><span>#</span></a></h3><p>在文章标题旁边显示一个编辑按钮，点击会跳转到对应的链接去。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## Post edit</span></div></div><div><div><div>2</div></div><div><span>## Easily browse and edit blog source code online.</span></div></div><div><div><div>3</div></div><div><span>post_edit</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>enable</span><span>: </span><span>false</span></div></div><div><div><div>5</div></div><div><span>  </span><span># url: https://github.com/user-name/repo-name/edit/branch-name/subdirectory-name/</span></div></div><div><div><div>6</div></div><div><span>  </span><span># For example: https://github.com/jerryc127/butterfly.js.org/edit/main/source/</span></div></div><div><div><div>7</div></div><div><span>  </span><span>url</span><span>:</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>文章分页按钮<a href="#文章分页按钮"><span>#</span></a></h3><div><div><div></div><div>Warning</div></div><div><p>当文章封面设置为 <code>false</code> 时，或者没有获取到封面配置，分页背景将会显示主题色。</p><p>可设置分页的逻辑，也可以关闭分页显示</p></div></div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## post_pagination (分页)</span></div></div><div><div><div>2</div></div><div><span>## value: 1 || 2 || false</span></div></div><div><div><div>3</div></div><div><span>## 1: The 'next post' will link to old post</span></div></div><div><div><div>4</div></div><div><span>## 2: The 'next post' will link to new post</span></div></div><div><div><div>5</div></div><div><span>## false: disable pagination</span></div></div><div><div><div>6</div></div><div><span>post_pagination</span><span>: </span><span>false</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<table><thead><tr><th>参数</th><th>解释</th></tr></thead><tbody><tr><td>post_pagination: false</td><td>关闭分页按钮</td></tr><tr><td>post_pagination: 1</td><td>下一篇显示的是旧文章</td></tr><tr><td>post_pagination: 2</td><td>下一篇显示的是新文章</td></tr></tbody></table></section><section><h3>中控台<a href="#中控台"><span>#</span></a></h3><p>主题配置文件中，默认为<code>true</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## 中控台</span></div></div><div><div><div>2</div></div><div><span>centerConsole</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/5853860f/</id>
      <title type="text">友情链接配置</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/5853860f/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>友情链接配置<a href="#友情链接配置"><span>#</span></a></h2><ol>
<li>
<p>前往你的 Hexo 博客的根目录</p>
</li>
<li>
<p>在 Hexo 博客根目录 <code>[blog]</code>下打开终端，输入</p>
</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>hexo</span><span> </span><span>new</span><span> </span><span>page</span><span> </span><span>link</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>
<p>你会找到 <code>source/link/index.md</code> 这个文件</p>
</li>
<li>
<p>修改这个文件： 记得添加 <code>type: "link"</code></p>
</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>link</span></div></div><div><div><div>3</div></div><div><span>date</span><span>: </span><span>2020-12-01 22:19:45</span></div></div><div><div><div>4</div></div><div><span>type</span><span>: </span><span>"link"</span></div></div><div><div><div>5</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>新建文件<code>source\_data\link.yml</code>,没有<code>_data</code>文件夹的话也请自己新建。以下是默认友链格式示例(自己写的教程，夹带点私货不过分吧，嘻嘻)。打开<code>[blog]\source\_data\link.yml</code>，输入：</li>
</ol><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- </span><span>class_name</span><span>: </span><span>框架</span></div></div><div><div><div>2</div></div><div><span>flink_style</span><span>: </span><span>flexcard</span></div></div><div><div><div>3</div></div><div><span>hundredSuffix</span><span>: </span><span>""</span></div></div><div><div><div>4</div></div><div><span>link_list</span><span>:</span></div></div><div><div><div>5</div></div><div><span>- </span><span>name</span><span>: </span><span>Hexo</span></div></div><div><div><div>6</div></div><div><span>link</span><span>: </span><span>https://hexo.io/zh-tw/</span></div></div><div><div><div>7</div></div><div><span>avatar</span><span>: </span><span>https://d33wubrfki0l68.cloudfront.net/6657ba50e702d84afb32fe846bed54fba1a77add/827ae/logo.svg</span></div></div><div><div><div>8</div></div><div><span>descr</span><span>: </span><span>快速、简单且强大的网站框架</span></div></div><div><div><div>9</div></div><div><span>- </span><span>name</span><span>: </span><span>anzhiyu主题</span></div></div><div><div><div>10</div></div><div><span>link</span><span>: </span><span>https://hexo.anheyu.com/</span></div></div><div><div><div>11</div></div><div><span>avatar</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog-static@1.0.4/img/avatar.jpg</span></div></div><div><div><div>12</div></div><div><span>descr</span><span>: </span><span>生活明朗，万物可爱</span></div></div><div><div><div>13</div></div><div><span>siteshot</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-theme-static@1.1.6/img/hexo.anheyu.com.jpg</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>- </span><span>class_name</span><span>: </span><span>推荐博客</span></div></div><div><div><div>16</div></div><div><span>flink_style</span><span>: </span><span>telescopic</span></div></div><div><div><div>17</div></div><div><span>hundredSuffix</span><span>: </span><span>""</span></div></div><div><div><div>18</div></div><div><span>link_list</span><span>:</span></div></div><div><div><div>19</div></div><div><span>- </span><span>name</span><span>: </span><span>安知鱼</span></div></div><div><div><div>20</div></div><div><span>link</span><span>: </span><span>https://hexo.anheyu.com/</span></div></div><div><div><div>21</div></div><div><span>avatar</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog-static@1.0.4/img/avatar.jpg</span></div></div><div><div><div>22</div></div><div><span>descr</span><span>: </span><span>生活明朗，万物可爱</span></div></div><div><div><div>23</div></div><div><span>siteshot</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-theme-static@1.1.6/img/hexo.anheyu.com.jpg</span></div></div><div><div><div>24</div></div><div><span>color</span><span>: </span><span>vip</span></div></div><div><div><div>25</div></div><div><span>tag</span><span>: </span><span>技术</span></div></div><div><div><div>26</div></div><div>
</div></div><div><div><div>27</div></div><div><span>- </span><span>class_name</span><span>: </span><span>小伙伴</span></div></div><div><div><div>28</div></div><div><span>class_desc</span><span>: </span><span>那些人，那些事</span></div></div><div><div><div>29</div></div><div><span>flink_style</span><span>: </span><span>anzhiyu</span></div></div><div><div><div>30</div></div><div><span>hundredSuffix</span><span>: </span><span>""</span></div></div><div><div><div>31</div></div><div><span>link_list</span><span>:</span></div></div><div><div><div>32</div></div><div><span>- </span><span>name</span><span>: </span><span>安知鱼</span></div></div><div><div><div>33</div></div><div><span>link</span><span>: </span><span>https://hexo.anheyu.com/</span></div></div><div><div><div>34</div></div><div><span>avatar</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog-static@1.0.4/img/avatar.jpg</span></div></div><div><div><div>35</div></div><div><span>descr</span><span>: </span><span>生活明朗，万物可爱</span></div></div><div><div><div>36</div></div><div><span>recommend</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>

<table><thead><tr><th>参数</th><th>解释</th></tr></thead><tbody><tr><td>class_name</td><td>【必填】友链分类名</td></tr><tr><td>class_desc</td><td>【可选】友链分类描述</td></tr><tr><td>flink_style</td><td>【必填】<code>flexcard</code>或者<code>anzhiyu</code>或者<code>telescopic</code></td></tr><tr><td>hundredSuffix</td><td>【可选】解决共同进步板块头像质量问题，配置后共同进步板块的头像会添加该后缀（请确保你的图片加上 hundredSuffix 的配置后依然可以访问）。 例如:<code>hundredSuffix: "!w120"</code></td></tr><tr><td>link_list</td><td>【必须】友链列表</td></tr><tr><td>link_list.name</td><td>【必须】友链名称</td></tr><tr><td>link_list.link</td><td>【必须】友链链接</td></tr><tr><td>link_list.avatar</td><td>【必须】友链头像</td></tr><tr><td>link_list.descr</td><td>【必须】友链描述</td></tr><tr><td>link_list.siteshot</td><td>【可选】flink_style 为 flexcard 或 telescopic 时友链的站点图片</td></tr><tr><td>link_list.recommend</td><td>【可选】快捷选项，等于<code>color:""</code> + <code>tag: "荐"</code></td></tr><tr><td>link_list.tag</td><td>【可选】左上角的 tag，为当前友链打上标签 例如:“推荐”</td></tr><tr><td>link_list.color</td><td>【可选】tag 的十六进制背景颜色例如: “#646cff”，提供了两个快捷颜色选项分别是<code>vip</code>和<code>speed</code></td></tr></tbody></table><p>主题配置文件中开启<code>menu</code>中友链和友人帐的注释，注意缩进！！！</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>menu</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span># 文章:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>#   隧道: /archives/ || icon-box-archive</span></div></div><div><div><div>4</div></div><div><span>  </span><span>#   分类: /categories/ || icon-shapes</span></div></div><div><div><div>5</div></div><div><span>  </span><span>#   标签: /tags/ || icon-tags</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>  </span><span>友链</span><span>:</span></div></div><div><div><div>8</div></div><div><span>    </span><span>友人帐</span><span>: </span><span>/link/ || icon-link</span></div></div><div><div><div>9</div></div><div><span>  </span><span>#   朋友圈: /fcircle/ || icon-artstation</span></div></div><div><div><div>10</div></div><div><span>  </span><span>#   留言板: /comments/ || icon-envelope</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>  </span><span># 我的:</span></div></div><div><div><div>13</div></div><div><span>  </span><span>#   音乐馆: /music/ || icon-music</span></div></div><div><div><div>14</div></div><div><span>  </span><span>#   追番页: /bangumis/ || icon-bilibili1</span></div></div><div><div><div>15</div></div><div><span>  </span><span>#   相册集: /album/ || icon-images</span></div></div><div><div><div>16</div></div><div><span>  </span><span>#   小空调: /air-conditioner/ || icon-fan</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>  </span><span>关于</span><span>:</span></div></div><div><div><div>19</div></div><div><span>    </span><span>#   关于本人: /about/ || icon-zhifeiji</span></div></div><div><div><div>20</div></div><div><span>    </span><span>闲言碎语</span><span>: </span><span>/essay/ || icon-lightbulb</span></div></div><div><div><div>21</div></div><div><span>    </span><span>#   随便逛逛: javascript:toRandomPost() || icon-shoe-prints1</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/773950733a554df09fced27d0e1128636432641611b97.png" alt="773950733a554df09fced27d0e1128636432641611b97.png" /><figcaption>773950733a554df09fced27d0e1128636432641611b97.png</figcaption></figure><p></p></section>
<section><h2>与数百博主共同进步<a href="#与数百博主共同进步"><span>#</span></a></h2><p>在主题配置文件中<code>_config.anzhiyu.yml</code>中配置</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 友情链接顶部相关配置</span></div></div><div><div><div>2</div></div><div><span>linkPageTop</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>title</span><span>: </span><span>与数百名博主无限进步</span></div></div><div><div><div>5</div></div><div><span>  </span><span># 添加博主友链的评论自定义格式</span></div></div><div><div><div>6</div></div><div><span>  </span><span>addFriendPlaceholder</span><span>: </span><span>"昵称（请勿包含博客等字样）：</span><span>\n</span><span>网站地址（要求博客地址，请勿提交个人主页）：</span><span>\n</span><span>头像图片url（请提供尽可能清晰的图片，我会上传到我自己的图床）：</span><span>\n</span><span>描述：</span><span>\n</span><span>站点截图（可选）：</span><span>\n</span><span>"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://bu.dusays.com/2023/08/26/64e976513baed.webp" alt="与数百博主共同进步" /><figcaption>与数百博主共同进步</figcaption></figure><p></p><p>建议超过 30 以上的友链数开启，友链数目不够会导致头像无法铺满。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/5e873b4/</id>
      <title type="text">我的装备页面配置</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/5e873b4/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>我的装备页面配置<a href="#我的装备页面配置"><span>#</span></a></h2><p>前往你的 Hexo 博客的根目录 在 Hexo 博客根目录 <code>[blog]</code> 下打开终端，输入</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>hexo</span><span> </span><span>new</span><span> </span><span>page</span><span> </span><span>equipment</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>你会找到 <code>source/equipment/index.md</code> 这个文件</p><p>修改这个文件： 记得添加 <code>type: "equipment"</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>title</span><span>: </span><span>我的装备</span></div></div><div><div><div>2</div></div><div><span>date</span><span>: </span><span>2023-06-10 21:33:24</span></div></div><div><div><div>3</div></div><div><span>type</span><span>: </span><span>equipment</span></div></div><div><div><div>4</div></div><div><span>aside</span><span>: </span><span>false</span></div></div><div><div><div>5</div></div><div><span>top_img</span><span>: </span><span>false</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>添加数据，新建文件<code>source\_data\equipment.yml</code>,没有<code>_data</code>文件夹的话也请自己新建。以下是默认格式示例，打开<code>source\_data\equipment.yml</code>，输入</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- </span><span>class_name</span><span>: </span><span>好物</span></div></div><div><div><div>2</div></div><div><span>  </span><span>description</span><span>: </span><span>实物装备推荐</span></div></div><div><div><div>3</div></div><div><span>  </span><span>tip</span><span>: </span><span>跟 安知鱼 一起享受科技带来的乐趣</span></div></div><div><div><div>4</div></div><div><span>  </span><span>top_background</span><span>: </span><span>https://bu.dusays.com/2023/07/05/64a4c38842b7a.webp</span></div></div><div><div><div>5</div></div><div><span>  </span><span>good_things</span><span>:</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>- </span><span>title</span><span>: </span><span>生产力</span></div></div><div><div><div>7</div></div><div><span>      </span><span>description</span><span>: </span><span>提升自己生产效率的硬件设备</span></div></div><div><div><div>8</div></div><div><span>      </span><span>equipment_list</span><span>:</span></div></div><div><div><div>9</div></div><div><span><span>        </span></span><span>- </span><span>name</span><span>: </span><span>MacBook Pro 2021 16 英寸</span></div></div><div><div><div>10</div></div><div><span>          </span><span>specification</span><span>: </span><span>M1 Max 64G / 1TB</span></div></div><div><div><div>11</div></div><div><span>          </span><span>description</span><span>: </span><span>屏幕显示效果好、色彩准确、对比度强、性能强劲、续航优秀。可以用来开发和设计。</span></div></div><div><div><div>12</div></div><div><span>          </span><span>image</span><span>: </span><span>https://bu.dusays.com/2023/07/05/64a4c3b191e2e.png</span></div></div><div><div><div>13</div></div><div><span>          </span><span>link</span><span>: </span><span>/posts/571d.html</span></div></div><div><div><div>14</div></div><div><span><span>        </span></span><span>- </span><span>name</span><span>: </span><span>iPad 2020</span></div></div><div><div><div>15</div></div><div><span>          </span><span>specification</span><span>: </span><span>深空灰 / 128G</span></div></div><div><div><div>16</div></div><div><span>          </span><span>description</span><span>: </span><span>事事玩得转，买前生产力，买后爱奇艺。</span></div></div><div><div><div>17</div></div><div><span>          </span><span>image</span><span>: </span><span>https://bu.dusays.com/2023/07/05/64a4c3b191e2e.png</span></div></div><div><div><div>18</div></div><div><span>          </span><span>link</span><span>: </span><span>https://www.apple.com.cn/ipad-10.2/</span></div></div><div><div><div>19</div></div><div><span><span>        </span></span><span>- </span><span>name</span><span>: </span><span>iPhone 12 mini</span></div></div><div><div><div>20</div></div><div><span>          </span><span>specification</span><span>: </span><span>绿色 / 128G</span></div></div><div><div><div>21</div></div><div><span>          </span><span>description</span><span>: </span><span>超瓷晶面板，玻璃背板搭配铝金属边框，曲线优美的圆角设计，mini大小正好一只手就抓住，深得我心，唯一缺点大概就是续航不够。</span></div></div><div><div><div>22</div></div><div><span>          </span><span>image</span><span>: </span><span>https://bu.dusays.com/2023/07/05/64a4c3ded6319.webp</span></div></div><div><div><div>23</div></div><div><span>          </span><span>link</span><span>: </span><span>https://www.apple.com.cn/iphone-12/specs/</span></div></div><div><div><div>24</div></div><div><span><span>        </span></span><span>- </span><span>name</span><span>: </span><span>AirPods（第三代）</span></div></div><div><div><div>25</div></div><div><span>          </span><span>specification</span><span>: </span><span>标准版</span></div></div><div><div><div>26</div></div><div><span>          </span><span>description</span><span>: </span><span>第三代对比第二代提升很大，和我一样不喜欢入耳式耳机的可以入，空间音频等功能确实新颖，第一次使用有被惊艳到。</span></div></div><div><div><div>27</div></div><div><span>          </span><span>image</span><span>: </span><span>https://bu.dusays.com/2023/07/05/64a4c3ded6319.webp</span></div></div><div><div><div>28</div></div><div><span>          </span><span>link</span><span>: </span><span>https://www.apple.com.cn/airpods-3rd-generation/</span></div></div><div><div><div>29</div></div><div><span><span>    </span></span><span>- </span><span>title</span><span>: </span><span>出行</span></div></div><div><div><div>30</div></div><div><span>      </span><span>description</span><span>: </span><span>用来出行的实物及设备</span></div></div><div><div><div>31</div></div><div><span>      </span><span>equipment_list</span><span>:</span></div></div><div><div><div>32</div></div><div><span><span>        </span></span><span>- </span><span>name</span><span>: </span><span>Apple Watch Series 8</span></div></div><div><div><div>33</div></div><div><span>          </span><span>specification</span><span>: </span><span>黑色</span></div></div><div><div><div>34</div></div><div><span>          </span><span>description</span><span>: </span><span>始终为我的健康放哨，深夜弹出站立提醒，不过确实有效的提高了我的运动频率，配合apple全家桶还是非常棒的产品，缺点依然是续航。</span></div></div><div><div><div>35</div></div><div><span>          </span><span>image</span><span>: </span><span>https://bu.dusays.com/2023/07/05/64a4c40ab698a.webp</span></div></div><div><div><div>36</div></div><div><span>          </span><span>link</span><span>: </span><span>https://www.apple.com.cn/apple-watch-series-8/</span></div></div><div><div><div>37</div></div><div><span><span>        </span></span><span>- </span><span>name</span><span>: </span><span>NATIONAL GEOGRAPHIC双肩包</span></div></div><div><div><div>38</div></div><div><span>          </span><span>specification</span><span>: </span><span>黑色</span></div></div><div><div><div>39</div></div><div><span>          </span><span>description</span><span>: </span><span>国家地理黑色大包，正好装下16寸 Macbook Pro，并且背起来很舒适，底部自带防雨罩也好用，各种奇怪的小口袋深得我心。</span></div></div><div><div><div>40</div></div><div><span>          </span><span>image</span><span>: </span><span>https://bu.dusays.com/2023/07/05/64a4c40ab698a.webp</span></div></div><div><div><div>41</div></div><div><span>          </span><span>link</span><span>: </span><span>https://item.jd.com/100011269828.html</span></div></div><div><div><div>42</div></div><div><span><span>        </span></span><span>- </span><span>name</span><span>: </span><span>NATIONAL GEOGRAPHIC学生书包🎒</span></div></div><div><div><div>43</div></div><div><span>          </span><span>specification</span><span>: </span><span>红白色</span></div></div><div><div><div>44</div></div><div><span>          </span><span>description</span><span>: </span><span>国家地理黑色大包，冰冰🧊同款，颜值在线且实用。</span></div></div><div><div><div>45</div></div><div><span>          </span><span>image</span><span>: </span><span>https://bu.dusays.com/2023/07/05/64a4c40ab698a.webp</span></div></div><div><div><div>46</div></div><div><span>          </span><span>link</span><span>: </span><span>https://item.jd.com/100005889786.html</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>主题配置文件中开启menu中关于和我的装备的注释，导航栏我的装备，注意缩进！！！</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>menu</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span># 文章:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>#   隧道: /archives/ || anzhiyu-icon-box-archive</span></div></div><div><div><div>4</div></div><div><span>  </span><span>#   分类: /categories/ || anzhiyu-icon-shapes</span></div></div><div><div><div>5</div></div><div><span>  </span><span>#   标签: /tags/ || anzhiyu-icon-tags</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>  </span><span># 友链:</span></div></div><div><div><div>8</div></div><div><span>  </span><span>#   友人帐: /link/ || anzhiyu-icon-link</span></div></div><div><div><div>9</div></div><div><span>  </span><span>#   朋友圈: /fcircle/ || anzhiyu-icon-artstation</span></div></div><div><div><div>10</div></div><div><span>  </span><span>#   留言板: /comments/ || anzhiyu-icon-envelope</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>  </span><span># 我的:</span></div></div><div><div><div>13</div></div><div><span>  </span><span>#   音乐馆: /music/ || anzhiyu-icon-music</span></div></div><div><div><div>14</div></div><div><span>  </span><span>#   追番页: /bangumis/ || anzhiyu-icon-bilibili</span></div></div><div><div><div>15</div></div><div><span>  </span><span>#   相册集: /album/ || anzhiyu-icon-images</span></div></div><div><div><div>16</div></div><div><span>  </span><span>#   小空调: /air-conditioner/ || anzhiyu-icon-fan</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>  </span><span>关于</span><span>:</span></div></div><div><div><div>19</div></div><div><span>    </span><span>#   关于本人: /about/ || anzhiyu-icon-paper-plane</span></div></div><div><div><div>20</div></div><div><span>    </span><span>#   闲言碎语: /essay/ || anzhiyu-icon-lightbulb</span></div></div><div><div><div>21</div></div><div><span>    </span><span>#   随便逛逛: javascript:toRandomPost() || anzhiyu-icon-shoe-prints1</span></div></div><div><div><div>22</div></div><div><span>    </span><span>我的装备</span><span>: </span><span>/equipment/ || anzhiyu-icon-dice-d20</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/5f7448b7/</id>
      <title type="text">Front-matter 的基本认识</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/5f7448b7/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>🧱 Front-matter 的基本认识<a href="#-front-matter-的基本认识"><span>#</span></a></h2><p><code>Front-matter</code> 是 <code>markdown</code> 文件最上方以 <code>---</code> 分隔的区域，用于指定个别档案的变数。其中又分为两种 markdown 里</p><ol>
<li>Page Front-matter 用于页面配置</li>
<li>Post Front-matter 用于文章页配置</li>
</ol><blockquote><p><strong>TIP</strong>
如果标注可选的参数，可根据自己需要添加，不用全部都写在 markdown 里</p></blockquote><section><h3><strong>Page Front-matter</strong><a href="#page-front-matter"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>title:</span></div></div><div><div><div>2</div></div><div><span>date:</span></div></div><div><div><div>3</div></div><div><span>updated:</span></div></div><div><div><div>4</div></div><div><span>type:</span></div></div><div><div><div>5</div></div><div><span>comments:</span></div></div><div><div><div>6</div></div><div><span>description:</span></div></div><div><div><div>7</div></div><div><span>keywords:</span></div></div><div><div><div>8</div></div><div><span>top_img:</span></div></div><div><div><div>9</div></div><div><span>mathjax:</span></div></div><div><div><div>10</div></div><div><span>katex:</span></div></div><div><div><div>11</div></div><div><span>aside:</span></div></div><div><div><div>12</div></div><div><span>aplayer:</span></div></div><div><div><div>13</div></div><div><span>highlight_shrink:</span></div></div><div><div><div>14</div></div><div><span>type:</span></div></div><div><div><div>15</div></div><div><span>top_single_background:</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>

<table><thead><tr><th>写法</th><th>解释</th></tr></thead><tbody><tr><td>title</td><td>【必需】页面标题</td></tr><tr><td>date</td><td>【必需】页面创建日期</td></tr><tr><td>type</td><td>【必需】标签、分类、关于、音乐馆、友情链接、相册、相册详情、朋友圈、即刻页面需要配置</td></tr><tr><td>updated</td><td>【可选】页面更新日期</td></tr><tr><td>description</td><td>【可选】页面描述</td></tr><tr><td>keywords</td><td>【可选】页面关键字</td></tr><tr><td>comments</td><td>【可选】显示页面评论模块(默认 true)</td></tr><tr><td>top_img</td><td>【可选】页面顶部图片</td></tr><tr><td>mathjax</td><td>【可选】显示 mathjax(当设置 mathjax 的 per_page: false 时，才需要配置，默认 false)</td></tr><tr><td>katex</td><td>【可选】显示 katex(当设置 katex 的 per_page: false 时，才需要配置，默认 false)</td></tr><tr><td>aside</td><td>【可选】显示侧边栏 (默认 true)</td></tr><tr><td>aplayer</td><td>【可选】在需要的页面加载 aplayer 的 js 和 css,请参考文章下面的音乐 配置</td></tr><tr><td>highlight_shrink</td><td>【可选】配置代码框是否展开(true/false)(默认为设置中 highlight_shrink 的配置)</td></tr><tr><td>top_single_background</td><td>【可选】部分页面的顶部模块背景图片</td></tr></tbody></table></section></section>
<section><h2>Post Front-matter<a href="#post-front-matter"><span>#</span></a></h2><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>title:</span></div></div><div><div><div>2</div></div><div><span>date:</span></div></div><div><div><div>3</div></div><div><span>updated:</span></div></div><div><div><div>4</div></div><div><span>tags:</span></div></div><div><div><div>5</div></div><div><span>category:</span></div></div><div><div><div>6</div></div><div><span>keywords:</span></div></div><div><div><div>7</div></div><div><span>description:</span></div></div><div><div><div>8</div></div><div><span>top_img:</span></div></div><div><div><div>9</div></div><div><span>comments:</span></div></div><div><div><div>10</div></div><div><span>cover:</span></div></div><div><div><div>11</div></div><div><span>toc:</span></div></div><div><div><div>12</div></div><div><span>toc_number:</span></div></div><div><div><div>13</div></div><div><span>toc_style_simple:</span></div></div><div><div><div>14</div></div><div><span>copyright:</span></div></div><div><div><div>15</div></div><div><span>copyright_author:</span></div></div><div><div><div>16</div></div><div><span>copyright_author_href:</span></div></div><div><div><div>17</div></div><div><span>copyright_url:</span></div></div><div><div><div>18</div></div><div><span>copyright_info:</span></div></div><div><div><div>19</div></div><div><span>mathjax:</span></div></div><div><div><div>20</div></div><div><span>katex:</span></div></div><div><div><div>21</div></div><div><span>aplayer:</span></div></div><div><div><div>22</div></div><div><span>highlight_shrink:</span></div></div><div><div><div>23</div></div><div><span>aside:</span></div></div><div><div><div>24</div></div><div><span>swiper_index: 1</span></div></div><div><div><div>25</div></div><div><span>top_group_index: 1</span></div></div><div><div><div>26</div></div><div><span>background: "#fff"</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>

<table><thead><tr><th>写法</th><th>解释</th></tr></thead><tbody><tr><td>title</td><td>【必需】文章标题</td></tr><tr><td>date</td><td>【必需】文章创建日期</td></tr><tr><td>updated</td><td>【可选】文章更新日期</td></tr><tr><td>tags</td><td>【可选】文章标签</td></tr><tr><td>categories</td><td>【可选】文章分类</td></tr><tr><td>keywords</td><td>【可选】文章关键字</td></tr><tr><td>description</td><td>【可选】文章描述</td></tr><tr><td>top_img</td><td>【可选】文章顶部图片</td></tr><tr><td>cover</td><td>【可选】文章缩略图(如果没有设置 top_img,文章页顶部将显示缩略图，可设为 false/图片地址/留空)</td></tr><tr><td>comments</td><td>【可选】显示文章评论模块(默认 true)</td></tr><tr><td>toc</td><td>【可选】显示文章 TOC(默认为设置中 toc 的 enable 配置)</td></tr><tr><td>toc_number</td><td>【可选】显示 toc_number(默认为设置中 toc 的 number 配置)</td></tr><tr><td>toc_style_simple</td><td>【可选】显示 toc 简洁模式</td></tr><tr><td>copyright</td><td>【可选】显示文章版权模块(默认为设置中 post_copyright 的 enable 配置)</td></tr><tr><td>copyright_author</td><td>【可选】文章版权模块的<code>文章作者</code></td></tr><tr><td>copyright_author_href</td><td>【可选】文章版权模块的<code>文章作者</code>链接</td></tr><tr><td>copyright_url</td><td>【可选】文章版权模块的<code>文章链接</code>链接</td></tr><tr><td>copyright_info</td><td>【可选】文章版权模块的版权声明文字</td></tr><tr><td>mathjax</td><td>【可选】显示 mathjax(当设置 mathjax 的 per_page: false 时，才需要配置，默认 false)</td></tr><tr><td>katex</td><td>【可选】显示 katex(当设置 katex 的 per_page: false 时，才需要配置，默认 false)</td></tr><tr><td>aplayer</td><td>【可选】在需要的页面加载 aplayer 的 js 和 css,请参考文章下面的<code>音乐</code> 配置</td></tr><tr><td>highlight_shrink</td><td>【可选】配置代码框是否展开(true/false)(默认为设置中 highlight_shrink 的配置)</td></tr><tr><td>aside</td><td>【可选】显示侧边栏 (默认 true)</td></tr><tr><td>swiper_index</td><td>【可选】首页轮播图配置 index 索引，数字越小越靠前</td></tr><tr><td>top_group_index</td><td>【可选】首页右侧卡片组配置, 数字越小越靠前</td></tr><tr><td>ai</td><td>【可选】文章ai摘要</td></tr><tr><td>main_color</td><td>【可选】文章主色，必须是16进制颜色且有6位，不可缩减，例如#ffffff 不可写成#fff</td></tr></tbody></table><ol>
<li>首页轮播图配置: <code>swiper_index</code>, 数字越小越靠前</li>
<li>首页卡片配置: <code>top_group_index</code>, 数字越小越靠前</li>
<li>page 中<code>top_single_background</code>, 可配置部分页面的顶部背景图片</li>
</ol><blockquote><p><strong>TIP</strong>
只需要在你的文章顶部的<code>Front-matter</code>配置这<code>swiper_index</code>和<code>top_group_index</code>两个字段即可显示轮播图和推荐卡片</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/6ee71a71/</id>
      <title type="text">全局配置</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/6ee71a71/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>评论<a href="#评论"><span>#</span></a></h2><p>开启评论需要在 comments-use 中填写你需要的评论。</p><p>支持双评论显示，只需要配置两个评论（第一个为默认显示）</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>comments</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span># Up to two comments system, the first will be shown as default</span></div></div><div><div><div>3</div></div><div><span>  </span><span># Choose: Valine/Waline/Twikoo/</span></div></div><div><div><div>4</div></div><div><span>  </span><span>use</span><span>: </span><span>Twikoo,Waline</span><span> </span><span># Twikoo/Waline</span></div></div><div><div><div>5</div></div><div><span>  </span><span>text</span><span>: </span><span>true</span><span> </span><span># Display the comment name next to the button</span></div></div><div><div><div>6</div></div><div><span>  </span><span># lazyload: The comment system will be load when comment element enters the browser's viewport.</span></div></div><div><div><div>7</div></div><div><span>  </span><span># If you set it to true, the comment count will be invalid</span></div></div><div><div><div>8</div></div><div><span>  </span><span>lazyload</span><span>: </span><span>false</span></div></div><div><div><div>9</div></div><div><span>  </span><span>count</span><span>: </span><span>true</span><span> </span><span># Display comment count in post's top_img</span></div></div><div><div><div>10</div></div><div><span>  </span><span>card_post_count</span><span>: </span><span>false</span><span> </span><span># Display comment count in Home Page</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<table><thead><tr><th>参数</th><th>解释</th></tr></thead><tbody><tr><td>use</td><td>使用的评论（请注意，最多支持两个，如果不需要请留空）</td></tr><tr><td>text</td><td>是否显示评论服务商的名字</td></tr><tr><td>lazyload</td><td>是否为评论开启 lazyload，开启后，只有滚动到评论位置时才会加载评论所需要的资源（开启 lazyload 后，评论数将不显示）</td></tr><tr><td>count</td><td>是否在文章顶部显示评论数</td></tr><tr><td>card_post_count</td><td>是否在首页文章卡片显示评论数</td></tr></tbody></table><section><h3>Twikoo<a href="#twikoo"><span>#</span></a></h3><p><code>Twikoo</code> 是一个简洁、安全、无后端的静态网站评论系统，基于<a href="https://cloud.tencent.com/product/tcb" target="_blank">腾讯云开发</a>。</p><p>具体如何配置评论，请查看 <a href="https://twikoo.js.org/quick-start.html" target="_blank">Twikoo 文档</a></p><p>你只需要把获取到的 <code>环境 ID (envId)</code> 填写到配置上去就行</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># Twikoo</span></div></div><div><div><div>2</div></div><div><span># https://github.com/imaegoo/twikoo</span></div></div><div><div><div>3</div></div><div><span>twikoo</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>envId</span><span>:</span></div></div><div><div><div>5</div></div><div><span>  </span><span>region</span><span>:</span></div></div><div><div><div>6</div></div><div><span>  </span><span>visitor</span><span>: </span><span>false</span></div></div><div><div><div>7</div></div><div><span>  </span><span>option</span><span>:</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<table><thead><tr><th>参数</th><th>解释</th></tr></thead><tbody><tr><td>envId</td><td>环境 ID</td></tr><tr><td>region</td><td>环境地域，默认为 ap-shanghai，如果您的环境地域不是上海，需传此参数</td></tr><tr><td>visitor</td><td>是否显示文章阅读数</td></tr><tr><td>option</td><td>可选配置</td></tr><tr><td>card_post_count</td><td>是否在首页文章卡片显示评论数</td></tr></tbody></table><p>开启 visitor 后，文章页的访问人数将改为 Twikoo 提供，而不是 <code>不蒜子</code></p></section><section><h3>Valine<a href="#valine"><span>#</span></a></h3><p>遵循 <a href="https://github.com/xCss/Valine" target="_blank">Valine</a> 的指示去配置你的 LeanCloud 应用。以及查看相应的配置说明。</p><p>然后修改 <code>主题配置文件</code>:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>valine</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>appId</span><span>: </span><span># leancloud application app id</span></div></div><div><div><div>3</div></div><div><span>  </span><span>appKey</span><span>: </span><span># leancloud application app key</span></div></div><div><div><div>4</div></div><div><span>  </span><span>avatar</span><span>: </span><span>monsterid</span><span> </span><span># gravatar style https://valine.js.org/#/avatar</span></div></div><div><div><div>5</div></div><div><span>  </span><span>serverURLs</span><span>: </span><span># This configuration is suitable for domestic custom domain name users, overseas version will be automatically detected (no need to manually fill in)</span></div></div><div><div><div>6</div></div><div><span>  </span><span>bg</span><span>: </span><span># valine background</span></div></div><div><div><div>7</div></div><div><span>  </span><span>visitor</span><span>: </span><span>false</span></div></div><div><div><div>8</div></div><div><span>  </span><span>option</span><span>:</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>开启 visitor 后，文章页的访问人数将改为 Valine 提供，而不是 不蒜子</p><p>Valine 于 v1.4.5 开始支持自定义表情，如果你需要自行配置，请在 emojiCDN 配置表情 CDN。</p><p>同时在 Hexo 工作目录下的 source/_data/创建一个 json 文件 valine.json,等同于 Valine 需要配置的 emojiMaps，valine.json 配置方式可参考如下</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"tv_doge"</span><span>: </span><span>"6ea59c827c414b4a2955fe79e0f6fd3dcd515e24.png"</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>"tv_亲亲"</span><span>: </span><span>"a8111ad55953ef5e3be3327ef94eb4a39d535d06.png"</span><span>,</span></div></div><div><div><div>4</div></div><div><span>  </span><span>"tv_偷笑"</span><span>: </span><span>"bb690d4107620f1c15cff29509db529a73aee261.png"</span><span>,</span></div></div><div><div><div>5</div></div><div><span>  </span><span>"tv_再见"</span><span>: </span><span>"180129b8ea851044ce71caf55cc8ce44bd4a4fc8.png"</span><span>,</span></div></div><div><div><div>6</div></div><div><span>  </span><span>"tv_冷漠"</span><span>: </span><span>"b9cbc755c2b3ee43be07ca13de84e5b699a3f101.png"</span><span>,</span></div></div><div><div><div>7</div></div><div><span>  </span><span>"tv_发怒"</span><span>: </span><span>"34ba3cd204d5b05fec70ce08fa9fa0dd612409ff.png"</span><span>,</span></div></div><div><div><div>8</div></div><div><span>  </span><span>"tv_发财"</span><span>: </span><span>"34db290afd2963723c6eb3c4560667db7253a21a.png"</span><span>,</span></div></div><div><div><div>9</div></div><div><span>  </span><span>"tv_可爱"</span><span>: </span><span>"9e55fd9b500ac4b96613539f1ce2f9499e314ed9.png"</span><span>,</span></div></div><div><div><div>10</div></div><div><span>  </span><span>"tv_吐血"</span><span>: </span><span>"09dd16a7aa59b77baa1155d47484409624470c77.png"</span><span>,</span></div></div><div><div><div>11</div></div><div><span>  </span><span>"tv_呆"</span><span>: </span><span>"fe1179ebaa191569b0d31cecafe7a2cd1c951c9d.png"</span><span>,</span></div></div><div><div><div>12</div></div><div><span>  </span><span>"tv_呕吐"</span><span>: </span><span>"9f996894a39e282ccf5e66856af49483f81870f3.png"</span><span>,</span></div></div><div><div><div>13</div></div><div><span>  </span><span>"tv_困"</span><span>: </span><span>"241ee304e44c0af029adceb294399391e4737ef2.png"</span><span>,</span></div></div><div><div><div>14</div></div><div><span>  </span><span>"tv_坏笑"</span><span>: </span><span>"1f0b87f731a671079842116e0991c91c2c88645a.png"</span><span>,</span></div></div><div><div><div>15</div></div><div><span>  </span><span>"tv_大佬"</span><span>: </span><span>"093c1e2c490161aca397afc45573c877cdead616.png"</span><span>,</span></div></div><div><div><div>16</div></div><div><span>  </span><span>"tv_大哭"</span><span>: </span><span>"23269aeb35f99daee28dda129676f6e9ea87934f.png"</span><span>,</span></div></div><div><div><div>17</div></div><div><span>  </span><span>"tv_委屈"</span><span>: </span><span>"d04dba7b5465779e9755d2ab6f0a897b9b33bb77.png"</span><span>,</span></div></div><div><div><div>18</div></div><div><span>  </span><span>"tv_害羞"</span><span>: </span><span>"a37683fb5642fa3ddfc7f4e5525fd13e42a2bdb1.png"</span><span>,</span></div></div><div><div><div>19</div></div><div><span>  </span><span>"tv_尴尬"</span><span>: </span><span>"7cfa62dafc59798a3d3fb262d421eeeff166cfa4.png"</span><span>,</span></div></div><div><div><div>20</div></div><div><span>  </span><span>"tv_微笑"</span><span>: </span><span>"70dc5c7b56f93eb61bddba11e28fb1d18fddcd4c.png"</span><span>,</span></div></div><div><div><div>21</div></div><div><span>  </span><span>"tv_思考"</span><span>: </span><span>"90cf159733e558137ed20aa04d09964436f618a1.png"</span><span>,</span></div></div><div><div><div>22</div></div><div><span>  </span><span>"tv_惊吓"</span><span>: </span><span>"0d15c7e2ee58e935adc6a7193ee042388adc22af.png"</span></div></div><div><div><div>23</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>Waline<a href="#waline"><span>#</span></a></h3><p>Waline - 一款从 Valine 衍生的带后端评论系统。可以将 Waline 等价成 With backend Valine。</p><p>具体配置可参考 <a href="https://waline.js.org/" target="_blank">waline 文档</a></p><p>然后修改 主题配置文件:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>waline</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>serverURL</span><span>: </span><span># Waline server address url</span></div></div><div><div><div>3</div></div><div><span>  </span><span>bg</span><span>: </span><span># waline background</span></div></div><div><div><div>4</div></div><div><span>  </span><span>pageview</span><span>: </span><span>false</span></div></div><div><div><div>5</div></div><div><span>  </span><span>option</span><span>:</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>开启 pageview 后，文章页的访问人数将改为 Waline 提供，而不是 不蒜子</p></section></section>
<section><h2>在线聊天<a href="#在线聊天"><span>#</span></a></h2><section><h3>通用配置<a href="#通用配置"><span>#</span></a></h3><p>这些工具都提供了一个按钮可以打开/关闭聊天窗口。 主题也提供了一个集合主题特色的按钮来替换这些工具本身的按钮，这个聊天按钮将会出现在右下角里。 你只需要把 <code>chat_btn</code> 打开就行。</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># Chat Button [recommend]</span></div></div><div><div><div>2</div></div><div><span># It will create a button in the bottom right corner of website, and hide the origin button</span></div></div><div><div><div>3</div></div><div><span>chat_btn</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>为了不影响访客的体验，主题提供一个 <code>chat_hide_show</code> 配置 设为 true 后，使用工具提供的按钮时，只有向上滚动才会显示聊天按钮，向下滚动时会隐藏按钮。</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># The origin chat button is displayed when scrolling up, and the button is hidden when scrolling down</span></div></div><div><div><div>2</div></div><div><span>chat_hide_show</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果使用工具自带的聊天按钮，按钮位置可能会遮挡右下角图标，请配置 <code>rightside-bottom</code> 调正右下角图标位置</p></section><section><h3>chatra<a href="#chatra"><span>#</span></a></h3><p>配置 <a href="https://chatra.com/cn/" target="_blank">chatra</a>,需要知道 <code>Public key</code></p><p>打开 <a href="https://chatra.com/cn/" target="_blank">chatra</a> 并注册账号。 你可以在 <code>Preferences</code> 中找到 <code>Public key</code></p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># chatra</span></div></div><div><div><div>2</div></div><div><span># https://chatra.io/</span></div></div><div><div><div>3</div></div><div><span>chatra</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>  </span><span>id</span><span>: </span><span>xxxxxxxx</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><code>chatra</code> 的样式你可以 <code>Chat Widget</code> 自行配置</p></section><section><h3>tidio<a href="#tidio"><span>#</span></a></h3><p>配置 tidio,需要知道 <code>Public key</code></p><p>打开 <a href="https://www.tidio.com/" target="_blank">tidio</a> 并注册账号。 你可以在 <code>Preferences &gt; Developer</code> 中找到 <code>Public key</code></p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># tidio</span></div></div><div><div><div>2</div></div><div><span># https://www.tidio.com/</span></div></div><div><div><div>3</div></div><div><span>tidio</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>  </span><span>public_key</span><span>: </span><span>XXXX</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><code>tidio</code>的样式你可以<code>Channels</code>自行配置</p></section><section><h3>daovoice<a href="#daovoice"><span>#</span></a></h3><p>打开 <a href="https://www.daocloud.io/" target="_blank">daovoice</a> 和注册帐号</p><p>找到你的 <code>app id</code><img src="https://file.crazywong.com/gh/jerryc127/CDN/img/hexo-theme-butterfly-docs-chat-daovoice-appid.png" alt="" /></p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># daovoice</span></div></div><div><div><div>2</div></div><div><span># http://daovoice.io/</span></div></div><div><div><div>3</div></div><div><span>daovoice</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>  </span><span>app_id</span><span>: </span><span>xxxxx</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>可在<code>聊天设置</code>里配置聊天按钮等样式</p></section><section><h3>crisp<a href="#crisp"><span>#</span></a></h3><p>打开 <a href="https://crisp.chat/en/" target="_blank">crisp</a> 并注册帐号</p><p>找到需要的网站 ID</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># crisp</span></div></div><div><div><div>2</div></div><div><span># https://crisp.chat/en/</span></div></div><div><div><div>3</div></div><div><span>crisp</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>enable</span><span>: </span><span>false</span></div></div><div><div><div>5</div></div><div><span>  </span><span>website_id</span><span>: </span><span>xxxxxxxx</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://file.crazywong.com/gh/jerryc127/CDN/img/hexo-theme-buttefly-docs-chat-crisp.png" alt="" /></p></section><section><h3>messenger<a href="#messenger"><span>#</span></a></h3><p>messenger 为 Facebook 旗下的聊天服务</p><p>具体操作请查看 <a href="https://developers.facebook.com/docs/messenger-platform/discovery/facebook-chat-plugin/" target="_blank">Facebook 洽谈附加程式 - Messenger 平台</a></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>messenger</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>enable</span><span>: </span><span>false</span></div></div><div><div><div>3</div></div><div><span>  </span><span>pageID</span><span>: </span><span>xxxxx</span></div></div><div><div><div>4</div></div><div><span>  </span><span>lang</span><span>: </span><span>zh_TW</span><span> </span><span># Language en_US/zh_CN/zh_TW and so on</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>ai 摘要<a href="#ai-摘要"><span>#</span></a></h2><p>需主题版本大于 1.1.6 版本</p><p>修改主题配置文件，其中<code>key</code>和<code>Referer</code> 为 <code>tianli gpt</code> 的<code>key</code>和<code>Referer</code>，可在 <a href="https://afdian.net/item/886a79d4db6711eda42a52540025c377" target="_blank">https://afdian.net/item/886a79d4db6711eda42a52540025c377</a> 购买 key，购买完成后请立即在<a href="https://summary.tianli0.top/" target="_blank">前端面板</a>绑定 key，以防止被盗用。</p><p>适用于 AnZhiYu 主题项目的 Key，前端管理面板 <a href="https://summary.tianli0.top/" target="_blank">https://summary.tianli0.top/</a></p><p>每个 key 限制请求字数 50000 字，如果是已经请求过的内容不会再次消耗 key 使用时需要绑定 key。 虚拟物品一经发出不支持退款。</p><p>关于续费： 续费和绑定流程相同，绑定成功后会自动充值到原有的 key 上，也就是说无需更改网页中的 key 参数，直接绑定即可。 格式发送，返回的 token 即你的剩余字数</p><p>yaml</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 文章顶部ai摘要</span></div></div><div><div><div>2</div></div><div><span>post_head_ai_description:</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>enable: true</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>gptName: AnZhiYu</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>mode: local # 默认模式 可选值: tianli/local</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>switchBtn: false # 可以配置是否显示切换按钮 以切换tianli/local</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>btnLink: https://afdian.net/item/886a79d4db6711eda42a52540025c377</span></div></div><div><div><div>8</div></div><div><span><span>  </span></span><span>randomNum: 3 # 按钮最大的随机次数，也就是一篇文章最大随机出来几种</span></div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>basicWordCount: 1000 # 最低获取字符数, 最小1000, 最大1999</span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>key: xxxx</span></div></div><div><div><div>11</div></div><div><span><span>  </span></span><span>Referer: https://xx.xx/</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>配置完成以后在文章的<code>Front-matter</code>配置<code>ai: true</code> 使用 <code>tianli gpt</code> 需将 mode 改为<code>tianli</code> 然后在需要 ai 摘要的文章的<code>Front-matter配置ai: true</code></p><p>如果使用<code>local</code>,需要按照以下方式配置</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>AnZhiYu主题快速开始</span></div></div><div><div><div>3</div></div><div><span>ai</span><span>:</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>- </span><span>本教程介绍了如何在博客中安装基于Hexo主题的安知鱼主题，并提供了安装、应用主题、修改配置文件、本地启动等详细步骤及技术支持方式。教程的内容针对最新的主题版本进行更新，如果你是旧版本教程会有出入。</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>- </span><span>本文真不错</span></div></div><div><div><div>6</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<table><thead><tr><th>mode</th><th>对比</th></tr></thead><tbody><tr><td>tianli</td><td>具有完备的训练后端功能，可优秀的完成文章的摘要，方便的快速生成对应摘要</td></tr><tr><td>local</td><td>本地，需自行在文章顶部添加 ai 摘要，内容自行决定，书写较为麻烦。</td></tr></tbody></table></section>
<section><h2>控制台信息<a href="#控制台信息"><span>#</span></a></h2><p>关于控制台信息，主题不提供修改配置，但是可以在主题配置文件中进行关闭。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 控制台打印信息</span></div></div><div><div><div>2</div></div><div><span>console</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>控制台打印时间相关信息可以配置页脚内容来修改。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>footer</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>owner</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>    </span><span>since</span><span>: </span><span>2020</span></div></div><div><div><div>5</div></div><div><span>  </span><span>custom_text</span><span>:</span></div></div><div><div><div>6</div></div><div><span>  </span><span>copyright</span><span>: </span><span>false</span><span> </span><span># Copyright of theme and framework</span></div></div><div><div><div>7</div></div><div><span>  </span><span>runtime</span><span>:</span></div></div><div><div><div>8</div></div><div><span>    </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>9</div></div><div><span>    </span><span>launch_time</span><span>: </span><span>04/01/2021 00:00:00</span><span> </span><span># 网站上线时间</span></div></div><div><div><div>10</div></div><div><span>    </span><span>work_img</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@2.0.4/img/badge/安知鱼-上班摸鱼中.svg</span></div></div><div><div><div>11</div></div><div><span>    </span><span>work_description</span><span>: </span><span>距离月入25k也就还差一个大佬带我~</span></div></div><div><div><div>12</div></div><div><span>    </span><span>offduty_img</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@2.0.4/img/badge/安知鱼-下班啦.svg</span></div></div><div><div><div>13</div></div><div><span>    </span><span>offduty_description</span><span>: </span><span>下班了就该开开心心的玩耍，嘿嘿~</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果实在有强迫症也可以自行修改内容<code>themes/anzhiyu/layout/includes/anzhiyu/log-js.pug</code>。</p><p></p><figure><img src="https://upload-bbs.miyoushe.com/upload/2025/07/09/125766904/c1dcc452a9ceca93564790f0bb441b1d_1028622417931412206.png" alt="控制台打印信息" /><figcaption>控制台打印信息</figcaption></figure><p></p></section>
<section><h2>如何配置首页顶部右侧不使用轮播图<a href="#如何配置首页顶部右侧不使用轮播图"><span>#</span></a></h2><p></p><figure><img src="https://img02.anheyu.com/adminuploads/1/2023/03/27/642172c889a45.png" alt="效果预览" /><figcaption>效果预览</figcaption></figure><p></p><p>将主题配置文件中<code>home_top.swiper.enable</code> 修改为 <code>false</code> 即可.</p></section>
<section><h2>标签卖萌<a href="#标签卖萌"><span>#</span></a></h2><p>主题配置文件中</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 标签卖萌</span></div></div><div><div><div>2</div></div><div><span>diytitle</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>leaveTitle</span><span>: </span><span>w(ﾟДﾟ)w 不要走！再看看嘛！</span></div></div><div><div><div>5</div></div><div><span>  </span><span>backTitle</span><span>: </span><span>♪(^∇^*)欢迎肥来！</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>配置关于页与文章页底部打赏二维码<a href="#配置关于页与文章页底部打赏二维码"><span>#</span></a></h2><p>在主题配置文件中</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># Sponsor/reward</span></div></div><div><div><div>2</div></div><div><span>reward</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>coinAudio</span><span>: </span><span>https://npm.elemecdn.com/akilar-candyassets@1.0.36/audio/aowu.m4a</span></div></div><div><div><div>5</div></div><div><span>  </span><span>QR_code</span><span>:</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>- </span><span>img</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@1.1.6/img/post/common/qrcode-weichat.png</span></div></div><div><div><div>7</div></div><div><span>      </span><span>link</span><span>:</span></div></div><div><div><div>8</div></div><div><span>      </span><span>text</span><span>: </span><span>wechat</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>- </span><span>img</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@1.1.6/img/post/common/qrcode-alipay.png</span></div></div><div><div><div>10</div></div><div><span>      </span><span>link</span><span>:</span></div></div><div><div><div>11</div></div><div><span>      </span><span>text</span><span>: </span><span>alipay</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>主题如何获取文章主色调<a href="#主题如何获取文章主色调"><span>#</span></a></h2><p>支持在文章<code>Post Front-matter</code>配置主色<code>main_color</code>，例如</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>AnZhiYu主题安装文档（一）</span></div></div><div><div><div>3</div></div><div><span>date</span><span>: </span><span>2023-03-26 18:55:44</span></div></div><div><div><div>4</div></div><div><span>main_color</span><span>: </span><span>"#c0e0e0"</span></div></div><div><div><div>5</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>主题将会优先获取文章<code>Post Front-matter</code>颜色，如果未设置才会使用<code>cdn/api/both</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 主色调相关配置</span></div></div><div><div><div>2</div></div><div><span>mainTone</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span><span> </span><span># true or false 文章是否启用获取图片主色调</span></div></div><div><div><div>4</div></div><div><span>  </span><span>mode</span><span>: </span><span>both</span><span> </span><span># cdn/api/both cdn模式为图片url+imageAve参数获取主色调，api模式为请求API获取主色调，both模式会先请求cdn参数，无法获取的情况下将请求API获取</span></div></div><div><div><div>5</div></div><div><span>  </span><span># 项目地址：https://github.com/anzhiyu-c/img2color-go</span></div></div><div><div><div>6</div></div><div><span>  </span><span>api</span><span>: </span><span>https://color.anheyu.com/api?img=</span><span> </span><span># mode为api时可填写</span></div></div><div><div><div>7</div></div><div><span>  </span><span>cover_change</span><span>: </span><span>true</span><span> </span><span># 整篇文章跟随cover修改主色调</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<table><thead><tr><th>参数</th><th>解释</th></tr></thead><tbody><tr><td>enable</td><td>是否开启主色调</td></tr><tr><td>mode</td><td>cdn/api/both cdn 模式为图片 url+imageAve 参数获取主色调，api 模式为请求 API 获取主色调，both 模式会先请求 cdn 参数，无法获取的情况下将请求 API 获取（目前 cdn 模式支持多吉云和腾讯数据万象两种方式）</td></tr><tr><td>api</td><td>mode 为 api 时，需返回 16 进制颜色，可以参考部署项目: <a href="https://github.com/anzhiyu-c/img2color-go" target="_blank">https://github.com/anzhiyu-c/img2color-go</a></td></tr><tr><td>cover_change</td><td>整篇文章跟随 cover 修改主色调</td></tr></tbody></table></section>
<section><h2>双栏<a href="#双栏"><span>#</span></a></h2><p>如果你需要像我一样首页双栏，修改主题配置文件<code>_config.anzhiyu.yml</code>（主题版本需要 1.1.1 以及以上）</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 双栏文章</span></div></div><div><div><div>2</div></div><div><span>article_double_row</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>首页顶部 3 大分类配置<a href="#首页顶部-3-大分类配置"><span>#</span></a></h2><p>首页技能点轮播下的分类，可通过配置主题配置文件<code>home_top</code></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>hexo</span><span> </span><span>new</span><span> </span><span>page</span><span> </span><span>categories</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>Hello World</span></div></div><div><div><div>3</div></div><div><span>category</span><span>: </span><span>前端开发</span></div></div><div><div><div>4</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>只需要在创建分类以后在对应的文章中添加上对应的分类，配置 path 即可，注意一定要对应。</p></section>
<section><h2>左下角音乐球<a href="#左下角音乐球"><span>#</span></a></h2><p>歌单配置很简单，只需要修改主题配置文件中<code>nav_music</code>即可.</p><p>其中 id 与 server 配置可以参考<a href="https://github.com/metowolf/MetingJS" target="_blank">MetingJS</a></p>

<table><thead><tr><th>option</th><th>default</th><th>description</th></tr></thead><tbody><tr><td>id</td><td><strong>require</strong></td><td>song id / playlist id / album id / search keyword</td></tr><tr><td>server</td><td><strong>require</strong></td><td>music platform: <code>netease</code>, <code>tencent</code>, <code>kugou</code>, <code>xiami</code>, <code>baidu</code></td></tr></tbody></table><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 左下角音乐配置项</span></div></div><div><div><div>2</div></div><div><span># https://github.com/metowolf/MetingJS</span></div></div><div><div><div>3</div></div><div><span>nav_music</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>  </span><span>console_widescreen_music</span><span>: </span><span>false</span><span> </span><span># 宽屏状态控制台显示音乐而不是标签 enable为true 控制台依然会显示</span></div></div><div><div><div>6</div></div><div><span>  </span><span>id</span><span>: </span><span>8152976493</span></div></div><div><div><div>7</div></div><div><span>  </span><span>server</span><span>: </span><span>netease</span></div></div><div><div><div>8</div></div><div><span>  </span><span>all_playlist</span><span>: </span><span>https://y.qq.com/n/ryqq/playlist/8802438608</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://upload-bbs.miyoushe.com/upload/2025/07/09/125766904/cf2b1c5fde48d21e4418e1b54a1a5164_4723369210836203093.png" alt="nav_music" /><figcaption>nav_music</figcaption></figure><p></p></section>
<section><h2>评论匿名邮箱<a href="#评论匿名邮箱"><span>#</span></a></h2><p>目前只支持 Twikoo</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 评论匿名邮箱</span></div></div><div><div><div>2</div></div><div><span>visitorMail</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>mail</span><span>: </span><span>visitor@anheyu.com</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/8b137612742545af9e113d3f7ca0c724ff8c3b886c1458502c6ee380fca57242_541291655091259594.png" alt="8b137612742545af9e113d3f7ca0c724ff8c3b886c1458502c6ee380fca57242_541291655091259594.png" /><figcaption>8b137612742545af9e113d3f7ca0c724ff8c3b886c1458502c6ee380fca57242_541291655091259594.png</figcaption></figure><p></p></section>
<section><h2>文章底部工具<a href="#文章底部工具"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># ptool 文章底部工具</span></div></div><div><div><div>2</div></div><div><span>ptool</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>share_mobile</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>  </span><span>share_weibo</span><span>: </span><span>true</span></div></div><div><div><div>6</div></div><div><span>  </span><span>share_copyurl</span><span>: </span><span>true</span></div></div><div><div><div>7</div></div><div><span>  </span><span>category</span><span>: </span><span>false</span><span> </span><span># 是否显示分类</span></div></div><div><div><div>8</div></div><div><span>  </span><span>mode</span><span>: </span><span>/wechat/</span><span> </span><span># 运营模式与责任，不配置不显示</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gitee.com/wbgithub/pic-bak/raw/master//3dc3656d3f244c5297925cc50d34aedb207dcb8f055b525fdbb993de52709e90_5925419818209142417.png" alt="3dc3656d3f244c5297925cc50d34aedb207dcb8f055b525fdbb993de52709e90_5925419818209142417.png" /><figcaption>3dc3656d3f244c5297925cc50d34aedb207dcb8f055b525fdbb993de52709e90_5925419818209142417.png</figcaption></figure><p></p></section>
<section><h2>首页技能点配置<a href="#首页技能点配置"><span>#</span></a></h2><p>[blog]代表你的博客根目录。示例数据中的图片链接为本人图床，请自行上传至您自己的图床，（不保证永久可用性）。</p><p>主题配置文件，关闭<code>peoplecanvas.enable</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 首页随便逛逛people模式 而非技能点模式，关闭后为技能点模式需要配置creativity.yml</span></div></div><div><div><div>2</div></div><div><span>peoplecanvas</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>false</span></div></div><div><div><div>4</div></div><div><span>  </span><span>img</span><span>: </span><span>https://upload-bbs.miyoushe.com/upload/2024/07/27/125766904/ee23df8517f3c3e3efc4145658269c06_236200206013649395..png</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>  </span><span># 备用图片（如上面的失效可以用这张） https://upload-bbs.miyoushe.com/upload/2024/07/27/125766904/ee23df8517f3c3e3efc4145658269c06_5446750740417254342..png</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>创建<code>[blog]/source/_data/creativity.yml</code>，输入以下内容</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- </span><span>class_name</span><span>: </span><span>开启创造力</span></div></div><div><div><div>2</div></div><div><span>  </span><span>creativity_list</span><span>:</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>Java</span></div></div><div><div><div>4</div></div><div><span>      </span><span>color</span><span>: </span><span>"#fff"</span></div></div><div><div><div>5</div></div><div><span>      </span><span>icon</span><span>: </span><span>https://upload-bbs.miyoushe.com/upload/2025/07/29/125766904/26ba17ce013ecde9afc8b373e2fc0b9d_1804318147854602575.jpg</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>Docker</span></div></div><div><div><div>7</div></div><div><span>      </span><span>color</span><span>: </span><span>"#57b6e6"</span></div></div><div><div><div>8</div></div><div><span>      </span><span>icon</span><span>: </span><span>https://upload-bbs.miyoushe.com/upload/2025/07/29/125766904/544b2d982fd5c4ede6630b29d86f3cae_7350393908531420887.png</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>Photoshop</span></div></div><div><div><div>10</div></div><div><span>      </span><span>color</span><span>: </span><span>"#4082c3"</span></div></div><div><div><div>11</div></div><div><span>      </span><span>icon</span><span>: </span><span>https://upload-bbs.miyoushe.com/upload/2025/07/29/125766904/4ce1d081b9b37b06e3714bee95e58589_1613929877388832041.png</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>Node</span></div></div><div><div><div>13</div></div><div><span>      </span><span>color</span><span>: </span><span>"#333"</span></div></div><div><div><div>14</div></div><div><span>      </span><span>icon</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@2.1.1/img/svg/node-logo.svg</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>Webpack</span></div></div><div><div><div>16</div></div><div><span>      </span><span>color</span><span>: </span><span>"#2e3a41"</span></div></div><div><div><div>17</div></div><div><span>      </span><span>icon</span><span>: </span><span>https://upload-bbs.miyoushe.com/upload/2025/07/29/125766904/32dc115fbfd1340f919f0234725c6fb4_4060605986539473613.png</span></div></div><div><div><div>18</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>Pinia</span></div></div><div><div><div>19</div></div><div><span>      </span><span>color</span><span>: </span><span>"#fff"</span></div></div><div><div><div>20</div></div><div><span>      </span><span>icon</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@2.0.8/img/svg/pinia-logo.svg</span></div></div><div><div><div>21</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>Python</span></div></div><div><div><div>22</div></div><div><span>      </span><span>color</span><span>: </span><span>"#fff"</span></div></div><div><div><div>23</div></div><div><span>      </span><span>icon</span><span>: </span><span>https://upload-bbs.miyoushe.com/upload/2025/07/29/125766904/02c9c621414cc2ca41035d809a4154be_7912546659792951301.png</span></div></div><div><div><div>24</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>Vite</span></div></div><div><div><div>25</div></div><div><span>      </span><span>color</span><span>: </span><span>"#937df7"</span></div></div><div><div><div>26</div></div><div><span>      </span><span>icon</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@2.0.8/img/svg/vite-logo.svg</span></div></div><div><div><div>27</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>Flutter</span></div></div><div><div><div>28</div></div><div><span>      </span><span>color</span><span>: </span><span>"#4499e4"</span></div></div><div><div><div>29</div></div><div><span>      </span><span>icon</span><span>: </span><span>https://upload-bbs.miyoushe.com/upload/2025/07/29/125766904/b5aa93e0b61d8c9784cf76d14886ea46_4590392178423108088.png</span></div></div><div><div><div>30</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>Vue</span></div></div><div><div><div>31</div></div><div><span>      </span><span>color</span><span>: </span><span>"#b8f0ae"</span></div></div><div><div><div>32</div></div><div><span>      </span><span>icon</span><span>: </span><span>https://upload-bbs.miyoushe.com/upload/2025/07/29/125766904/cf23526f451784ff137f161b8fe18d5a_692393069314581413.png</span></div></div><div><div><div>33</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>React</span></div></div><div><div><div>34</div></div><div><span>      </span><span>color</span><span>: </span><span>"#222"</span></div></div><div><div><div>35</div></div><div><span>      </span><span>icon</span><span>: </span><span>data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii0xMS41IC0xMC4yMzE3NCAyMyAyMC40NjM0OCI+CiAgPHRpdGxlPlJlYWN0IExvZ288L3RpdGxlPgogIDxjaXJjbGUgY3g9IjAiIGN5PSIwIiByPSIyLjA1IiBmaWxsPSIjNjFkYWZiIi8+CiAgPGcgc3Ryb2tlPSIjNjFkYWZiIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiPgogICAgPGVsbGlwc2Ugcng9IjExIiByeT0iNC4yIi8+CiAgICA8ZWxsaXBzZSByeD0iMTEiIHJ5PSI0LjIiIHRyYW5zZm9ybT0icm90YXRlKDYwKSIvPgogICAgPGVsbGlwc2Ugcng9IjExIiByeT0iNC4yIiB0cmFuc2Zvcm09InJvdGF0ZSgxMjApIi8+CiAgPC9nPgo8L3N2Zz4K</span></div></div><div><div><div>36</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>CSS3</span></div></div><div><div><div>37</div></div><div><span>      </span><span>color</span><span>: </span><span>"#2c51db"</span></div></div><div><div><div>38</div></div><div><span>      </span><span>icon</span><span>: </span><span>https://upload-bbs.miyoushe.com/upload/2025/08/02/125766904/948767d87de7c5733b5f59b036d28b4b_3573026798828830876.png</span></div></div><div><div><div>39</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>JS</span></div></div><div><div><div>40</div></div><div><span>      </span><span>color</span><span>: </span><span>"#f7cb4f"</span></div></div><div><div><div>41</div></div><div><span>      </span><span>icon</span><span>: </span><span>https://upload-bbs.miyoushe.com/upload/2025/07/29/125766904/06216e7fddb6704b57cb89be309443f9_7269407781142156006.png</span></div></div><div><div><div>42</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>HTML</span></div></div><div><div><div>43</div></div><div><span>      </span><span>color</span><span>: </span><span>"#e9572b"</span></div></div><div><div><div>44</div></div><div><span>      </span><span>icon</span><span>: </span><span>https://upload-bbs.miyoushe.com/upload/2025/08/02/125766904/f774c401c8bc2707e1df1323bdc9e423_1926035231499717029.png</span></div></div><div><div><div>45</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>Git</span></div></div><div><div><div>46</div></div><div><span>      </span><span>color</span><span>: </span><span>"#df5b40"</span></div></div><div><div><div>47</div></div><div><span>      </span><span>icon</span><span>: </span><span>https://upload-bbs.miyoushe.com/upload/2025/07/29/125766904/fcc0dbbfe206b4436097a8362d64b558_6981541002497327189.webp</span></div></div><div><div><div>48</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>Apifox</span></div></div><div><div><div>49</div></div><div><span>      </span><span>color</span><span>: </span><span>"#e65164"</span></div></div><div><div><div>50</div></div><div><span>      </span><span>icon</span><span>: </span><span>https://upload-bbs.miyoushe.com/upload/2025/08/02/125766904/b61bc7287d7f7f89bd30079c7f04360e_2465770520170903938.png</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>此时可以看到首页顶部已经有技能点的轮播了。</p><p></p><figure><img src="https://img02.anheyu.com/adminuploads/1/2023/03/26/641fe7b5c77c3.webp" alt="技能点轮播" /><figcaption>技能点轮播</figcaption></figure><p></p><p>文字部分在主题配置文件中<code>home_top</code>配置项修改</p></section>
<section><h2>配置 nav 顶栏左侧应用列表<a href="#配置-nav-顶栏左侧应用列表"><span>#</span></a></h2><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># nav左侧菜单</span></div></div><div><div><div>2</div></div><div><span>nav</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>menu</span><span>:</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>- </span><span>title</span><span>: </span><span>网页</span></div></div><div><div><div>6</div></div><div><span>      </span><span>item</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>        </span></span><span>- </span><span>name</span><span>: </span><span>个人主页</span></div></div><div><div><div>8</div></div><div><span>          </span><span>link</span><span>: </span><span>https://index.anheyu.com/</span></div></div><div><div><div>9</div></div><div><span>          </span><span>icon</span><span>: </span><span>https://bu.dusays.com/2023/08/13/64d8c2748ef34.jpg</span></div></div><div><div><div>10</div></div><div><span><span>        </span></span><span>- </span><span>name</span><span>: </span><span>博客</span></div></div><div><div><div>11</div></div><div><span>          </span><span>link</span><span>: </span><span>https://hexo.anheyu.com/</span></div></div><div><div><div>12</div></div><div><span>          </span><span>icon</span><span>: </span><span>https://bu.dusays.com/2023/07/23/64bc72c75319d.png</span></div></div><div><div><div>13</div></div><div><span><span>        </span></span><span>- </span><span>name</span><span>: </span><span>安知鱼图床</span></div></div><div><div><div>14</div></div><div><span>          </span><span>link</span><span>: </span><span>https://image.anheyu.com/</span></div></div><div><div><div>15</div></div><div><span>          </span><span>icon</span><span>: </span><span>https://bu.dusays.com/2023/08/13/64d8c2653332e.ico</span></div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>- </span><span>title</span><span>: </span><span>项目</span></div></div><div><div><div>17</div></div><div><span>      </span><span>item</span><span>:</span></div></div><div><div><div>18</div></div><div><span><span>        </span></span><span>- </span><span>name</span><span>: </span><span>安知鱼图床</span></div></div><div><div><div>19</div></div><div><span>          </span><span>link</span><span>: </span><span>https://image.anheyu.com/</span></div></div><div><div><div>20</div></div><div><span>          </span><span>icon</span><span>: </span><span>https://bu.dusays.com/2023/08/13/64d8c2653332e.ico</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>
<section><h2>字数统计<a href="#字数统计"><span>#</span></a></h2><p>要为 AnZhiYu 配上字数统计特性, 你需要如下几个步骤:</p><p>打开 hexo 工作目录</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>hexo-wordcount</span><span> </span><span>--save</span></div></div><div><div><div>2</div></div><div><span>或者</span></div></div><div><div><div>3</div></div><div><span>yarn</span><span> </span><span>add</span><span> </span><span>hexo-wordcount</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>修改 主题配置文件:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>wordcount</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>3</div></div><div><span>  </span><span>post_wordcount</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>min2read</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>  </span><span>total_wordcount</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>网站验证<a href="#网站验证"><span>#</span></a></h2><p>如果需要搜索引擎收录网站，可能需要登录对应搜索引擎的管理平台进行提交。 各自的验证码可从各自管理平台拿到</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>site_verification</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span># - name: google_site_verification</span></div></div><div><div><div>3</div></div><div><span>  </span><span>#   content: xxxxxx</span></div></div><div><div><div>4</div></div><div><span>  </span><span># - name: baidu_site_verification</span></div></div><div><div><div>5</div></div><div><span>  </span><span>#   content: xxxxxxx</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>搜索系统<a href="#搜索系统"><span>#</span></a></h2><p>algolia本地搜索DocSearch</p><p>记得运行 hexo clean</p><p>使用 <a href="https://github.com/LouisBarranqueiro/hexo-algoliasearch" target="_blank">hexo-algoliasearch</a>，请记得配置 fields 参数的 <code>title</code>, <code>permalink</code> 和 <code>content</code></p><p>你需要安装 <a href="https://github.com/LouisBarranqueiro/hexo-algoliasearch" target="_blank">hexo-algoliasearch</a>. 根据它的说明文档去做相应的配置。</p><p>修改 主题配置文件</p><p>yaml</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>algolia_search:</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>enable: true</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>hits:</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>per_page: 6</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>hexo 配置文件 <code>_config.yml</code> 添加以下内容</p><p>注意 algolia 搜索出来 URL 前缀为 hexo 配置文件<code>_config.yml</code>中的<code>url</code>配置。</p><p>yaml</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># algolia搜索: https://github.com/LouisBarranqueiro/hexo-algoliasearch</span></div></div><div><div><div>2</div></div><div><span>algolia:</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>appId: "xxxx"</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>apiKey: "xxxx"</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>adminApiKey: "xxxx"</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>chunkSize: 5000</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>indexName: "hexo"</span></div></div><div><div><div>8</div></div><div><span><span>  </span></span><span>fields:</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>- content:strip:truncate,0,200</span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>- excerpt:strip</span></div></div><div><div><div>11</div></div><div><span><span>    </span></span><span>- gallery</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>- permalink</span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>- photos</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>- slug</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>- tags</span></div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>- title</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>
<section><h2>数学公式<a href="#数学公式"><span>#</span></a></h2><p>hexo-renderer-pandoc（推荐）MathjaxKaTeXhexo-renderer-markdown-ithexo-renderer-markdown-it-plus</p><p>详情请见 <a href="https://www.yyyzyyyz.cn/posts/654d8712aff4/" target="_blank">https://www.yyyzyyyz.cn/posts/654d8712aff4/</a></p></section>
<section><h2>分享<a href="#分享"><span>#</span></a></h2><p>只能选择一个分享服务商</p><p>sharejsaddtoany</p><p>如果你不知道 <a href="https://github.com/overtrue/share.js/" target="_blank">sharejs</a>，看看它的説明。</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>sharejs</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>3</div></div><div><span>  </span><span>sites</span><span>: </span><span>facebook,twitter,wechat,weibo,qq</span><span> </span><span>#想要显示的内容</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>欢迎语配置<a href="#欢迎语配置"><span>#</span></a></h2><p>在每次进入首页时根据当前时间弹出欢迎语，为 true 时必须配置 list。</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 欢迎语配置</span></div></div><div><div><div>2</div></div><div><span>greetingBox</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span><span> </span><span>#开启后必须配置下面的list对应的时间段，不然会出现小白条</span></div></div><div><div><div>4</div></div><div><span>  </span><span>default</span><span>: </span><span>晚上好👋</span></div></div><div><div><div>5</div></div><div><span>  </span><span>list</span><span>:</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>- </span><span>greeting</span><span>: </span><span>晚安😴</span></div></div><div><div><div>7</div></div><div><span>      </span><span>startTime</span><span>: </span><span>0</span></div></div><div><div><div>8</div></div><div><span>      </span><span>endTime</span><span>: </span><span>5</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>- </span><span>greeting</span><span>: </span><span>早上好鸭👋, 祝你一天好心情！</span></div></div><div><div><div>10</div></div><div><span>      </span><span>startTime</span><span>: </span><span>6</span></div></div><div><div><div>11</div></div><div><span>      </span><span>endTime</span><span>: </span><span>9</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>- </span><span>greeting</span><span>: </span><span>上午好👋, 状态很好，鼓励一下～</span></div></div><div><div><div>13</div></div><div><span>      </span><span>startTime</span><span>: </span><span>10</span></div></div><div><div><div>14</div></div><div><span>      </span><span>endTime</span><span>: </span><span>10</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>- </span><span>greeting</span><span>: </span><span>11点多啦, 在坚持一下就吃饭啦～</span></div></div><div><div><div>16</div></div><div><span>      </span><span>startTime</span><span>: </span><span>11</span></div></div><div><div><div>17</div></div><div><span>      </span><span>endTime</span><span>: </span><span>11</span></div></div><div><div><div>18</div></div><div><span><span>    </span></span><span>- </span><span>greeting</span><span>: </span><span>午安👋, 宝贝</span></div></div><div><div><div>19</div></div><div><span>      </span><span>startTime</span><span>: </span><span>12</span></div></div><div><div><div>20</div></div><div><span>      </span><span>endTime</span><span>: </span><span>14</span></div></div><div><div><div>21</div></div><div><span><span>    </span></span><span>- </span><span>greeting</span><span>: </span><span>🌈充实的一天辛苦啦！</span></div></div><div><div><div>22</div></div><div><span>      </span><span>startTime</span><span>: </span><span>14</span></div></div><div><div><div>23</div></div><div><span>      </span><span>endTime</span><span>: </span><span>18</span></div></div><div><div><div>24</div></div><div><span><span>    </span></span><span>- </span><span>greeting</span><span>: </span><span>19点喽, 奖励一顿丰盛的大餐吧🍔。</span></div></div><div><div><div>25</div></div><div><span>      </span><span>startTime</span><span>: </span><span>19</span></div></div><div><div><div>26</div></div><div><span>      </span><span>endTime</span><span>: </span><span>19</span></div></div><div><div><div>27</div></div><div><span><span>    </span></span><span>- </span><span>greeting</span><span>: </span><span>晚上好👋, 在属于自己的时间好好放松😌~</span></div></div><div><div><div>28</div></div><div><span>      </span><span>startTime</span><span>: </span><span>20</span></div></div><div><div><div>29</div></div><div><span>      </span><span>endTime</span><span>: </span><span>24</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f295fbab122.png" alt="欢迎语配置" /><figcaption>欢迎语配置</figcaption></figure><p></p></section>
<section><h2>博客快捷键<a href="#博客快捷键"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 快捷键配置</span></div></div><div><div><div>2</div></div><div><span>shortcutKey</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>delay</span><span>: </span><span>100</span><span> </span><span># 所有键位延时触发而不是立即触发（包括shift，以解决和浏览器键位冲突问题）</span></div></div><div><div><div>5</div></div><div><span>  </span><span>shiftDelay</span><span>: </span><span>200</span><span> </span><span># shift按下延时多久开启</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f28f14b1677.png" alt="博客快捷键" /><figcaption>博客快捷键</figcaption></figure><p></p></section>
<section><h2>无障碍优化<a href="#无障碍优化"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 无障碍优化（在首页按下「shift + ?」以查看效果）</span></div></div><div><div><div>2</div></div><div><span>accesskey</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f2969b6a83b.webp" alt="无障碍优化" /><figcaption>无障碍优化</figcaption></figure><p></p></section>
<section><h2>友情链接顶部相关配置<a href="#友情链接顶部相关配置"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 友情链接顶部相关配置</span></div></div><div><div><div>2</div></div><div><span>linkPageTop</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>title</span><span>: </span><span>与数百名博主无限进步</span></div></div><div><div><div>5</div></div><div><span>  </span><span># 添加博主友链的评论自定义格式</span></div></div><div><div><div>6</div></div><div><span>  </span><span>addFriendPlaceholder</span><span>: </span><span>"昵称（请勿包含博客等字样）：</span><span>\n</span><span>网站地址（要求博客地址，请勿提交个人主页）：</span><span>\n</span><span>头像图片url（请提供尽可能清晰的图片，我会上传到我自己的图床）：</span><span>\n</span><span>描述：</span><span>\n</span><span>站点截图（可选）：</span><span>\n</span><span>"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://bu.dusays.com/2023/09/02/64f296f1ed91f.webp" alt="" /></p></section>
<section><h2>缩略图后缀<a href="#缩略图后缀"><span>#</span></a></h2><p>该配置用于优化缩略图，archive/tag/category 页面单独开启后缀，可以优化图像质量问题，注意开启后一定要保证你的图片本身可以支持链接后 ➕pageThumbnailSuffix 能够被访问。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 缩略图后缀 archive/tag/category 页面单独开启后缀</span></div></div><div><div><div>2</div></div><div><span>pageThumbnailSuffix</span><span>: </span><span>"!page_thumbnail"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f297a3be6a7.webp" alt="缩略图后缀" /><figcaption>缩略图后缀</figcaption></figure><p></p></section>
<section><h2>隐私协议弹窗<a href="#隐私协议弹窗"><span>#</span></a></h2><p>该弹窗一个窗口会话只会弹出一次。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 隐私协议弹窗</span></div></div><div><div><div>2</div></div><div><span>agreementPopup</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>url</span><span>: </span><span>/privacy</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f297ecbb523.webp" alt="隐私协议弹窗" /><figcaption>隐私协议弹窗</figcaption></figure><p></p></section>
<section><h2>定制化的右键菜单<a href="#定制化的右键菜单"><span>#</span></a></h2><p>开启<code>rightClickMenu</code>即可。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 右键菜单</span></div></div><div><div><div>2</div></div><div><span>rightClickMenu</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f2987b95753.png" alt="右键菜单一般情况" /><figcaption>右键菜单一般情况</figcaption></figure><p></p><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f2987b95753.png" alt="右键菜单链接情况" /><figcaption>右键菜单链接情况</figcaption></figure><p></p></section>
<section><h2>动效控制<a href="#动效控制"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 动效</span></div></div><div><div><div>2</div></div><div><span>dynamicEffect</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>postTopWave</span><span>: </span><span>true</span><span> </span><span># 文章顶部波浪效果</span></div></div><div><div><div>4</div></div><div><span>  </span><span>postTopRollZoomInfo</span><span>: </span><span>true</span><span> </span><span># 文章顶部滚动时缩放</span></div></div><div><div><div>5</div></div><div><span>  </span><span>pageCommentsRollZoom</span><span>: </span><span>true</span><span> </span><span># 非文章页面评论滚动时缩放显示（仅仅Twikoo生效）</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f298e0920cb.webp" alt="文章顶部波浪效果" /><figcaption>文章顶部波浪效果</figcaption></figure><p></p><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f299eb3ea0d.gif" alt="文章顶部滚动时缩放" /><figcaption>文章顶部滚动时缩放</figcaption></figure><p></p><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f29a87d6dbc.gif" alt="非文章页面评论滚动时缩放显示" /><figcaption>非文章页面评论滚动时缩放显示</figcaption></figure><p></p></section>
<section><h2>51A 统计<a href="#51a-统计"><span>#</span></a></h2><p>可以配置 <a href="https://v6.51.la/user/application" target="_blank">51A 统计</a> 与<a href="https://perf.51.la/manage/home" target="_blank">灵雀</a></p><p>配置后可在关于页面显示统计信息。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 51a统计配置</span></div></div><div><div><div>2</div></div><div><span>LA</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>ck</span><span>: </span><span>Jp8wwGQpp21utaFQ</span></div></div><div><div><div>5</div></div><div><span>  </span><span>LingQueMonitorID</span><span>: </span><span>Jp8ztDRrxmTf7LDj</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>警告</p><p>注意一定要开启数据挂件功能!!!</p><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f29c8ae5d5a.png" alt="开启数据挂件" /><figcaption>开启数据挂件</figcaption></figure><p></p><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f29c29019c9.png" alt="51A统计ck" /><figcaption>51A统计ck</figcaption></figure><p></p><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f29be2c2aee.webp" alt="灵雀LingQueMonitorID" /><figcaption>灵雀LingQueMonitorID</figcaption></figure><p></p></section>
<section><h2>页面卡片顶部气泡升起效果<a href="#页面卡片顶部气泡升起效果"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 页面卡片顶部气泡升起效果</span></div></div><div><div><div>2</div></div><div><span>bubble</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>false</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f29d7965a3d.webp" alt="页面卡片顶部气泡升起效果" /><figcaption>页面卡片顶部气泡升起效果</figcaption></figure><p></p></section>
<section><h2>深色模式粒子效果 canvas<a href="#深色模式粒子效果-canvas"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 深色模式粒子效果canvas</span></div></div><div><div><div>2</div></div><div><span>universe</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f29dfaa6f04.webp" alt="深色模式粒子效果canvas" /><figcaption>深色模式粒子效果canvas</figcaption></figure><p></p><div><div><div></div><div>Important</div></div><div></div></div></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/7ac51263/</id>
      <title type="text">额外配置</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/7ac51263/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>额外配置 🚀<a href="#额外配置-"><span>#</span></a></h2><section><h3>Footer 设置<a href="#footer-设置"><span>#</span></a></h3><p><code>since</code> 是一个来展示你站点起始时间的选项。它位于页面的最底部。</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## Footer Settings</span></div></div><div><div><div>2</div></div><div><span>## --------------------------------------</span></div></div><div><div><div>3</div></div><div><span>footer</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>owner</span><span>:</span></div></div><div><div><div>5</div></div><div><span>    </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>6</div></div><div><span>    </span><span>since</span><span>: </span><span>2020</span></div></div><div><div><div>7</div></div><div><span>  </span><span>custom_text</span><span>:</span></div></div><div><div><div>8</div></div><div><span>  </span><span>runtime</span><span>:</span></div></div><div><div><div>9</div></div><div><span>    </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>10</div></div><div><span>    </span><span>launch_time</span><span>: </span><span>04/01/2021 00:00:00</span><span> </span><span># 网站上线时间</span></div></div><div><div><div>11</div></div><div><span>    </span><span>work_img</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@2.0.4/img/badge/安知鱼-上班摸鱼中.svg</span></div></div><div><div><div>12</div></div><div><span>    </span><span>work_description</span><span>: </span><span>距离月入25k也就还差一个大佬带我~</span></div></div><div><div><div>13</div></div><div><span>    </span><span>offduty_img</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@2.0.4/img/badge/安知鱼-下班啦.svg</span></div></div><div><div><div>14</div></div><div><span>    </span><span>offduty_description</span><span>: </span><span>下班了就该开开心心的玩耍，嘿嘿~</span></div></div><div><div><div>15</div></div><div><span>  </span><span># 徽标部分配置项 https://shields.io/</span></div></div><div><div><div>16</div></div><div><span>  </span><span># https://img.shields.io/badge/CDN-jsDelivr-orange?style=flat&amp;logo=jsDelivr</span></div></div><div><div><div>17</div></div><div><span>  </span><span>bdageitem</span><span>:</span></div></div><div><div><div>18</div></div><div><span><span>    </span></span><span>- </span><span>link</span><span>: </span><span>https://hexo.io/</span><span> </span><span>#徽标指向网站链接</span></div></div><div><div><div>19</div></div><div><span>      </span><span>shields</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@2.1.5/img/badge/Frame-Hexo.svg</span><span> </span><span>#徽标API</span></div></div><div><div><div>20</div></div><div><span>      </span><span>message</span><span>: </span><span>博客框架为Hexo_v5.4.0</span><span> </span><span>#徽标提示语</span></div></div><div><div><div>21</div></div><div><span><span>    </span></span><span>- </span><span>link</span><span>: </span><span>https://hexo.anheyu.com/</span></div></div><div><div><div>22</div></div><div><span>      </span><span>shields</span><span>: </span><span>https://pan.anheyu.com/d/anzhiyu/svg/Theme-AnZhiYu-2E67D3.svg</span></div></div><div><div><div>23</div></div><div><span>      </span><span>message</span><span>: </span><span>本站使用AnZhiYu主题</span></div></div><div><div><div>24</div></div><div><span><span>    </span></span><span>- </span><span>link</span><span>: </span><span>https://www.dogecloud.com/</span></div></div><div><div><div>25</div></div><div><span>      </span><span>shields</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@2.2.0/img/badge/CDN-多吉云-3693F3.svg</span></div></div><div><div><div>26</div></div><div><span>      </span><span>message</span><span>: </span><span>本站使用多吉云为静态资源提供CDN加速</span></div></div><div><div><div>27</div></div><div><span><span>    </span></span><span>- </span><span>link</span><span>: </span><span>https://github.com/</span></div></div><div><div><div>28</div></div><div><span>      </span><span>shields</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@2.1.5/img/badge/Source-Github.svg</span></div></div><div><div><div>29</div></div><div><span>      </span><span>message</span><span>: </span><span>本站项目由Github托管</span></div></div><div><div><div>30</div></div><div><span><span>    </span></span><span>- </span><span>link</span><span>: </span><span>http://creativecommons.org/licenses/by-nc-sa/4.0/</span></div></div><div><div><div>31</div></div><div><span>      </span><span>shields</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@2.2.0/img/badge/Copyright-BY-NC-SA.svg</span></div></div><div><div><div>32</div></div><div><span>      </span><span>message</span><span>: </span><span>本站采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议进行许可</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>

<table><thead><tr><th>参数</th><th>解释</th></tr></thead><tbody><tr><td>owner</td><td>页脚网站所有者@2020-当前年份</td></tr><tr><td>owner.enable</td><td>页脚网站所有者是否启用</td></tr><tr><td>owner.since</td><td>页脚年份，控制台中打印的运行时间也来自这里</td></tr><tr><td>runtime</td><td>运行时间</td></tr><tr><td>runtime.enable</td><td>运行时间是否启用</td></tr><tr><td>runtime.launch_time</td><td>网站上线时间</td></tr><tr><td>runtime.work_img</td><td>页脚上班时间的徽标</td></tr><tr><td>runtime.work_description</td><td>页脚上班时间的 title 描述</td></tr><tr><td>runtime.offduty_img</td><td>页脚下班时间的徽标</td></tr><tr><td>runtime.offduty_description</td><td>页脚下班时间的 title 描述</td></tr><tr><td>bdageitem</td><td>徽标配置项</td></tr><tr><td>bdageitem.link</td><td>徽标配置链接</td></tr><tr><td>bdageitem.shields</td><td>徽标配置徽标</td></tr><tr><td>bdageitem.message</td><td>徽标配置徽标 title</td></tr></tbody></table><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/9470df42193744a39e557984871ff2c464412c4c08266.png!blogimg" alt="页脚" /><figcaption>页脚</figcaption></figure><p></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/8b2faf23e079447e9381485c136593de64412cb6bbbf5.png!blogimg" alt="页脚你好自动定义文字" /><figcaption>页脚你好自动定义文字</figcaption></figure><p></p></section><section><h3>侧边栏设置<a href="#侧边栏设置"><span>#</span></a></h3><p>可自行决定哪个项目需要显示，可决定位置，也可以设置不显示侧边栏。</p><p>修改 <code>主题配置文件</code></p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## aside (侧边栏)</span></div></div><div><div><div>2</div></div><div><span>## --------------------------------------</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>aside</span><span>:</span></div></div><div><div><div>5</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>6</div></div><div><span>  </span><span>hide</span><span>: </span><span>false</span></div></div><div><div><div>7</div></div><div><span>  </span><span>button</span><span>: </span><span>true</span></div></div><div><div><div>8</div></div><div><span>  </span><span>mobile</span><span>: </span><span>true</span><span> </span><span># display on mobile</span></div></div><div><div><div>9</div></div><div><span>  </span><span>position</span><span>: </span><span>right</span><span> </span><span># left or right</span></div></div><div><div><div>10</div></div><div><span>  </span><span>display</span><span>: </span><span># 控制对应详情页面是否显示侧边栏</span></div></div><div><div><div>11</div></div><div><span>    </span><span>archive</span><span>: </span><span>true</span></div></div><div><div><div>12</div></div><div><span>    </span><span>tag</span><span>: </span><span>true</span></div></div><div><div><div>13</div></div><div><span>    </span><span>category</span><span>:  </span><span>true</span></div></div><div><div><div>14</div></div><div><span>  </span><span>card_author</span><span>:</span></div></div><div><div><div>15</div></div><div><span>    </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>16</div></div><div><span>    </span><span>description</span><span>: </span><span>&lt;div style="line-height:1.38;margin:0.6rem 0;text-align:justify;color:rgba(255, 255, 255, 0.8);"&gt;这有关于&lt;b style="color:#fff"&gt;产品、设计、开发&lt;/b&gt;相关的问题和看法，还有&lt;b style="color:#fff"&gt;文章翻译&lt;/b&gt;和&lt;b style="color:#fff"&gt;分享&lt;/b&gt;。&lt;/div&gt;&lt;div style="line-height:1.38;margin:0.6rem 0;text-align:justify;color:rgba(255, 255, 255, 0.8);"&gt;相信你可以在这里找到对你有用的&lt;b style="color:#fff"&gt;知识&lt;/b&gt;和&lt;b style="color:#fff"&gt;教程&lt;/b&gt;。&lt;/div&gt;</span></div></div><div><div><div>17</div></div><div><span>    </span><span>name_link</span><span>: </span><span>/about</span></div></div><div><div><div>18</div></div><div><span>  </span><span>card_announcement</span><span>:</span></div></div><div><div><div>19</div></div><div><span>    </span><span>enable</span><span>: </span><span>false</span></div></div><div><div><div>20</div></div><div><span>    </span><span>content</span><span>: </span><span>欢迎来看我的博客鸭~</span></div></div><div><div><div>21</div></div><div><span>  </span><span>card_weixin</span><span>:</span></div></div><div><div><div>22</div></div><div><span>    </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>23</div></div><div><span>    </span><span>face</span><span>: </span><span>https://img02.anheyu.com/adminuploads/1/2022/09/11/631ddb7c9b250.png</span></div></div><div><div><div>24</div></div><div><span>    </span><span>backFace</span><span>: </span><span>https://img02.anheyu.com/adminuploads/1/2022/09/11/631ddeb0900b7.png</span></div></div><div><div><div>25</div></div><div><span>  </span><span>card_recent_post</span><span>:</span></div></div><div><div><div>26</div></div><div><span>    </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>27</div></div><div><span>    </span><span>limit</span><span>: </span><span>5</span><span> </span><span># if set 0 will show all</span></div></div><div><div><div>28</div></div><div><span>    </span><span>sort</span><span>: </span><span>date</span><span> </span><span># date or updated</span></div></div><div><div><div>29</div></div><div><span>    </span><span>sort_order</span><span>: </span><span># Don't modify the setting unless you know how it works</span></div></div><div><div><div>30</div></div><div><span>  </span><span>card_category</span><span>:</span></div></div><div><div><div>31</div></div><div><span>    </span><span>enable</span><span>: </span><span>false</span></div></div><div><div><div>32</div></div><div><span>    </span><span>limit</span><span>: </span><span>8</span><span> </span><span># if set 0 will show all</span></div></div><div><div><div>33</div></div><div><span>    </span><span>expand</span><span>: </span><span>none</span><span> </span><span># none/true/false</span></div></div><div><div><div>34</div></div><div><span>    </span><span>sort_order</span><span>: </span><span># Don't modify the setting unless you know how it works</span></div></div><div><div><div>35</div></div><div><span>  </span><span>card_tags</span><span>:</span></div></div><div><div><div>36</div></div><div><span>    </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>37</div></div><div><span>    </span><span>limit</span><span>: </span><span>40</span><span> </span><span># if set 0 will show all</span></div></div><div><div><div>38</div></div><div><span>    </span><span>color</span><span>: </span><span>false</span></div></div><div><div><div>39</div></div><div><span>    </span><span>sort_order</span><span>: </span><span># Don't modify the setting unless you know how it works</span></div></div><div><div><div>40</div></div><div><span>    </span><span>highlightTags</span><span>:</span></div></div><div><div><div>41</div></div><div><span><span>      </span></span><span>- </span><span>Hexo</span></div></div><div><div><div>42</div></div><div><span><span>      </span></span><span>- </span><span>前端</span></div></div><div><div><div>43</div></div><div><span>  </span><span>card_archives</span><span>:</span></div></div><div><div><div>44</div></div><div><span>    </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>45</div></div><div><span>    </span><span>type</span><span>: </span><span>monthly</span><span> </span><span># yearly or monthly</span></div></div><div><div><div>46</div></div><div><span>    </span><span>format</span><span>: </span><span>MMMM YYYY</span><span> </span><span># eg: YYYY年MM月</span></div></div><div><div><div>47</div></div><div><span>    </span><span>order</span><span>: </span><span>-1</span><span> </span><span># Sort of order. 1, asc for ascending; -1, desc for descending</span></div></div><div><div><div>48</div></div><div><span>    </span><span>limit</span><span>: </span><span>8</span><span> </span><span># if set 0 will show all</span></div></div><div><div><div>49</div></div><div><span>    </span><span>sort_order</span><span>: </span><span># Don't modify the setting unless you know how it works</span></div></div><div><div><div>50</div></div><div><span>  </span><span>card_webinfo</span><span>:</span></div></div><div><div><div>51</div></div><div><span>    </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>52</div></div><div><span>    </span><span>post_count</span><span>: </span><span>true</span></div></div><div><div><div>53</div></div><div><span>    </span><span>last_push_date</span><span>: </span><span>false</span></div></div><div><div><div>54</div></div><div><span>    </span><span>sort_order</span><span>: </span><span># Don't modify the setting unless you know how it works</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>其中 <code>card_weixin</code> 可以控制微信公众号的图片，<code>face</code>为翻转前的图片，<code>backFace</code>为翻转后的图片。</p></section><section><h3>访问人数 busuanzi<a href="#访问人数-busuanzi"><span>#</span></a></h3><p>访问 busuanzi 的<a href="http://busuanzi.ibruce.info/" target="_blank">官方网站</a>查看更多的介绍。</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>busuanzi</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>site_uv</span><span>: </span><span>true</span></div></div><div><div><div>3</div></div><div><span>  </span><span>site_pv</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>page_pv</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>如果需要修改 busuanzi 的 CDN 链接，可通过 主题配置文件 的 CDN 中的 option 进行修改</p></blockquote><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>CDN</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>option</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>busuanzi</span><span>: </span><span>xxxxxxxxx</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/c1d276a918094ddda5eb02a6bb95f8686441312192cba.png" alt="" /></p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/304c478cc46241cfbae0a93448e1a3f06441312d5e8d0.webp!blogimg" alt="" /></p></section><section><h3>运行时间<a href="#运行时间"><span>#</span></a></h3><p>网页已运行时间</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## Time difference between publish date and now (网页运行时间)</span></div></div><div><div><div>2</div></div><div><span>## Formal: Month/Day/Year Time or Year/Month/Day Time</span></div></div><div><div><div>3</div></div><div><span>runtimeshow</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>  </span><span>publish_date</span><span>: </span><span>4/1/2021 00:00:00</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/f95b2520b5944a368341acebe5d85c1b6441319e80977.webp" alt="运行时间" /><figcaption>运行时间</figcaption></figure><p></p></section><section><h3>最新评论<a href="#最新评论"><span>#</span></a></h3><p>最新评论只会在刷新时才会去读取，并不会实时变化</p><p>由于 API 有 访问次数限制，为了避免调用太多，主题默认存取期限为 10 分钟。也就是説，调用后资料会存在 localStorage 里，10 分钟内刷新网站只会去 localStorage 读取资料。 10 分钟期限一过，刷新页面时才会去调取 API 读取新的数据。（ 配置 storage，可自行配置缓存时间）</p><p>在侧边栏显示最新评论板块</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## Console - Newest Comments</span></div></div><div><div><div>2</div></div><div><span>newest_comments</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>sort_order</span><span>: </span><span># Don't modify the setting unless you know how it works</span></div></div><div><div><div>5</div></div><div><span>  </span><span>limit</span><span>: </span><span>6</span></div></div><div><div><div>6</div></div><div><span>  </span><span>storage</span><span>: </span><span>10</span><span> </span><span># unit: mins, save data to localStorage</span></div></div><div><div><div>7</div></div><div><span>  </span><span>avatar</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<table><thead><tr><th>配置</th><th>解释</th></tr></thead><tbody><tr><td>limit</td><td>显示的数量</td></tr><tr><td>storage</td><td>设置缓存时间，单位 分钟</td></tr><tr><td>avatar</td><td>是否显示头像</td></tr></tbody></table><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/40204b074bd644f18202a040453f432f644132e885d91.webp!blogimg" alt="" /></p></section><section><h3>右下角按钮<a href="#右下角按钮"><span>#</span></a></h3><section><h4>简繁转换<a href="#简繁转换"><span>#</span></a></h4><p>简体繁体互换</p><p>右下角会有简繁转换按钮。</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>translate</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>3</div></div><div><span>  </span><span># 默认按钮显示文字(网站是简体，应设置为'default: 繁')</span></div></div><div><div><div>4</div></div><div><span>  </span><span>default</span><span>: </span><span>简</span></div></div><div><div><div>5</div></div><div><span>  </span><span>#网站默认语言，1: 繁体中文, 2: 简体中文</span></div></div><div><div><div>6</div></div><div><span>  </span><span>defaultEncoding</span><span>: </span><span>1</span></div></div><div><div><div>7</div></div><div><span>  </span><span>#延迟时间,若不在前, 要设定延迟翻译时间, 如100表示100ms,默认为0</span></div></div><div><div><div>8</div></div><div><span>  </span><span>translateDelay</span><span>: </span><span>0</span></div></div><div><div><div>9</div></div><div><span>  </span><span>#当文字是简体时，按钮显示的文字</span></div></div><div><div><div>10</div></div><div><span>  </span><span>msgToTraditionalChinese</span><span>: </span><span>"繁"</span></div></div><div><div><div>11</div></div><div><span>  </span><span>#当文字是繁体时，按钮显示的文字</span></div></div><div><div><div>12</div></div><div><span>  </span><span>msgToSimplifiedChinese</span><span>: </span><span>"简"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>简体</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/58315417811e4f2f95d3d63da3a1cc4b644133ef810f7.webp" alt="简体" /><figcaption>简体</figcaption></figure><p></p><blockquote><p>繁体</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/7419ed9d26034b6c84b98dc8682282ec644133ef85f42.webp" alt="繁体" /><figcaption>繁体</figcaption></figure><p></p></section><section><h4>阅读模式<a href="#阅读模式"><span>#</span></a></h4><p>阅读模式下会去掉除文章外的内容，避免干扰阅读。</p><p>只会出现在文章页面，右下角会有阅读模式按钮。</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>readmode</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/16aee5afaff04459b51433114e4297446441350b98041.webp" alt="阅读模式" /><figcaption>阅读模式</figcaption></figure><p></p></section><section><h4>夜间模式<a href="#夜间模式"><span>#</span></a></h4><p>右下角会有夜间模式按钮</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## dark mode</span></div></div><div><div><div>2</div></div><div><span>darkmode</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span># Toggle Button to switch dark/light mode</span></div></div><div><div><div>5</div></div><div><span>  </span><span>button</span><span>: </span><span>true</span></div></div><div><div><div>6</div></div><div><span>  </span><span># Switch dark/light mode automatically (自动切换 dark mode和 light mode)</span></div></div><div><div><div>7</div></div><div><span>  </span><span># autoChangeMode: 1  Following System Settings, if the system doesn't support dark mode, it will switch dark mode between 6 pm to 6 am</span></div></div><div><div><div>8</div></div><div><span>  </span><span># autoChangeMode: 2  Switch dark mode between 6 pm to 6 am</span></div></div><div><div><div>9</div></div><div><span>  </span><span># autoChangeMode: false</span></div></div><div><div><div>10</div></div><div><span>  </span><span>autoChangeMode</span><span>: </span><span>1</span></div></div><div><div><div>11</div></div><div><span>  </span><span># Set the light mode time. The value is between 0 and 24. If not set, the default value is 6 and 18</span></div></div><div><div><div>12</div></div><div><span>  </span><span>start</span><span>: </span><span># 8</span></div></div><div><div><div>13</div></div><div><span>  </span><span>end</span><span>: </span><span># 22</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<table><thead><tr><th>参数</th><th>解释</th></tr></thead><tbody><tr><td>button</td><td>是否在右下角显示日夜模式切换按钮</td></tr><tr><td>autoChangeMode</td><td>自动切换的模式</td></tr><tr><td>autoChangeMode</td><td>autoChangeMode: 1 跟随系统而变化，不支持的浏览器/系统将按照时间 start 到 end 之间切换为 light mode <br /> autoChangeMode: 2 只按照时间 start 到 end 之间切换为 light mode ,其余时间为 dark mode <br /> autoChangeMode: false 取消自动切换</td></tr><tr><td>start</td><td>light mode 的开始时间</td></tr><tr><td>end</td><td>light mode 的结束时间</td></tr></tbody></table></section></section><section><h3>按钮排序<a href="#按钮排序"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## Don't modify the following settings unless you know how they work (非必要请不要修改 )</span></div></div><div><div><div>2</div></div><div><span>## Choose: readmode,translate,darkmode,hideAside,toc,chat,comment</span></div></div><div><div><div>3</div></div><div><span>## Don't repeat 不要重复</span></div></div><div><div><div>4</div></div><div><span>rightside_item_order</span><span>:</span></div></div><div><div><div>5</div></div><div><span>  </span><span>enable</span><span>: </span><span>false</span></div></div><div><div><div>6</div></div><div><span>  </span><span>hide</span><span>: </span><span># readmode,translate,darkmode,hideAside</span></div></div><div><div><div>7</div></div><div><span>  </span><span>show</span><span>: </span><span># toc,chat,comment</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>短标签 Tag Plugins<a href="#短标签-tag-plugins"><span>#</span></a></h3><blockquote><p><strong>TIP</strong>
短标签是 Hexo 独有的功能，并不是标准的 Markdown 格式。 以下的写法，只适用于 AnZhiYu 主题，用在其它主题上不会有效果，甚至可能会报错。使用前请留意</p></blockquote><div><div><div></div><div>Warning</div></div><div><p>短标签虽然能为主题带来一些额外的功能和 UI 方面的强化，但是，短标签也有明显的限制，使用时请留意。</p></div></div><p>只需要将标签写在 md 文件内即可使用，详细写法请阅读 <a href="https://hexo.anheyu.com/posts/d50a.html" target="_blank">安知鱼主题标签 Tag Plugins</a> 查看</p></section><section><h3>评论弹幕<a href="#评论弹幕"><span>#</span></a></h3><p><img src="https://bu.dusays.com/2023/09/02/64f28f14a7a42.png" alt="" /></p><p>评论弹幕仅支持 Twikoo。</p><p>token 在你博客的控制台获取，打开浏览器开发者工具，找到本地存储空间，找到键名为<code>twikoo-access-token</code>的内容，将值复制下来填写即可，本方法仅限 server 部署，其他部署方案请自行查看如何获取 token。</p><p></p><figure><img src="https://bu.dusays.com/2023/09/02/64f292d6d8fef.png" alt="token获取" /><figcaption>token获取</figcaption></figure><p></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## 留言弹幕配置</span></div></div><div><div><div>2</div></div><div><span>comment_barrage_config</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span># 同时最多显示弹幕数</span></div></div><div><div><div>5</div></div><div><span>  </span><span>maxBarrage</span><span>: </span><span>1</span></div></div><div><div><div>6</div></div><div><span>  </span><span># 弹幕显示间隔时间ms</span></div></div><div><div><div>7</div></div><div><span>  </span><span>barrageTime</span><span>: </span><span>8000</span></div></div><div><div><div>8</div></div><div><span>  </span><span># token</span></div></div><div><div><div>9</div></div><div><span>  </span><span>accessToken</span><span>: </span><span>"xxxxxx"</span></div></div><div><div><div>10</div></div><div><span>  </span><span># 博主邮箱md5值</span></div></div><div><div><div>11</div></div><div><span>  </span><span>mailMd5</span><span>: </span><span>"xxxxxxxxxx"</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>分析统计<a href="#分析统计"><span>#</span></a></h3><section><h4>百度统计<a href="#百度统计"><span>#</span></a></h4><ol>
<li>
<p>登录百度统计的<a href="https://tongji.baidu.com/web/welcome/login?castk=LTE%3D" target="_blank">官方网站</a></p>
</li>
<li>
<p>找到你百度统计的统计代码</p>
</li>
</ol><p><img src="https://bu.dusays.com/2023/06/02/64795c52dff22.jpg" alt="" /></p><ol>
<li>修改 <code>主题配置文件</code></li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>baidu_analytics</span><span>: </span><span>你的代码</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>谷歌分析<a href="#谷歌分析"><span>#</span></a></h4><ol>
<li>
<p>登录谷歌分析的<a href="https://www.google.com/analytics/" target="_blank">官方网站</a></p>
</li>
<li>
<p>找到你的谷歌分析的跟踪 ID</p>
</li>
</ol><p></p><figure><img src="https://bu.dusays.com/2023/06/02/64795cfc15eef.jpg" alt="谷歌分析" /><figcaption>谷歌分析</figcaption></figure><p></p><ol>
<li>修改 <code>主题配置文件</code></li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>google_analytics</span><span>: </span><span>你的代码</span><span> </span><span># 通常以`UA-`打头</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>Cloudflare<a href="#cloudflare"><span>#</span></a></h4><ol>
<li>登录 Cloudflare 分析的<a href="https://www.cloudflare.com/zh-tw/web-analytics/" target="_blank">官方网站</a></li>
<li>找到 <code>JavaScript 程式码片段</code></li>
<li>找到你的 <code>token</code><img src="https://bu.dusays.com/2023/06/02/64795d7a7776b.png" alt="" /></li>
<li>修改 <code>主题配置文件</code></li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## Cloudflare Analytics</span></div></div><div><div><div>2</div></div><div><span>## https://www.cloudflare.com/zh-tw/web-analytics/</span></div></div><div><div><div>3</div></div><div><span>cloudflare_analytics</span><span>:</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>Microsoft Clarity<a href="#microsoft-clarity"><span>#</span></a></h4><ol>
<li>
<p>登录 Clarity 的<a href="https://clarity.microsoft.com/" target="_blank">官方网站</a></p>
</li>
<li>
<p>创建 <code>PROJECT</code></p>
</li>
<li>
<p>找到你的 <code>ID</code></p>
</li>
</ol><p><img src="https://bu.dusays.com/2023/06/02/64795dd09af94.png" alt="" /></p><ol>
<li>修改 <code>主题配置文件</code></li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## Microsoft Clarity</span></div></div><div><div><div>2</div></div><div><span>## https://clarity.microsoft.com/</span></div></div><div><div><div>3</div></div><div><span>microsoft_clarity</span><span>:</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h3>广告<a href="#广告"><span>#</span></a></h3><section><h4>谷歌广告<a href="#谷歌广告"><span>#</span></a></h4><p>主题已集成谷歌广告（自动广告）</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>google_adsense</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>3</div></div><div><span>  </span><span>auto_ads</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>js</span><span>: </span><span>https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js</span></div></div><div><div><div>5</div></div><div><span>  </span><span>client</span><span>: </span><span># 填入个人识别码</span></div></div><div><div><div>6</div></div><div><span>  </span><span>enable_page_level_ads</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><img src="https://bu.dusays.com/2023/06/02/64795e6fba8e3.png" alt="" /></p></section><section><h4>手动广告配置<a href="#手动广告配置"><span>#</span></a></h4><p>主题预留了三个位置可供插入广告，分别为主页文章(每三篇文章出现广告)/aside 公告之后/文章页打赏之后。 把 html 代码填写到对应的位置</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>ad</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>index</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>aside</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>post</span><span>:</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>例如:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>index</span><span>: </span><span>&lt;ins class="adsbygoogle" style="display:block" data-ad-format="fluid" data-ad-layout-key="xxxxxxxxxxxx" data-ad-client="ca-pub-xxxxxxxxxx" data-ad-slot="xxxxxxxxxx"&gt;&lt;/ins&gt;&lt;script&gt;(adsbygoogle=window.adsbygoogle||[]).push({})&lt;/script&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h3>页面加载动画<a href="#页面加载动画"><span>#</span></a></h3><p>当进入网页时，因为加载速度的问题，可能会导致 top_img 图片出现断层显示，或者网页加载不全而出现等待时间，开启 preloader 后，会显示加载动画，等页面加载完，加载动画会消失。</p><p>主题支持 pace.js 的加载动画，具体可查看 <a href="https://codebyzach.github.io/pace/" target="_blank">pace.js</a></p><p>修改 <code>主题配置文件</code>，其中<code>avatar</code>可以自定义加载时的头像</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## Loading Animation (加载动画)</span></div></div><div><div><div>2</div></div><div><span>preloader</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span># source</span></div></div><div><div><div>5</div></div><div><span>  </span><span># 1. fullpage-loading</span></div></div><div><div><div>6</div></div><div><span>  </span><span># 2. pace (progress bar)</span></div></div><div><div><div>7</div></div><div><span>  </span><span># else all</span></div></div><div><div><div>8</div></div><div><span>  </span><span>source</span><span>: </span><span>3</span></div></div><div><div><div>9</div></div><div><span>  </span><span># pace theme (see https://codebyzach.github.io/pace/)</span></div></div><div><div><div>10</div></div><div><span>  </span><span>pace_css_url</span><span>:</span></div></div><div><div><div>11</div></div><div><span>  </span><span>avatar</span><span>: </span><span># 自定义头像</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>图片大图查看模式<a href="#图片大图查看模式"><span>#</span></a></h3><div><div><div></div><div>Warning</div></div><div><p>如果你并不想为某张图片添加大图查看模式，你可以使用 html 格式引用图片，并为图片添加 no-lightbox class 名。</p></div></div><p>修改 <code>主题配置文件</code></p></section><section><h3>Pjax<a href="#pjax"><span>#</span></a></h3><p>当用户点击链接，通过 ajax 更新页面需要变化的部分，然后使用 HTML5 的 pushState 修改浏览器的 URL 地址。</p><p>这样可以不用重复加载相同的资源（css/js）， 从而提升网页的加载速度。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## Pjax [Beta]</span></div></div><div><div><div>2</div></div><div><span>## It may contain bugs and unstable, give feedback when you find the bugs.</span></div></div><div><div><div>3</div></div><div><span>## https://github.com/MoOx/pjax</span></div></div><div><div><div>4</div></div><div><span>pjax</span><span>:</span></div></div><div><div><div>5</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>6</div></div><div><span>  </span><span>exclude</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>- </span><span>/music/</span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>- </span><span>/no-pjax/</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p><strong>TIP</strong>
对于一些第三方插件，有些并不支持 pjax 。 你可以把网页加入到 exclude 里，这个网页会被 pjax 排除在外。 点击该网页会重新加载网站</p></blockquote><p>使用 pjax 后，一些自己 DIY 的 js 可能会无效，跳转页面时需要重新调用，请参考<a href="https://github.com/MoOx/pjax" target="_blank">Pjax 文档</a></p><p>使用 pjax 后，一些个别页面加载的 js/css，将会改为所有页面都加载</p><div><div><div></div><div>Warning</div></div><div><p>主题默认开启 Pjax，大量服务依赖于 pjax，关闭可能会造成破坏性问题。 主题对 pjax 做了深度适配，关闭可能会造成严重的后果，比如某些链接无法跳转。</p></div></div><p>安知鱼主题的的 Pjax 目前仍有一些问题，请留意</p><p>使用谷歌广告可能会报错（例如自动广告） 如果你在使用中发现问题，欢迎反馈 Bugs</p></section><section><h3>Snackbar 弹窗<a href="#snackbar-弹窗"><span>#</span></a></h3><p>Snackbar 弹窗,根据自己爱好开启</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## Snackbar 弹窗</span></div></div><div><div><div>2</div></div><div><span>## https://github.com/polonel/SnackBar</span></div></div><div><div><div>3</div></div><div><span>## position 弹窗位置</span></div></div><div><div><div>4</div></div><div><span>## 可选 top-left / top-center / top-right / bottom-left / bottom-center / bottom-right</span></div></div><div><div><div>5</div></div><div><span>snackbar</span><span>:</span></div></div><div><div><div>6</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>7</div></div><div><span>  </span><span>position</span><span>: </span><span>bottom-left</span></div></div><div><div><div>8</div></div><div><span>  </span><span>bg_light</span><span>: </span><span>"#49b1f5"</span><span> </span><span>#light mode时弹窗背景</span></div></div><div><div><div>9</div></div><div><span>  </span><span>bg_dark</span><span>: </span><span>"#2d3035"</span><span> </span><span>#dark mode时弹窗背景</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Pangu<a href="#pangu"><span>#</span></a></h3><blockquote><p>如果你跟我一样，每次看到网页上的中文字和英文、数字、符号挤在一块，就会坐立难安，忍不住想在它们之间加个空格。这个外挂正是你在网路世界走跳所需要的东西，它会自动替你在网页中所有的中文字和半形的英文、数字、符号之间插入空白。</p></blockquote><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## https://github.com/vinta/pangu.js</span></div></div><div><div><div>2</div></div><div><span>## Insert a space between Chinese character and English character (中英文之间添加空格)</span></div></div><div><div><div>3</div></div><div><span>pangu</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>enable</span><span>: </span><span>false</span></div></div><div><div><div>5</div></div><div><span>  </span><span>field</span><span>: </span><span>post</span><span> </span><span># site/post</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><code>field</code>只支持两个参数，<code>post</code>(只在文章页生效)和<code>site</code>(全站生效)</p></section><section><h3>PWA<a href="#pwa"><span>#</span></a></h3><p>PWA 是 web 优化的一种手段，主题做了一定的适配，但是依然需要进行配置。要为 AnZhiYu 配上 PWA 特性, 你可以进行选择以下两种方式来进行适配，<code>hexo-offline</code>适合初学者，<code>hexo-swpp</code>适合已经对<code>service worker</code>有一定解决问题能力的进阶使用。</p><section><h4>hexo-offline<a href="#hexo-offline"><span>#</span></a></h4><ol>
<li>打开 hexo 工作目录</li>
<li><code>npm install hexo-offline --save</code> 或者 <code>yarn add hexo-offline</code></li>
<li>在根目录创建 <code>hexo-offline.config.cjs</code> 文件，并增加以下内容。</li>
</ol><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>// offline config passed to workbox-build.</span></div></div><div><div><div>2</div></div><div><span>module</span><span>.</span><span>exports</span><span> </span><span>=</span><span> {</span></div></div><div><div><div>3</div></div><div><span>  </span><span>// 静态文件合集，如果你的站点使用了例如 webp 格式的文件，请将文件类型添加进去。</span></div></div><div><div><div>4</div></div><div><span>  </span><span>globPatterns</span><span>:</span><span> [</span><span>"404.html"</span><span>, </span><span>"css/index.css"</span><span>],</span></div></div><div><div><div>5</div></div><div><span>  </span><span>globDirectory</span><span>:</span><span> </span><span>"public"</span><span>,</span></div></div><div><div><div>6</div></div><div><span>  </span><span>swDest</span><span>:</span><span> </span><span>"public/service-worker.js"</span><span>,</span></div></div><div><div><div>7</div></div><div><span>  </span><span>maximumFileSizeToCacheInBytes</span><span>:</span><span> </span><span>10485760</span><span>, </span><span>// 缓存的最大文件大小，以字节为单位。</span></div></div><div><div><div>8</div></div><div><span>  </span><span>skipWaiting</span><span>:</span><span> </span><span>true</span><span>,</span></div></div><div><div><div>9</div></div><div><span>  </span><span>clientsClaim</span><span>:</span><span> </span><span>true</span><span>,</span></div></div><div><div><div>10</div></div><div><span>  </span><span>runtimeCaching</span><span>:</span><span> [</span></div></div><div><div><div>11</div></div><div><span>    </span><span>// 如果你需要加载 CDN 资源，请配置该选项，如果没有，可以不配置。</span></div></div><div><div><div>12</div></div><div><span>    </span><span>// CDNs - should be CacheFirst, since they should be used specific versions so should not change</span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>14</div></div><div><span>      </span><span>urlPattern</span><span>:</span><span> /</span><span>^</span><span><span>https:</span><span>\/\/</span><span>npm</span><span>\.</span><span>elemecdn</span><span>\.</span><span>com</span><span>\/</span><span>anzhiyu-blog/</span></span><span>, </span><span>// 缓存elmentcdn</span></div></div><div><div><div>15</div></div><div><span>      </span><span>handler</span><span>:</span><span> </span><span>"CacheFirst"</span><span>,</span></div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>17</div></div><div><span><span>  </span></span><span>],</span></div></div><div><div><div>18</div></div><div><span>  </span><span>manifestTransforms</span><span>:</span><span> [</span></div></div><div><div><div>19</div></div><div><span>    </span><span>async</span><span><span> (</span><span>manifestEntries</span><span>, </span><span>compilation</span><span>) </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>20</div></div><div><span>      </span><span>const</span><span> </span><span>timestamp</span><span> </span><span>=</span><span> </span><span>new</span><span> </span><span>Date</span><span>().</span><span>toISOString</span><span>().</span><span>replace</span><span>(</span><span>/</span><span><span>[-:</span><span>.</span><span>TZ]</span></span><span>/</span><span>g</span><span>, </span><span>""</span><span>); </span><span>// 获取当前时间戳</span></div></div><div><div><div>21</div></div><div><span><span>      </span></span><span>manifestEntries</span><span>.</span><span>push</span><span>(</span></div></div><div><div><div>22</div></div><div><span><span>        </span></span><span>{</span></div></div><div><div><div>23</div></div><div><span>          </span><span>url</span><span>:</span><span> </span><span>"/"</span><span>,</span></div></div><div><div><div>24</div></div><div><span>          </span><span>revision</span><span>:</span><span> </span><span>`index-</span><span>${</span><span>timestamp</span><span>}</span><span>`</span><span>,</span></div></div><div><div><div>25</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>26</div></div><div><span><span>        </span></span><span>{</span></div></div><div><div><div>27</div></div><div><span>          </span><span>url</span><span>:</span><span> </span><span>"music/"</span><span>,</span></div></div><div><div><div>28</div></div><div><span>          </span><span>revision</span><span>:</span><span> </span><span>`music-</span><span>${</span><span>timestamp</span><span>}</span><span>`</span><span>,</span></div></div><div><div><div>29</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>30</div></div><div><span><span>        </span></span><span>{</span></div></div><div><div><div>31</div></div><div><span>          </span><span>url</span><span>:</span><span> </span><span>"about/"</span><span>,</span></div></div><div><div><div>32</div></div><div><span>          </span><span>revision</span><span>:</span><span> </span><span>`about-</span><span>${</span><span>timestamp</span><span>}</span><span>`</span><span>,</span></div></div><div><div><div>33</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>34</div></div><div><span><span>      </span></span><span>);</span></div></div><div><div><div>35</div></div><div><span>      </span><span>return</span><span> { </span><span>manifest</span><span>:</span><span><span> </span><span>manifestEntries</span><span> };</span></span></div></div><div><div><div>36</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>37</div></div><div><span><span>  </span></span><span>],</span></div></div><div><div><div>38</div></div><div><span>};</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>更多内容请查看 <a href="https://github.com/JLHwung/hexo-offline" target="_blank">hexo-offline</a> 的官方文档</p><ol>
<li>在<code>主题配置文件</code>中开启 pwa 选项。</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## PWA</span></div></div><div><div><div>2</div></div><div><span>## See https://github.com/JLHwung/hexo-offline</span></div></div><div><div><div>3</div></div><div><span>## ---------------</span></div></div><div><div><div>4</div></div><div><span>pwa</span><span>:</span></div></div><div><div><div>5</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>6</div></div><div><span>  </span><span>startup_image_enable</span><span>: </span><span>true</span></div></div><div><div><div>7</div></div><div><span>  </span><span>manifest</span><span>: </span><span>/manifest.json</span></div></div><div><div><div>8</div></div><div><span>  </span><span>theme_color</span><span>: </span><span>var(--anzhiyu-main)</span></div></div><div><div><div>9</div></div><div><span>  </span><span>mask_icon</span><span>: </span><span>/img/siteicon/apple-icon-180.png</span></div></div><div><div><div>10</div></div><div><span>  </span><span>apple_touch_icon</span><span>: </span><span>/img/siteicon/apple-icon-180.png</span></div></div><div><div><div>11</div></div><div><span>  </span><span>bookmark_icon</span><span>: </span><span>/img/siteicon/apple-icon-180.png</span></div></div><div><div><div>12</div></div><div><span>  </span><span>favicon_32_32</span><span>: </span><span>/img/siteicon/32.png</span></div></div><div><div><div>13</div></div><div><span>  </span><span>favicon_16_16</span><span>: </span><span>/img/siteicon/16.png</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>在创建<code>source/</code>目录中创建<code>manifest.json</code>文件。</li>
</ol><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"name"</span><span>: </span><span>"安知鱼`Blog"</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>"short_name"</span><span>: </span><span>"安知鱼"</span><span>,</span></div></div><div><div><div>4</div></div><div><span>  </span><span>"theme_color"</span><span>: </span><span>"#3b70fc"</span><span>,</span></div></div><div><div><div>5</div></div><div><span>  </span><span>"background_color"</span><span>: </span><span>"#3b70fc"</span><span>,</span></div></div><div><div><div>6</div></div><div><span>  </span><span>"display"</span><span>: </span><span>"fullscreen"</span><span>,</span></div></div><div><div><div>7</div></div><div><span>  </span><span>"scope"</span><span>: </span><span>"/"</span><span>,</span></div></div><div><div><div>8</div></div><div><span>  </span><span>"start_url"</span><span>: </span><span>"/"</span><span>,</span></div></div><div><div><div>9</div></div><div><span>  </span><span>"id"</span><span>: </span><span>"/"</span><span>,</span></div></div><div><div><div>10</div></div><div><span>  </span><span>"icons"</span><span>: [</span></div></div><div><div><div>11</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>12</div></div><div><span>      </span><span>"src"</span><span>: </span><span>"img/siteicon/manifest-icon-192.maskable.png"</span><span>,</span></div></div><div><div><div>13</div></div><div><span>      </span><span>"sizes"</span><span>: </span><span>"192x192"</span><span>,</span></div></div><div><div><div>14</div></div><div><span>      </span><span>"type"</span><span>: </span><span>"image/png"</span><span>,</span></div></div><div><div><div>15</div></div><div><span>      </span><span>"purpose"</span><span>: </span><span>"any"</span></div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>17</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>18</div></div><div><span>      </span><span>"src"</span><span>: </span><span>"img/siteicon/manifest-icon-192.maskable.png"</span><span>,</span></div></div><div><div><div>19</div></div><div><span>      </span><span>"sizes"</span><span>: </span><span>"192x192"</span><span>,</span></div></div><div><div><div>20</div></div><div><span>      </span><span>"type"</span><span>: </span><span>"image/png"</span><span>,</span></div></div><div><div><div>21</div></div><div><span>      </span><span>"purpose"</span><span>: </span><span>"maskable"</span></div></div><div><div><div>22</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>23</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>24</div></div><div><span>      </span><span>"src"</span><span>: </span><span>"img/siteicon/manifest-icon-512.maskable.png"</span><span>,</span></div></div><div><div><div>25</div></div><div><span>      </span><span>"sizes"</span><span>: </span><span>"512x512"</span><span>,</span></div></div><div><div><div>26</div></div><div><span>      </span><span>"type"</span><span>: </span><span>"image/png"</span><span>,</span></div></div><div><div><div>27</div></div><div><span>      </span><span>"purpose"</span><span>: </span><span>"any"</span></div></div><div><div><div>28</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>29</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>30</div></div><div><span>      </span><span>"src"</span><span>: </span><span>"img/siteicon/manifest-icon-512.maskable.png"</span><span>,</span></div></div><div><div><div>31</div></div><div><span>      </span><span>"sizes"</span><span>: </span><span>"512x512"</span><span>,</span></div></div><div><div><div>32</div></div><div><span>      </span><span>"type"</span><span>: </span><span>"image/png"</span><span>,</span></div></div><div><div><div>33</div></div><div><span>      </span><span>"purpose"</span><span>: </span><span>"maskable"</span></div></div><div><div><div>34</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>35</div></div><div><span><span>  </span></span><span>],</span></div></div><div><div><div>36</div></div><div><span>  </span><span>"splash_pages"</span><span>: </span><span>null</span></div></div><div><div><div>37</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>你也可以通过 <a href="https://app-manifest.firebaseapp.com/" target="_blank">Web App Manifestopen</a> 快速创建<code>manifest.json</code>。（Web App Manifest 要求至少包含一个 512*512 像素的图标）</p><ol>
<li>可以通过<code>Chrome</code>插件<code>Lighthouse</code>检查 PWA 配置是否生效以及配置是否正确。</li>
</ol><ul>
<li>打开博客页面</li>
<li>启动<code>Lighthouse</code>插件 (Lighthouse 插件要求至少包含一个 512*512 像素的图标)</li>
</ul><p>关于 PWA（渐进式增强 Web 应用）的更多内容请参考 <a href="https://developers.google.com/web/tools/lighthouse/audits/address-bar" target="_blank">Google Tools for Web Developersopen</a></p><ol>
<li>生成 pwa 启动图</li>
</ol><ul>
<li>安装 pwa-asset-generator，执行以下命令</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>pwa-asset-generator</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>hexo 根目录执行<code>hexo g</code>后执行以下命令</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npx</span><span> </span><span>pwa-asset-generator</span><span> </span><span>./public/img/512.png</span><span> </span><span>./public/img/siteicon</span><span> </span><span>--padding</span><span> </span><span>"calc(50vh - 20%) calc(50vw - 40%)"</span><span> </span><span>-s</span><span> </span><span>false</span><span> </span><span>-h</span><span> </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>这条命令会使用<code>themes/source/img/512.png</code>这张图片来生成 siteicon 到目录<code>/public/img/siteicon</code>中，由于<code>hexo cl</code>会清除<code>/public</code>目录中的文件，所以每次<code>hexo d</code>之前都需要执行，如果不想每次<code>hexo d</code>之前都执行的话，可以将主题中的<code>themes/source/img/512.png</code>图片复制移动到<code>根目录``/source/img</code>中，然后将生成后的<code>/public/img/siteicon</code>文件夹复制到<code>根目录``/source/img</code>中，这样<code>根目录``/source/img</code>中就会一直有<code>siteicon</code>，以后执行<code>hexo g</code>时，也会将<code>siteicon</code>生成到<code>public</code>目录中。</li>
</ul></section><section><h4>hexo-swpp<a href="#hexo-swpp"><span>#</span></a></h4><p>主题版本大于 1.5.2 支持，这种加载办法为极其迅速，由 sw 控制其缓存，实现原理以及配置请查看以下三篇文章</p><p><a href="https://github.com/EmptyDreams/hexo-swpp#readme" target="_blank">hexo-swpp</a></p><p><a href="https://github.com/EmptyDreams/swpp-backends" target="_blank">swpp-backends</a></p><p><a href="https://kmar.top/posts/b70ec88f/" target="_blank">Swpp Backends 官方文档</a></p><p>配置方法：</p><ol>
<li>安装 hexo-swpp 插件和 swpp-backends，在博客根目录执行</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>hexo-swpp</span><span> </span><span>--save</span></div></div><div><div><div>2</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>swpp-backends</span><span> </span><span>--save</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>在<code>主题配置文件</code>中开启 pwa 选项。</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## PWA</span></div></div><div><div><div>2</div></div><div><span>## See https://github.com/JLHwung/hexo-offline</span></div></div><div><div><div>3</div></div><div><span>## ---------------</span></div></div><div><div><div>4</div></div><div><span>pwa</span><span>:</span></div></div><div><div><div>5</div></div><div><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>6</div></div><div><span>startup_image_enable</span><span>: </span><span>true</span></div></div><div><div><div>7</div></div><div><span>manifest</span><span>: </span><span>/manifest.json</span></div></div><div><div><div>8</div></div><div><span>theme_color</span><span>: </span><span>var(--anzhiyu-main)</span></div></div><div><div><div>9</div></div><div><span>mask_icon</span><span>: </span><span>/img/siteicon/apple-icon-180.png</span></div></div><div><div><div>10</div></div><div><span>apple_touch_icon</span><span>: </span><span>/img/siteicon/apple-icon-180.png</span></div></div><div><div><div>11</div></div><div><span>bookmark_icon</span><span>: </span><span>/img/siteicon/apple-icon-180.png</span></div></div><div><div><div>12</div></div><div><span>favicon_32_32</span><span>: </span><span>/img/siteicon/32.png</span></div></div><div><div><div>13</div></div><div><span>favicon_16_16</span><span>: </span><span>/img/siteicon/16.png</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>在 hexo 的配置文件中添加如下内容即可启用插件：</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>swpp</span><span>:</span></div></div><div><div><div>2</div></div><div><span>## 是否启用插件</span></div></div><div><div><div>3</div></div><div><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>## 是否在发布前自动执行脚本</span></div></div><div><div><div>5</div></div><div><span>## auto_exec: true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>在创建<code>source/</code>目录中创建<code>manifest.json</code>文件。</li>
</ol><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>"name"</span><span>: </span><span>"安知鱼`Blog"</span><span>,</span></div></div><div><div><div>3</div></div><div><span>"short_name"</span><span>: </span><span>"安知鱼"</span><span>,</span></div></div><div><div><div>4</div></div><div><span>"theme_color"</span><span>: </span><span>"#3b70fc"</span><span>,</span></div></div><div><div><div>5</div></div><div><span>"background_color"</span><span>: </span><span>"#3b70fc"</span><span>,</span></div></div><div><div><div>6</div></div><div><span>"display"</span><span>: </span><span>"fullscreen"</span><span>,</span></div></div><div><div><div>7</div></div><div><span>"scope"</span><span>: </span><span>"/"</span><span>,</span></div></div><div><div><div>8</div></div><div><span>"start_url"</span><span>: </span><span>"/"</span><span>,</span></div></div><div><div><div>9</div></div><div><span>"id"</span><span>: </span><span>"/"</span><span>,</span></div></div><div><div><div>10</div></div><div><span>"icons"</span><span>: [</span></div></div><div><div><div>11</div></div><div><span>{</span></div></div><div><div><div>12</div></div><div><span>"src"</span><span>: </span><span>"img/siteicon/manifest-icon-192.maskable.png"</span><span>,</span></div></div><div><div><div>13</div></div><div><span>"sizes"</span><span>: </span><span>"192x192"</span><span>,</span></div></div><div><div><div>14</div></div><div><span>"type"</span><span>: </span><span>"image/png"</span><span>,</span></div></div><div><div><div>15</div></div><div><span>"purpose"</span><span>: </span><span>"any"</span></div></div><div><div><div>16</div></div><div><span>},</span></div></div><div><div><div>17</div></div><div><span>{</span></div></div><div><div><div>18</div></div><div><span>"src"</span><span>: </span><span>"img/siteicon/manifest-icon-192.maskable.png"</span><span>,</span></div></div><div><div><div>19</div></div><div><span>"sizes"</span><span>: </span><span>"192x192"</span><span>,</span></div></div><div><div><div>20</div></div><div><span>"type"</span><span>: </span><span>"image/png"</span><span>,</span></div></div><div><div><div>21</div></div><div><span>"purpose"</span><span>: </span><span>"maskable"</span></div></div><div><div><div>22</div></div><div><span>},</span></div></div><div><div><div>23</div></div><div><span>{</span></div></div><div><div><div>24</div></div><div><span>"src"</span><span>: </span><span>"img/siteicon/manifest-icon-512.maskable.png"</span><span>,</span></div></div><div><div><div>25</div></div><div><span>"sizes"</span><span>: </span><span>"512x512"</span><span>,</span></div></div><div><div><div>26</div></div><div><span>"type"</span><span>: </span><span>"image/png"</span><span>,</span></div></div><div><div><div>27</div></div><div><span>"purpose"</span><span>: </span><span>"any"</span></div></div><div><div><div>28</div></div><div><span>},</span></div></div><div><div><div>29</div></div><div><span>{</span></div></div><div><div><div>30</div></div><div><span>"src"</span><span>: </span><span>"img/siteicon/manifest-icon-512.maskable.png"</span><span>,</span></div></div><div><div><div>31</div></div><div><span>"sizes"</span><span>: </span><span>"512x512"</span><span>,</span></div></div><div><div><div>32</div></div><div><span>"type"</span><span>: </span><span>"image/png"</span><span>,</span></div></div><div><div><div>33</div></div><div><span>"purpose"</span><span>: </span><span>"maskable"</span></div></div><div><div><div>34</div></div><div><span>}</span></div></div><div><div><div>35</div></div><div><span>],</span></div></div><div><div><div>36</div></div><div><span>"splash_pages"</span><span>: </span><span>null</span></div></div><div><div><div>37</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>你也可以通过 <a href="https://app-manifest.firebaseapp.com/" target="_blank">Web App Manifestopen</a> 快速创建<code>manifest.json</code>。（Web App Manifest 要求至少包含一个 512*512 像素的图标）</p><ol>
<li>
<p>可以通过<code>Chrome</code>插件<code>Lighthouse</code>检查 PWA 配置是否生效以及配置是否正确。 打开博客页面启动<code>Lighthouse</code>插件 (Lighthouse 插件要求至少包含一个 512*512 像素的图标) 关于 PWA（渐进式增强 Web 应用）的更多内容请参考 <a href="https://developers.google.com/web/tools/lighthouse/audits/address-bar" target="_blank">Google Tools for Web Developersopen</a></p>
</li>
<li>
<p>生成 pwa 启动图 安装<code>pwa-asset-generator</code></p>
</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>pwa-asset-generator</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>hexo 根目录执行<code>hexo g</code>然后执行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npx</span><span> </span><span>pwa-asset-generator</span><span> </span><span>./public/img/512.png</span><span> </span><span>./public/img/siteicon</span><span> </span><span>--padding</span><span> </span><span>"calc(50vh - 20%) calc(50vw - 40%)"</span><span> </span><span>-s</span><span> </span><span>false</span><span> </span><span>-h</span><span> </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这条命令会使用<code>themes/anzhiyu/source/img/512.png</code>这张图片来生成 siteicon 到目录<code>/public/img/siteicon</code>中，由于<code>hexo cl</code>会清除<code>/public</code>目录中的文件，所以每次<code>hexo d</code>之前都需要执行，如果不想每次<code>hexo d</code>之前都执行的话，可以将主题中的<code>themes/anzhiyu/source/img/512.png</code>图片复制移动到<code>根目录``/source/img</code>中，然后将生成后的<code>/public/img/siteicon</code>文件夹复制到<code>根目录``/source/img</code>中，这样<code>根目录``/source/img</code>中就会一直有<code>siteicon</code>，以后执行<code>hexo g</code>时，也会将<code>siteicon</code>生成到<code>public</code>目录中。</p><ol>
<li>在 hexo g 以后执行一次 hexo swpp 命令 如果你的网站使用了 CDN 且启用了 CDN 端缓存，请务必将 CDN 缓存时间调整至最大值，然后每次更新网页内容后手动刷新 CDN 缓存。 因为本插件的更新方案要求<code>update.json</code>更新时，其它所有需要更新的资源均已更新，否则客户端拉取时会误以为拉取到了最新的内容，从而导致部分资源“错过”更新。 简而言之，就是<code>update.json</code>必须与需要缓存的资源共享同样的 CDN 缓存周期，但是目前市面上我知道的 CDN 无法做到这一点，所以只能从下列选项中二选一</li>
</ol><ul>
<li>把所有资源的 CDN 缓存时间拉满，每次更新网站时刷新 CDN 缓存</li>
<li>CDN 不缓存所有需要在客户端缓存的资源</li>
</ul><p>Netlify 构建后自动刷新 CDN 缓存的教程见：<a href="https://kmar.top/posts/a427ed12/" target="_blank">《全自动博客部署方案》</a> 请务必注意 CDN 缓存的问题！！！ 默认主题将只缓存 404 和 index.css 如果你需要配置自己的缓存策略，请在博客根目录新建<code>sw-rules.js</code> 请注意 ⚠️ 定期或不定期检查 hexo swpp 是否存在更新，以及查看更新日志对配置做出最新的更改</p><div><div><div></div><div>Warning</div></div><div><p>主题默认内置了一份 sw-rules.js 规则，位于<code>themes/anzhiyu/sw-rules.js</code>可以开箱即用，如需自定义缓存规则可以复制该文件至 hexo 根目录然后修改根目录的 sw-rules.js。</p></div></div><ol>
<li>安知鱼主题适配 hexo-swpp3.2+，swpp-backends2.0+更多内容请参考 <a href="https://kmar.top/posts/b70ec88f/" target="_blank">Swpp Backends 官方文档</a><a href="https://github.com/EmptyDreams/hexo-swpp#readme" target="_blank">hexo-swpp</a><a href="https://github.com/EmptyDreams/swpp-backends" target="_blank">swpp-backends</a><a href="https://kmar.top/posts/bcfe8408/" target="_blank">解剖 SW 原理暨博主 SW 实现</a><a href="https://kmar.top/posts/73014407/" target="_blank">小白也能用的 SW 构建插件</a></li>
</ol></section></section><section><h3>Open Graph<a href="#open-graph"><span>#</span></a></h3><p>在 <code>head</code> 里增加一些 meta 资料，例如缩略图、标题、时间等等。当你分享网页到一些平台时，平台会读取 Open Graph 的内容，展示缩略图，标题等等信息。</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## Open graph meta tags</span></div></div><div><div><div>2</div></div><div><span>## https://developers.facebook.com/docs/sharing/webmasters/</span></div></div><div><div><div>3</div></div><div><span>Open_Graph_meta</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>  </span><span>option</span><span>:</span></div></div><div><div><div>6</div></div><div><span>    </span><span># twitter_card:</span></div></div><div><div><div>7</div></div><div><span>    </span><span># twitter_image:</span></div></div><div><div><div>8</div></div><div><span>    </span><span># twitter_id:</span></div></div><div><div><div>9</div></div><div><span>    </span><span># twitter_site:</span></div></div><div><div><div>10</div></div><div><span>    </span><span># google_plus:</span></div></div><div><div><div>11</div></div><div><span>    </span><span># fb_admins:</span></div></div><div><div><div>12</div></div><div><span>    </span><span># fb_app_id:</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>CSS 前缀<a href="#css-前缀"><span>#</span></a></h3><p>有些 CSS 并不是所有浏览器都支持，需要增加对应的前缀才会生效。</p><p>开启 <code>css_prefix</code> 后，会自动为一些 CSS 增加前缀。（会增加 20%的体积）</p><p>修改 <code>主题配置文件</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## Add the vendor prefixes to ensure compatibility</span></div></div><div><div><div>2</div></div><div><span>css_prefix</span><span>: </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Inject<a href="#inject"><span>#</span></a></h3><p>如想添加额外的 js/css/meta 等等东西，可以在 Inject 里添加，支持添加到 head(<code>&lt;/body&gt;</code>标签之前)和 bottom(<code>&lt;/html&gt;</code>标签之前)。</p><p>请注意：以标准的 html 格式添加内容</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>inject</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>head</span><span>:</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>- </span><span>&lt;link rel="stylesheet" href="/self.css"&gt;</span></div></div><div><div><div>4</div></div><div><span>  </span><span>bottom</span><span>:</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>- </span><span>&lt;script src="xxxx"&gt;&lt;/script&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>留意: 如果你的网站根目录不是’/‘,使用本地图片时，需加上你的根目录。</p><p>例如：网站是 <code>https://yoursite.com/blog,引用css/xx.css</code>，则设置为<code>&lt;link rel="stylesheet" href="/blog/css/xx.css"&gt;</code></p></section><section><h3>CDN<a href="#cdn"><span>#</span></a></h3><p>配置文件中最后一部分 CDN，里面是主题所引用到的文件，可自行配置 CDN。（非必要请勿修改，配置后请确认链接是否能访问）</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>## CDN</span></div></div><div><div><div>2</div></div><div><span>## Don't modify the following settings unless you know how they work</span></div></div><div><div><div>3</div></div><div><span>## 非必要请不要修改</span></div></div><div><div><div>4</div></div><div><span>CDN</span><span>:</span></div></div><div><div><div>5</div></div><div><span>  </span><span># The CDN provider of internal scripts (主题内部 js 的 cdn 配置)</span></div></div><div><div><div>6</div></div><div><span>  </span><span># option: local/elemecdn/jsdelivr/unpkg/cdnjs/custom</span></div></div><div><div><div>7</div></div><div><span>  </span><span># Dev version can only choose. ( dev版的主题只能设置为 local )</span></div></div><div><div><div>8</div></div><div><span>  </span><span>internal_provider</span><span>: </span><span>cbd</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>  </span><span># The CDN provider of third party scripts (第三方 js 的 cdn 配置)</span></div></div><div><div><div>11</div></div><div><span>  </span><span># option: elemecdn/jsdelivr/unpkg/cdnjs/custom</span></div></div><div><div><div>12</div></div><div><span>  </span><span>third_party_provider</span><span>: </span><span>cbd</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>  </span><span># Add version number to CDN, true or false</span></div></div><div><div><div>15</div></div><div><span>  </span><span>version</span><span>: </span><span>true</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>  </span><span># Custom format</span></div></div><div><div><div>18</div></div><div><span>  </span><span># For example: https://cdn.staticfile.org/${cdnjs_name}/${version}/${min_cdnjs_file}</span></div></div><div><div><div>19</div></div><div><span>  </span><span>custom_format</span><span>: </span><span># https://npm.elemecdn.com/${name}@latest/${file}</span></div></div><div><div><div>20</div></div><div>
</div></div><div><div><div>21</div></div><div><span>  </span><span>option</span><span>:</span></div></div><div><div><div>22</div></div><div><span>    </span><span># main_css:</span></div></div><div><div><div>23</div></div><div><span>    </span><span># main:</span></div></div><div><div><div>24</div></div><div><span>    </span><span># utils:</span></div></div><div><div><div>25</div></div><div><span>    </span><span># translate:</span></div></div><div><div><div>26</div></div><div><span>    </span><span># random_friends_post_js:</span></div></div><div><div><div>27</div></div><div><span>    </span><span># right_click_menu_js:</span></div></div><div><div><div>28</div></div><div><span>    </span><span># comment_barrage_js:</span></div></div><div><div><div>29</div></div><div><span>    </span><span># local_search:</span></div></div><div><div><div>30</div></div><div><span>    </span><span># algolia_js:</span></div></div><div><div><div>31</div></div><div><span>    </span><span># algolia_search:</span></div></div><div><div><div>32</div></div><div><span>    </span><span># instantsearch:</span></div></div><div><div><div>33</div></div><div><span>    </span><span># pjax:</span></div></div><div><div><div>34</div></div><div><span>    </span><span># blueimp_md5:</span></div></div><div><div><div>35</div></div><div><span>    </span><span># valine:</span></div></div><div><div><div>36</div></div><div><span>    </span><span># twikoo:</span></div></div><div><div><div>37</div></div><div><span>    </span><span># waline_js:</span></div></div><div><div><div>38</div></div><div><span>    </span><span># waline_css:</span></div></div><div><div><div>39</div></div><div><span>    </span><span># sharejs:</span></div></div><div><div><div>40</div></div><div><span>    </span><span># sharejs_css:</span></div></div><div><div><div>41</div></div><div><span>    </span><span># mathjax:</span></div></div><div><div><div>42</div></div><div><span>    </span><span># katex:</span></div></div><div><div><div>43</div></div><div><span>    </span><span># katex_copytex:</span></div></div><div><div><div>44</div></div><div><span>    </span><span># mermaid:</span></div></div><div><div><div>45</div></div><div><span>    </span><span># canvas_ribbon:</span></div></div><div><div><div>46</div></div><div><span>    </span><span># canvas_fluttering_ribbon:</span></div></div><div><div><div>47</div></div><div><span>    </span><span># canvas_nest:</span></div></div><div><div><div>48</div></div><div><span>    </span><span># lazyload:</span></div></div><div><div><div>49</div></div><div><span>    </span><span># instantpage:</span></div></div><div><div><div>50</div></div><div><span>    </span><span># typed:</span></div></div><div><div><div>51</div></div><div><span>    </span><span># pangu:</span></div></div><div><div><div>52</div></div><div><span>    </span><span># fancybox_css:</span></div></div><div><div><div>53</div></div><div><span>    </span><span># fancybox:</span></div></div><div><div><div>54</div></div><div><span>    </span><span># medium_zoom:</span></div></div><div><div><div>55</div></div><div><span>    </span><span># snackbar_css:</span></div></div><div><div><div>56</div></div><div><span>    </span><span># snackbar:</span></div></div><div><div><div>57</div></div><div><span>    </span><span># activate_power_mode:</span></div></div><div><div><div>58</div></div><div><span>    </span><span># fireworks:</span></div></div><div><div><div>59</div></div><div><span>    </span><span># click_heart:</span></div></div><div><div><div>60</div></div><div><span>    </span><span># ClickShowText:</span></div></div><div><div><div>61</div></div><div><span>    </span><span># fontawesome:</span></div></div><div><div><div>62</div></div><div><span>    </span><span># flickr_justified_gallery_js:</span></div></div><div><div><div>63</div></div><div><span>    </span><span># flickr_justified_gallery_css:</span></div></div><div><div><div>64</div></div><div><span>    </span><span># aplayer_css:</span></div></div><div><div><div>65</div></div><div><span>    </span><span># aplayer_js:</span></div></div><div><div><div>66</div></div><div><span>    </span><span># meting_js:</span></div></div><div><div><div>67</div></div><div><span>    </span><span># meting_api:</span></div></div><div><div><div>68</div></div><div><span>    </span><span># prismjs_js:</span></div></div><div><div><div>69</div></div><div><span>    </span><span># prismjs_lineNumber_js:</span></div></div><div><div><div>70</div></div><div><span>    </span><span># prismjs_autoloader:</span></div></div><div><div><div>71</div></div><div><span>    </span><span># artalk_js:</span></div></div><div><div><div>72</div></div><div><span>    </span><span># artalk_css:</span></div></div><div><div><div>73</div></div><div><span>    </span><span># pace_js:</span></div></div><div><div><div>74</div></div><div><span>    </span><span># pace_default_css:</span></div></div><div><div><div>75</div></div><div><span>    </span><span># countup_js:</span></div></div><div><div><div>76</div></div><div><span>    </span><span># gsap_js:</span></div></div><div><div><div>77</div></div><div><span>    </span><span># busuanzi:</span></div></div><div><div><div>78</div></div><div><span>    </span><span># rightmenu:</span></div></div><div><div><div>79</div></div><div><span>    </span><span># waterfall:</span></div></div><div><div><div>80</div></div><div><span>    </span><span># ali_iconfont_css:</span></div></div><div><div><div>81</div></div><div><span>    </span><span># accesskey_js:</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>

<table><thead><tr><th>参数</th><th>解释</th></tr></thead><tbody><tr><td>internal_provider</td><td>主题内部文件</td></tr><tr><td>可选 local/jsdelivr/unpkg/cdnjs/custom</td><td></td></tr><tr><td>lcoal 为本地加载，custom 为自定义格式，需配置 <code>custom_format</code></td><td></td></tr><tr><td><strong>注意</strong>: 如果使用的是 Dev 版，只能设置为 local</td><td></td></tr><tr><td>third_party_provider</td><td>第三方文件</td></tr><tr><td>可选 local/jsdelivr/unpkg/cdnjs/custom</td><td></td></tr><tr><td>lcoal 为本地加载，custom 为自定义格式，需配置 custom_format</td><td></td></tr><tr><td><strong>注意</strong>: 如果你选择 local 则需要自行将文件都下载至本地，并修改对应的选项，否则会报错。</td><td></td></tr><tr><td>version</td><td>true/false 为 cdn 加上指定版本号</td></tr><tr><td>custom_format</td><td>自定义格式</td></tr><tr><td>option</td><td>你可以在这里更换部分文件,会覆盖原有的配置</td></tr></tbody></table><section><h4>version<a href="#version"><span>#</span></a></h4><p>如需修改版本号，可修改<code>主题目录</code>的 ‘plugins.yml’ 中对应插件的 version</p><p>请确保你修改的版本号，你所使用的 cdn 有收录</p></section><section><h4>custom_format<a href="#custom_format"><span>#</span></a></h4><p>提供以下参数</p>

<table><thead><tr><th>参数</th><th>解释</th></tr></thead><tbody><tr><td>name</td><td>npm 上的包名</td></tr><tr><td>file</td><td>npm 上的文件路径</td></tr><tr><td>min_file</td><td>cdnjs 上的包名</td></tr><tr><td>cdnjs_file</td><td>cdnjs 上的文件路径</td></tr><tr><td>min_cdnjs_file</td><td>cdnjs 上的文件路径（压缩过的文件）</td></tr><tr><td>version</td><td>插件版本号</td></tr></tbody></table><p>部分可用的第三方 CDN 列表</p><blockquote><p>请确保你选择的 CDN 有收录主题使用的第三方插件</p></blockquote>

<table><thead><tr><th>提供商</th><th>格式</th><th>备注</th></tr></thead><tbody><tr><td><a href="https://www.staticfile.org/" target="_blank">Staticfile（七牛云）</a></td><td>[<a href="https://cdn.staticfile.org/" target="_blank">https://cdn.staticfile.org/</a><span><span>cdnjs_name/{cdnjs\_name}/</span><span><span><span></span><span><span>c</span><span>d</span><span>nj</span><span>s</span><span>_</span><span>nam</span><span>e</span></span><span>/</span></span></span></span>{version}/<span><span>min_cdnjs_file](https://cdn.staticfile.org/{min\_cdnjs\_file}](https://cdn.staticfile.org/</span><span><span><span></span><span><span>min</span><span>_</span><span>c</span><span>d</span><span>nj</span><span>s</span><span>_</span><span>f</span><span>i</span><span>l</span><span>e</span></span><span>]</span><span>(</span><span>h</span><span>ttp</span><span>s</span><span></span><span>:</span><span></span></span><span><span></span><span>//</span><span>c</span><span>d</span><span>n</span><span>.</span><span>s</span><span>t</span><span>a</span><span>t</span><span>i</span><span>c</span><span>f</span><span>i</span><span>l</span><span>e</span><span>.</span><span>or</span><span>g</span><span>/</span></span></span></span>%7Bcdnjs_name%7D/<span><span>%7Bversion%7D/</span><span></span></span>%7Bmin_cdnjs_file%7D)</td><td>同步 cdnjs</td></tr><tr><td><a href="https://www.bootcdn.cn/" target="_blank">BootCDN</a></td><td>[<a href="https://cdn.bootcdn.net/ajax/libs/" target="_blank">https://cdn.bootcdn.net/ajax/libs/</a><span><span>cdnjs_name/{cdnjs\_name}/</span><span><span><span></span><span><span>c</span><span>d</span><span>nj</span><span>s</span><span>_</span><span>nam</span><span>e</span></span><span>/</span></span></span></span>{version}/<span><span>min_cdnjs_file](https://cdn.bootcdn.net/ajax/libs/{min\_cdnjs\_file}](https://cdn.bootcdn.net/ajax/libs/</span><span><span><span></span><span><span>min</span><span>_</span><span>c</span><span>d</span><span>nj</span><span>s</span><span>_</span><span>f</span><span>i</span><span>l</span><span>e</span></span><span>]</span><span>(</span><span>h</span><span>ttp</span><span>s</span><span></span><span>:</span><span></span></span><span><span></span><span>//</span><span>c</span><span>d</span><span>n</span><span>.</span><span>b</span><span>oo</span><span>t</span><span>c</span><span>d</span><span>n</span><span>.</span><span>n</span><span>e</span><span>t</span><span>/</span><span>aj</span><span>a</span><span>x</span><span>/</span><span>l</span><span>ib</span><span>s</span><span>/</span></span></span></span>%7Bcdnjs_name%7D/<span><span>%7Bversion%7D/</span><span></span></span>%7Bmin_cdnjs_file%7D)</td><td>同步 cdnjs</td></tr><tr><td><a href="https://cdn.baomitu.com/" target="_blank">Baomitu（360）</a></td><td>最新版本： <a href="https://lib.baomitu.com/$%7Bcdnjs_name%7D/latest/$%7Bmin_cdnjs_file%7D" target="_blank">https://lib.baomitu.com/<span><span>cdnjs_name/latest/{cdnjs\_name}/latest/</span><span><span><span></span><span><span>c</span><span>d</span><span>nj</span><span>s</span><span>_</span><span>nam</span><span>e</span></span><span>/</span><span>l</span><span>a</span><span>t</span><span>es</span><span>t</span><span>/</span></span></span></span>{min_cdnjs_file}</a></td><td></td></tr><tr><td>指定版本： [<a href="https://lib.baomitu.com/" target="_blank">https://lib.baomitu.com/</a><span><span>cdnjs_name/{cdnjs\_name}/</span><span><span><span></span><span><span>c</span><span>d</span><span>nj</span><span>s</span><span>_</span><span>nam</span><span>e</span></span><span>/</span></span></span></span>{version}/<span><span>min_cdnjs_file](https://lib.baomitu.com/{min\_cdnjs\_file}](https://lib.baomitu.com/</span><span><span><span></span><span><span>min</span><span>_</span><span>c</span><span>d</span><span>nj</span><span>s</span><span>_</span><span>f</span><span>i</span><span>l</span><span>e</span></span><span>]</span><span>(</span><span>h</span><span>ttp</span><span>s</span><span></span><span>:</span><span></span></span><span><span></span><span>//</span><span>l</span><span>ib</span><span>.</span><span>ba</span><span>o</span><span>mi</span><span>t</span><span>u</span><span>.</span><span>co</span><span>m</span><span>/</span></span></span></span>%7Bcdnjs_name%7D/<span><span>%7Bversion%7D/</span><span></span></span>%7Bmin_cdnjs_file%7D)</td><td>同步 cdnjs</td><td></td></tr><tr><td>Elemecdn</td><td>最新版本： <a href="https://npm.elemecdn.com/$%7Bname%7D@latest/$%7Bfile%7D" target="_blank">https://npm.elemecdn.com/<span><span>name@latest/{name}@latest/</span><span><span><span></span><span><span>nam</span><span>e</span></span><span>@</span><span>l</span><span>a</span><span>t</span><span>es</span><span>t</span><span>/</span></span></span></span>{file}</a></td><td></td></tr><tr><td>指定版本： [<a href="https://npm.elemecdn.com/" target="_blank">https://npm.elemecdn.com/</a><span><span>name@{name}@</span><span><span><span></span><span><span>nam</span><span>e</span></span><span>@</span></span></span></span>{version}/<span><span>file](https://npm.elemecdn.com/{file}](https://npm.elemecdn.com/</span><span><span><span></span><span><span>f</span><span>i</span><span>l</span><span>e</span></span><span>]</span><span>(</span><span>h</span><span>ttp</span><span>s</span><span></span><span>:</span><span></span></span><span><span></span><span>//</span><span>n</span><span>p</span><span>m</span><span>.</span><span>e</span><span>l</span><span>e</span><span>m</span><span>ec</span><span>d</span><span>n</span><span>.</span><span>co</span><span>m</span><span>/</span></span></span></span>%7Bname%7D@<span><span>%7Bversion%7D/</span><span></span></span>%7Bfile%7D)</td><td>同步 npm</td><td></td></tr></tbody></table></section></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/9389626e/</id>
      <title type="text">相册页面配置</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/9389626e/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>相册页面配置<a href="#相册页面配置"><span>#</span></a></h2><ol>
<li>
<p>前往你的 Hexo 博客的根目录</p>
</li>
<li>
<p>在 Hexo 博客根目录 <code>[blog]</code>下打开终端，输入</p>
</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>hexo</span><span> </span><span>new</span><span> </span><span>page</span><span> </span><span>album</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>
<p>你会找到 <code>source/album/index.md</code> 这个文件</p>
</li>
<li>
<p>修改这个文件： 记得添加 <code>type: "album"</code></p>
</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>相册集</span></div></div><div><div><div>3</div></div><div><span>date</span><span>: </span><span>2022-10-23 15:57:51</span></div></div><div><div><div>4</div></div><div><span>aside</span><span>: </span><span>false</span></div></div><div><div><div>5</div></div><div><span>top_img</span><span>: </span><span>false</span></div></div><div><div><div>6</div></div><div><span>type</span><span>: </span><span>"album"</span></div></div><div><div><div>7</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>主题配置文件中开启<code>menu</code>中我的和相册集的注释，注意缩进！！！</li>
</ol><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>menu</span><span>:</span></div></div><div><div><div>2</div></div><div><span># 文章:</span></div></div><div><div><div>3</div></div><div><span>#   隧道: /archives/ || icon-box-archive</span></div></div><div><div><div>4</div></div><div><span>#   分类: /categories/ || icon-shapes</span></div></div><div><div><div>5</div></div><div><span>#   标签: /tags/ || icon-tags</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>友链</span><span>:</span></div></div><div><div><div>8</div></div><div><span>友人帐</span><span>: </span><span>/link/ || icon-link</span></div></div><div><div><div>9</div></div><div><span>#   朋友圈: /fcircle/ || icon-artstation</span></div></div><div><div><div>10</div></div><div><span>#   留言板: /comments/ || icon-envelope</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>我的</span><span>:</span></div></div><div><div><div>13</div></div><div><span>音乐馆</span><span>: </span><span>/music/ || icon-music</span></div></div><div><div><div>14</div></div><div><span>#   追番页: /bangumis/ || icon-bilibili1</span></div></div><div><div><div>15</div></div><div><span>相册集</span><span>: </span><span>/album/ || icon-images</span></div></div><div><div><div>16</div></div><div><span>#   小空调: /air-conditioner/ || icon-fan</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>关于</span><span>:</span></div></div><div><div><div>19</div></div><div><span>#   关于本人: /about/ || icon-zhifeiji</span></div></div><div><div><div>20</div></div><div><span>闲言碎语</span><span>: </span><span>/essay/ || icon-lightbulb</span></div></div><div><div><div>21</div></div><div><span>#   随便逛逛: javascript:toRandomPost() || icon-shoe-prints1</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>新建文件<code>[blog]\source\_data\album.yml</code>,没有<code>_data</code>文件夹的话也请自己新建。打开<code>[blog]\source\_data\album.yml</code>，输入：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- </span><span>class_name</span><span>: </span><span>世界各地夕阳与风景</span></div></div><div><div><div>2</div></div><div><span>    </span><span>path_name</span><span>: </span><span>/wordScenery</span></div></div><div><div><div>3</div></div><div><span>    </span><span>type</span><span>: </span><span>2</span></div></div><div><div><div>4</div></div><div><span>    </span><span>description</span><span>: </span><span>因为到不了世界各地，所以请网友们发来了各地的夕阳与风景🌇。</span></div></div><div><div><div>5</div></div><div><span>    </span><span>cover</span><span>: </span><span>https://upload-bbs.miyoushe.com/upload/2025/06/13/125766904/2cf2b6aea07bba089d0d17c4fea72d1b_5366629137934368264.png</span></div></div><div><div><div>6</div></div><div><span>    </span><span>top_background</span><span>: </span><span>https://bu.dusays.com/2023/06/30/649e546ada7dd.webp</span></div></div><div><div><div>7</div></div><div><span>    </span><span>rowHeight</span><span>: </span><span>220</span></div></div><div><div><div>8</div></div><div><span>    </span><span>limit</span><span>: </span><span>10</span></div></div><div><div><div>9</div></div><div><span>    </span><span>lazyload</span><span>: </span><span>true</span></div></div><div><div><div>10</div></div><div><span>    </span><span>btnLazyload</span><span>: </span><span>false</span></div></div><div><div><div>11</div></div><div><span>    </span><span>url</span><span>: </span><span>false</span></div></div><div><div><div>12</div></div><div><span>    </span><span>top_link</span><span>: </span><span>/album</span></div></div><div><div><div>13</div></div><div><span>    </span><span>top_btn_text</span><span>: </span><span>返回</span></div></div><div><div><div>14</div></div><div><span>    </span><span>album_list</span><span>:</span></div></div><div><div><div>15</div></div><div><span><span>        </span></span><span>- </span><span>date</span><span>: </span><span>2022/10/26 01:00:00</span></div></div><div><div><div>16</div></div><div><span>        </span><span>content</span><span>: </span><span>湘潭的一角。</span></div></div><div><div><div>17</div></div><div><span>        </span><span>address</span><span>: </span><span>湖南湘潭</span></div></div><div><div><div>18</div></div><div><span>        </span><span>from</span><span>: </span><span>再吃一口就减肥</span></div></div><div><div><div>19</div></div><div><span>        </span><span>image</span><span>:</span></div></div><div><div><div>20</div></div><div><span><span>            </span></span><span>- </span><span>https://bu.dusays.com/2023/04/09/64329399db122.webp</span></div></div><div><div><div>21</div></div><div><span><span>        </span></span><span>- </span><span>date</span><span>: </span><span>2022-10-25</span></div></div><div><div><div>22</div></div><div><span>        </span><span>content</span><span>: </span><span>洛阳暴雨后的天空。</span></div></div><div><div><div>23</div></div><div><span>        </span><span>address</span><span>: </span><span>河南洛阳</span></div></div><div><div><div>24</div></div><div><span>        </span><span>from</span><span>: </span><span>紫菜卷</span></div></div><div><div><div>25</div></div><div><span>        </span><span>image</span><span>:</span></div></div><div><div><div>26</div></div><div><span><span>            </span></span><span>- </span><span>https://bu.dusays.com/2023/04/09/64329399db122.webp</span></div></div><div><div><div>27</div></div><div><span><span>            </span></span><span>- </span><span>https://bu.dusays.com/2023/04/09/64329399db2e1.webp</span></div></div><div><div><div>28</div></div><div>
</div></div><div><div><div>29</div></div><div><span>- </span><span>class_name</span><span>: </span><span>我的日常</span></div></div><div><div><div>30</div></div><div><span>    </span><span>path_name</span><span>: </span><span>/dailyPhoto</span></div></div><div><div><div>31</div></div><div><span>    </span><span>type</span><span>: </span><span>1</span></div></div><div><div><div>32</div></div><div><span>    </span><span>description</span><span>: </span><span>这里存放的是有关我自己的一些沙雕生活与有趣的事情。</span></div></div><div><div><div>33</div></div><div><span>    </span><span>top_link</span><span>: </span><span>/album</span></div></div><div><div><div>34</div></div><div><span>    </span><span>top_btn_text</span><span>: </span><span>返回</span></div></div><div><div><div>35</div></div><div><span>    </span><span>top_background</span><span>: </span><span>https://bu.dusays.com/2023/04/09/64329399cea5a.webp</span></div></div><div><div><div>36</div></div><div><span>    </span><span>cover</span><span>: </span><span>https://bu.dusays.com/2023/04/09/64329399cea5a.webp</span></div></div><div><div><div>37</div></div><div><span>    </span><span>album_list</span><span>:</span></div></div><div><div><div>38</div></div><div><span><span>        </span></span><span>- </span><span>date</span><span>: </span><span>2022-10-24</span></div></div><div><div><div>39</div></div><div><span>        </span><span>content</span><span>: </span><span>老妹的画</span></div></div><div><div><div>40</div></div><div><span>        </span><span>image</span><span>:</span></div></div><div><div><div>41</div></div><div><span><span>            </span></span><span>- </span><span>https://bu.dusays.com/2023/04/09/643293997b92b.jpeg</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>

<table><thead><tr><th>参数</th><th>备选值/类型</th><th>解释</th></tr></thead><tbody><tr><td>class_name</td><td>string</td><td>【必须】页面类</td></tr><tr><td>path_name</td><td>url</td><td>【必须】当前相册路径</td></tr><tr><td>type</td><td>number</td><td>【必须】当前相册页面样式类型</td></tr><tr><td>description</td><td>string</td><td>【必须】当前相册描述</td></tr><tr><td>cover</td><td>url</td><td>【必须】当前相册 cover 图片</td></tr><tr><td>rowHeight</td><td>number</td><td>【可选】仅当 type 为 2 时有效，当前相册 rowHeight</td></tr><tr><td>limit</td><td>number</td><td>【可选】仅当 type 为 2 时有效，当前相册 一次懒加载的数量</td></tr><tr><td>lazyload</td><td>boolean</td><td>【可选】仅当 type 为 2 时有效，当前相册 lazyload 是否开启懒加载，默认懒加载为滚动懒加载，type 为 1 时懒加载不可关闭。</td></tr><tr><td>btnLazyload</td><td>boolean</td><td>【可选】仅当 type 为 2 且 lazyload 开启 时有效，当前相册 lazyload 懒加载的方式，默认为滚动懒加载，开启本选项后为按钮点击懒加载。</td></tr><tr><td>album_list</td><td>list</td><td>【必须】当前相册内图片列表</td></tr><tr><td>url</td><td>url</td><td>【可选】仅当 type 为 2 时有效，可以加载远程的 json 数据。</td></tr><tr><td>album_list.date</td><td>date</td><td>【必须】当前图片创建时间</td></tr><tr><td>album_list.content</td><td>string</td><td>【必须】当前图片描述内容</td></tr><tr><td>album_list.image</td><td>list</td><td>【必须】当前图片集，可以多张</td></tr><tr><td>album_list.from</td><td>string</td><td>【可选】当前图片的创建人，未填写则不显示</td></tr><tr><td>album_list.address</td><td>string</td><td>【必须】当前图片地址</td></tr></tbody></table><div><div><div></div><div>Warning</div></div><div><p>注意示例数据中的图片不保证可用性。</p></div></div><p>由于相册页面需要很多的 page，所以在写数据的时候自行写入路径<code>path_name</code>，示例数据中有两个<code>path_name</code>，所以需要再创建两个页面</p><p>注意新建的页面必须与<code>path_name</code>一致。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>hexo</span><span> </span><span>new</span><span> </span><span>page</span><span> </span><span>dailyPhoto</span></div></div><div><div><div>2</div></div><div><span>hexo</span><span> </span><span>new</span><span> </span><span>page</span><span> </span><span>wordScenery</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>你会找到 <code>source/dailyPhoto/index.md</code> 和<code>source/wordScenery/index.md</code>两个文件，这两个为相册集详情页</p><p>然后内容为以下内容, 需在详情页加上<code>type: "album_detail"</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>日常生活</span></div></div><div><div><div>3</div></div><div><span>date</span><span>: </span><span>2022-10-23 15:57:51</span></div></div><div><div><div>4</div></div><div><span>aside</span><span>: </span><span>false</span></div></div><div><div><div>5</div></div><div><span>top_img</span><span>: </span><span>false</span></div></div><div><div><div>6</div></div><div><span>type</span><span>: </span><span>"album_detail"</span></div></div><div><div><div>7</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>世界各地风景</span></div></div><div><div><div>3</div></div><div><span>date</span><span>: </span><span>2022-10-23 15:57:51</span></div></div><div><div><div>4</div></div><div><span>aside</span><span>: </span><span>false</span></div></div><div><div><div>5</div></div><div><span>top_img</span><span>: </span><span>false</span></div></div><div><div><div>6</div></div><div><span>type</span><span>: </span><span>"album_detail"</span></div></div><div><div><div>7</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><code>远程加载json示例数据</code></p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>{</span></div></div><div><div><div>3</div></div><div><span>    </span><span>"url"</span><span>: </span><span>"https://cdn.jsdelivr.net/gh/jerryc127/CDN/img/IMG_0556.jpg"</span><span>,</span></div></div><div><div><div>4</div></div><div><span>    </span><span>"alt"</span><span>: </span><span>"IMG_0556.jpg"</span><span>,</span></div></div><div><div><div>5</div></div><div><span>    </span><span>"title"</span><span>: </span><span>"这是title"</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>{</span></div></div><div><div><div>8</div></div><div><span>    </span><span>"url"</span><span>: </span><span>"https://cdn.jsdelivr.net/gh/jerryc127/CDN/img/IMG_0472.jpg"</span><span>,</span></div></div><div><div><div>9</div></div><div><span>    </span><span>"alt"</span><span>: </span><span>"IMG_0472.jpg"</span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>11</div></div><div><span><span>  </span></span><span>{</span></div></div><div><div><div>12</div></div><div><span>    </span><span>"url"</span><span>: </span><span>"https://cdn.jsdelivr.net/gh/jerryc127/CDN/img/IMG_0453.jpg"</span><span>,</span></div></div><div><div><div>13</div></div><div><span>    </span><span>"alt"</span><span>: </span><span>""</span></div></div><div><div><div>14</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>15</div></div><div><span><span>  </span></span><span>{</span></div></div><div><div><div>16</div></div><div><span>    </span><span>"url"</span><span>: </span><span>"https://cdn.jsdelivr.net/gh/jerryc127/CDN/img/IMG_0931.jpg"</span><span>,</span></div></div><div><div><div>17</div></div><div><span>    </span><span>"alt"</span><span>: </span><span>""</span></div></div><div><div><div>18</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>19</div></div><div><span>]</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/12/4e742d18dae9490d9cccfc07ac51a79a64326458a0f01.png!blogimg" alt="相册页" /><figcaption>相册页</figcaption></figure><p></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/12/471edd72b97e4af19068398e913f9a0c643f4351c8245.webp!blogimg" alt="相册页" /><figcaption>相册页</figcaption></figure><p></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/12/1f42752c85ee4b28bccd6b0d956092d1643f42162d2f4.webp!blogimg" alt="相册页" /><figcaption>相册页</figcaption></figure><p></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/95bf0b14/</id>
      <title type="text">分类页配置</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/95bf0b14/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>分类页配置<a href="#分类页配置"><span>#</span></a></h2><ol>
<li>
<p>前往你的 Hexo 博客的根目录</p>
</li>
<li>
<p>在 Hexo 博客根目录 <code>[blog]</code>下打开终端，输入</p>
</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>hexo</span><span> </span><span>new</span><span> </span><span>page</span><span> </span><span>categories</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>
<p>你会找到 <code>source/categories/index.md</code> 这个文件</p>
</li>
<li>
<p>修改这个文件： 记得添加 <code>type: "categories"</code></p>
</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>分类</span></div></div><div><div><div>3</div></div><div><span>date</span><span>: </span><span>2022-02-23 17:56:00</span></div></div><div><div><div>4</div></div><div><span>aside</span><span>: </span><span>false</span></div></div><div><div><div>5</div></div><div><span>top_img</span><span>: </span><span>false</span></div></div><div><div><div>6</div></div><div><span>type</span><span>: </span><span>"categories"</span></div></div><div><div><div>7</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/b7b7a53b/</id>
      <title type="text">朋友圈页面配置</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/b7b7a53b/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>朋友圈页面配置<a href="#朋友圈页面配置"><span>#</span></a></h2><p>在 Hexo 博客根目录 <code>[blog]</code>下打开终端，输入</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>hexo</span><span> </span><span>new</span><span> </span><span>page</span><span> </span><span>fcircle</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>打开<code>[blog]\source\fcircle\index.md</code>,添加一行<code>type: 'fcircle'</code>:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>朋友圈</span></div></div><div><div><div>3</div></div><div><span>date</span><span>: </span><span>2022-11-21 17:06:17</span></div></div><div><div><div>4</div></div><div><span>comments</span><span>: </span><span>false</span></div></div><div><div><div>5</div></div><div><span>aside</span><span>: </span><span>false</span></div></div><div><div><div>6</div></div><div><span>top_img</span><span>: </span><span>false</span></div></div><div><div><div>7</div></div><div><span>type</span><span>: </span><span>"fcircle"</span></div></div><div><div><div>8</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>主题配置文件中开启<code>menu</code>中友链和朋友圈的注释，导航栏朋友圈，注意缩进！！！</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>menu</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span># 文章:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>#   隧道: /archives/ || icon-box-archive</span></div></div><div><div><div>4</div></div><div><span>  </span><span>#   分类: /categories/ || icon-shapes</span></div></div><div><div><div>5</div></div><div><span>  </span><span>#   标签: /tags/ || icon-tags</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>  </span><span>友链</span><span>:</span></div></div><div><div><div>8</div></div><div><span>    </span><span>#   友人帐: /link/ || icon-link</span></div></div><div><div><div>9</div></div><div><span>    </span><span>朋友圈</span><span>: </span><span>/fcircle/ || icon-artstation</span></div></div><div><div><div>10</div></div><div><span>    </span><span>#   留言板: /comments/ || icon-envelope</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>  </span><span># 我的:</span></div></div><div><div><div>13</div></div><div><span>  </span><span>#   音乐馆: /music/ || icon-music</span></div></div><div><div><div>14</div></div><div><span>  </span><span>#   追番页: /bangumis/ || icon-bilibili1</span></div></div><div><div><div>15</div></div><div><span>  </span><span>#   相册集: /album/ || icon-images</span></div></div><div><div><div>16</div></div><div><span>  </span><span>#   小空调: /air-conditioner/ || icon-fan</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>  </span><span>关于</span><span>:</span></div></div><div><div><div>19</div></div><div><span>    </span><span>#   关于本人: /about/ || icon-zhifeiji</span></div></div><div><div><div>20</div></div><div><span>    </span><span>闲言碎语</span><span>: </span><span>/essay/ || icon-lightbulb</span></div></div><div><div><div>21</div></div><div><span>    </span><span>#   随便逛逛: javascript:toRandomPost() || icon-shoe-prints1</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>主题配置文件中开启<code>friends_vue.enable</code>，自行设置 朋友圈后端地址 和 顶部模块背景，注意缩进！！！</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 朋友圈配置</span></div></div><div><div><div>2</div></div><div><span>friends_vue</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>false</span></div></div><div><div><div>4</div></div><div><span>  </span><span>vue_js</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-theme-static@1.1.2/friends/index.f9a2b8d2.js</span></div></div><div><div><div>5</div></div><div><span>  </span><span>apiurl</span><span>: </span><span># 朋友圈后端地址</span></div></div><div><div><div>6</div></div><div><span>  </span><span>top_background</span><span>:</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<table><thead><tr><th>参数</th><th>备选值/类型</th><th>解释</th></tr></thead><tbody><tr><td>enable</td><td>boolean</td><td>【必须】是否启用</td></tr><tr><td>vue_js</td><td>url</td><td>【必须】朋友圈前端构建后的 url</td></tr><tr><td>apiurl</td><td>string</td><td>【必须】朋友圈后端 url</td></tr><tr><td>top_background</td><td>url</td><td>【可选】朋友圈顶部背景图</td></tr></tbody></table><p>以下是本站配置</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>friends_vue</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>3</div></div><div><span>  </span><span>vue_js</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-theme-static@1.1.2/friends/index.f9a2b8d2.js</span></div></div><div><div><div>4</div></div><div><span>  </span><span>apiurl</span><span>: </span><span>https://friends.anheyu.com/</span><span> </span><span># 朋友圈后端地址</span></div></div><div><div><div>5</div></div><div><span>  </span><span>top_background</span><span>: </span><span>https://img02.anheyu.com/adminuploads/1/2022/08/21/630249e2df20f.jpg</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>其中<code>vue_js</code>参数，可以将<code>https://npm.elemecdn.com/anzhiyu-theme-static@1.1.2/friends/index.f9a2b8d2.js</code>下载下来后将其中的 <code>friends.anheyu.com</code>替换为您的后端 url 然后上传至您的存储端以url的形式使用。</p><p>原项目地址：<a href="https://github.com/anzhiyu-c/hexo-circle-of-friends-front/tree/anzhiyu" target="_blank">hexo-circle-of-friends-front</a></p><p>第二种办法也可以自行下载项目后，修改代码中的 url 变量路径<code>friends.anheyu.com</code>为你自己的，然后执行<code>npm run build</code>构建后将dist文件夹中的js上传至您的存储端使用</p><div><div><div></div><div>Tip</div></div><div><p>注意朋友圈后端爬取需使用<code>common2</code>，否则无法爬取到您的友链数据。</p></div></div><p>主题配置文件中开启<code>menu</code>中友链和朋友圈的注释，注意缩进！！！</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>menu</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span># 文章:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>#   隧道: /archives/ || icon-box-archive</span></div></div><div><div><div>4</div></div><div><span>  </span><span>#   分类: /categories/ || icon-shapes</span></div></div><div><div><div>5</div></div><div><span>  </span><span>#   标签: /tags/ || icon-tags</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>  </span><span>友链</span><span>:</span></div></div><div><div><div>8</div></div><div><span>    </span><span>#  友人帐: /link/ || icon-link</span></div></div><div><div><div>9</div></div><div><span>    </span><span>朋友圈</span><span>: </span><span>/fcircle/ || icon-artstation</span></div></div><div><div><div>10</div></div><div><span>  </span><span>#  留言板: /comments/ || icon-envelope</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>  </span><span>我的</span><span>:</span></div></div><div><div><div>13</div></div><div><span>    </span><span>音乐馆</span><span>: </span><span>/music/ || icon-music</span></div></div><div><div><div>14</div></div><div><span>  </span><span>#   追番页: /bangumis/ || icon-bilibili1</span></div></div><div><div><div>15</div></div><div><span>  </span><span>#   相册集: /album/ || icon-images</span></div></div><div><div><div>16</div></div><div><span>  </span><span>#   小空调: /air-conditioner/ || icon-fan</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>  </span><span>关于</span><span>:</span></div></div><div><div><div>19</div></div><div><span>    </span><span>#   关于本人: /about/ || icon-zhifeiji</span></div></div><div><div><div>20</div></div><div><span>    </span><span>闲言碎语</span><span>: </span><span>/essay/ || icon-lightbulb</span></div></div><div><div><div>21</div></div><div><span>    </span><span>#   随便逛逛: javascript:toRandomPost() || icon-shoe-prints1</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/12/50bd686132ed4709be0bd6925688cd1b64326468190c2.png!blogimg" alt="朋友圈页" /><figcaption>朋友圈页</figcaption></figure><p></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/c277f881/</id>
      <title type="text">关于页面配置</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/c277f881/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>关于页面配置<a href="#关于页面配置"><span>#</span></a></h2><ol>
<li>
<p>前往你的 Hexo 博客的根目录</p>
</li>
<li>
<p>在 Hexo 博客根目录 <code>[blog]</code>下打开终端，输入</p>
</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>hexo</span><span> </span><span>new</span><span> </span><span>page</span><span> </span><span>about</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>
<p>你会找到 <code>source/about/index.md</code> 这个文件</p>
</li>
<li>
<p>修改这个文件： 记得添加 <code>type: "about"</code></p>
</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>关于</span></div></div><div><div><div>3</div></div><div><span>date</span><span>: </span><span>2021-03-30 15:57:51</span></div></div><div><div><div>4</div></div><div><span>aside</span><span>: </span><span>false</span></div></div><div><div><div>5</div></div><div><span>top_img</span><span>: </span><span>false</span></div></div><div><div><div>6</div></div><div><span>background</span><span>: </span><span>"#f8f9fe"</span></div></div><div><div><div>7</div></div><div><span>comments</span><span>: </span><span>false</span></div></div><div><div><div>8</div></div><div><span>type</span><span>: </span><span>"about"</span></div></div><div><div><div>9</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>主题配置文件中开启<code>menu</code>中关于和关于本人的注释，注意缩进！！！</li>
</ol><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>menu</span><span>:</span></div></div><div><div><div>2</div></div><div><span># 文章:</span></div></div><div><div><div>3</div></div><div><span>#   隧道: /archives/ || icon-box-archive</span></div></div><div><div><div>4</div></div><div><span>#   分类: /categories/ || icon-shapes</span></div></div><div><div><div>5</div></div><div><span>#   标签: /tags/ || icon-tags</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>友链</span><span>:</span></div></div><div><div><div>8</div></div><div><span>友人帐</span><span>: </span><span>/link/ || icon-link</span></div></div><div><div><div>9</div></div><div><span>#   朋友圈: /fcircle/ || icon-artstation</span></div></div><div><div><div>10</div></div><div><span>#   留言板: /comments/ || icon-envelope</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>我的</span><span>:</span></div></div><div><div><div>13</div></div><div><span>音乐馆</span><span>: </span><span>/music/ || icon-music</span></div></div><div><div><div>14</div></div><div><span>#   追番页: /bangumis/ || icon-bilibili1</span></div></div><div><div><div>15</div></div><div><span>#   相册集: /album/ || icon-images</span></div></div><div><div><div>16</div></div><div><span>#   小空调: /air-conditioner/ || icon-fan</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>关于</span><span>:</span></div></div><div><div><div>19</div></div><div><span>关于本人</span><span>: </span><span>/about/ || icon-zhifeiji</span></div></div><div><div><div>20</div></div><div><span>闲言碎语</span><span>: </span><span>/essay/ || icon-lightbulb</span></div></div><div><div><div>21</div></div><div><span>#   随便逛逛: javascript:toRandomPost() || icon-shoe-prints1</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>新建<code>source/_data/about.yml</code>，输入以下内容</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>- </span><span>class_name</span><span>: </span><span>关于页</span></div></div><div><div><div>2</div></div><div><span>  </span><span>subtitle</span><span>: </span><span>生活明朗，万物可爱✨</span></div></div><div><div><div>3</div></div><div><span>  </span><span>avatarImg</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog-static@1.0.0/img/avatar.webp</span></div></div><div><div><div>4</div></div><div><span>  </span><span>avatarSkills</span><span>:</span></div></div><div><div><div>5</div></div><div><span>    </span><span>left</span><span>:</span></div></div><div><div><div>6</div></div><div><span><span>      </span></span><span>- </span><span>🤖️ 数码科技爱好者</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>🔍 分享与热心帮助</span></div></div><div><div><div>8</div></div><div><span><span>      </span></span><span>- </span><span>🏠 智能家居小能手</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>- </span><span>🔨 设计开发一条龙</span></div></div><div><div><div>10</div></div><div><span>    </span><span>right</span><span>:</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>- </span><span>专修交互与设计 🤝</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>- </span><span>脚踏实地行动派 🏃</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span>- </span><span>团队小组发动机 🧱</span></div></div><div><div><div>14</div></div><div><span><span>      </span></span><span>- </span><span>壮汉人狠话不多 💢</span></div></div><div><div><div>15</div></div><div><span>  </span><span>name</span><span>: </span><span>陈志伟</span></div></div><div><div><div>16</div></div><div><span>  </span><span>description</span><span>: </span><span>是一名 前端工程师、学生、独立开发者、博主</span></div></div><div><div><div>17</div></div><div><span>  </span><span>aboutsiteTips</span><span>:</span></div></div><div><div><div>18</div></div><div><span>    </span><span>tips</span><span>: </span><span>追求</span></div></div><div><div><div>19</div></div><div><span>    </span><span>title1</span><span>: </span><span>源于</span></div></div><div><div><div>20</div></div><div><span>    </span><span>title2</span><span>: </span><span>热爱而去 感受</span></div></div><div><div><div>21</div></div><div><span>    </span><span>word</span><span>:</span></div></div><div><div><div>22</div></div><div><span><span>      </span></span><span>- </span><span>学习</span></div></div><div><div><div>23</div></div><div><span><span>      </span></span><span>- </span><span>生活</span></div></div><div><div><div>24</div></div><div><span><span>      </span></span><span>- </span><span>程序</span></div></div><div><div><div>25</div></div><div><span><span>      </span></span><span>- </span><span>体验</span></div></div><div><div><div>26</div></div><div><span>  </span><span>helloAbout</span><span>: </span><span>Hello there!</span></div></div><div><div><div>27</div></div><div><span>  </span><span>skillsTips</span><span>:</span></div></div><div><div><div>28</div></div><div><span>    </span><span>tips</span><span>: </span><span>技能</span></div></div><div><div><div>29</div></div><div><span>    </span><span>title</span><span>: </span><span>开启创造力</span></div></div><div><div><div>30</div></div><div><span>  </span><span>careers</span><span>:</span></div></div><div><div><div>31</div></div><div><span>    </span><span>tips</span><span>: </span><span>生涯</span></div></div><div><div><div>32</div></div><div><span>    </span><span>title</span><span>: </span><span>无限进步</span></div></div><div><div><div>33</div></div><div><span>    </span><span>list</span><span>:</span></div></div><div><div><div>34</div></div><div><span><span>      </span></span><span>- </span><span>desc</span><span>: </span><span>EDU,软件工程专业</span></div></div><div><div><div>35</div></div><div><span>        </span><span>color</span><span>: </span><span>"#357ef5"</span></div></div><div><div><div>36</div></div><div><span><span>      </span></span><span>- </span><span>desc</span><span>: </span><span>EDU,软件工程专业</span></div></div><div><div><div>37</div></div><div><span>        </span><span>color</span><span>: </span><span>"#357ef5"</span></div></div><div><div><div>38</div></div><div><span><span>      </span></span><span>- </span><span>desc</span><span>: </span><span>EDU,软件工程专业</span></div></div><div><div><div>39</div></div><div><span>        </span><span>color</span><span>: </span><span>"#357ef5"</span></div></div><div><div><div>40</div></div><div><span>    </span><span>img</span><span>: </span><span>https://bu.dusays.com/2023/04/21/644287166329b.png</span></div></div><div><div><div>41</div></div><div><span>  </span><span>statistic</span><span>:</span></div></div><div><div><div>42</div></div><div><span>    </span><span>link</span><span>: </span><span>/archives</span></div></div><div><div><div>43</div></div><div><span>    </span><span>text</span><span>: </span><span>文章隧道</span></div></div><div><div><div>44</div></div><div><span>    </span><span>cover</span><span>: </span><span>https://bu.dusays.com/2023/05/01/644f4b037b930.jpg</span></div></div><div><div><div>45</div></div><div><span>  </span><span>map</span><span>:</span></div></div><div><div><div>46</div></div><div><span>    </span><span>title</span><span>: </span><span>我现在住在</span></div></div><div><div><div>47</div></div><div><span>    </span><span>StrengthenTitle</span><span>: </span><span>中国，长沙市</span></div></div><div><div><div>48</div></div><div><span>    </span><span>background</span><span>: </span><span>https://bu.dusays.com/2023/07/05/64a4c61cb20ef.jpg</span></div></div><div><div><div>49</div></div><div><span>    </span><span>backgroundDark</span><span>: </span><span>https://bu.dusays.com/2023/07/05/64a4c63495ac5.jpg</span></div></div><div><div><div>50</div></div><div><span>  </span><span>selfInfo</span><span>:</span></div></div><div><div><div>51</div></div><div><span>    </span><span>selfInfoTips1</span><span>: </span><span>生于</span></div></div><div><div><div>52</div></div><div><span>    </span><span>selfInfoContentYear</span><span>: </span><span>2002</span></div></div><div><div><div>53</div></div><div><span>    </span><span>selfInfoTips2</span><span>: </span><span>湖南信息学院</span></div></div><div><div><div>54</div></div><div><span>    </span><span>selfInfoContent2</span><span>: </span><span>软件工程</span></div></div><div><div><div>55</div></div><div><span>    </span><span>selfInfoTips3</span><span>: </span><span>现在职业</span></div></div><div><div><div>56</div></div><div><span>    </span><span>selfInfoContent3</span><span>: </span><span>大三学生👨‍🎓</span></div></div><div><div><div>57</div></div><div><span>  </span><span>personalities</span><span>:</span></div></div><div><div><div>58</div></div><div><span>    </span><span>author_name</span><span>: </span><span>执政官</span></div></div><div><div><div>59</div></div><div><span>    </span><span>personality_type</span><span>: </span><span>ESFJ-A</span></div></div><div><div><div>60</div></div><div><span>    </span><span>photo_url</span><span>: </span><span>https://bu.dusays.com/2023/07/05/64a4c63495ac5.jpg</span></div></div><div><div><div>61</div></div><div><span>    </span><span>personality_img</span><span>: </span><span>https://npm.elemecdn.com/anzhiyu-blog@2.0.8/img/svg/ESFJ-A.svg</span></div></div><div><div><div>62</div></div><div><span>    </span><span>name_url</span><span>: </span><span>https://www.16personalities.com/ch/esfj-%E4%BA%BA%E6%A0%BC</span></div></div><div><div><div>63</div></div><div><span>  </span><span>maxim</span><span>:</span></div></div><div><div><div>64</div></div><div><span>    </span><span>maxim_tips</span><span>: </span><span>座右铭</span></div></div><div><div><div>65</div></div><div><span>    </span><span>maxim_top</span><span>: </span><span>生活明朗，</span></div></div><div><div><div>66</div></div><div><span>    </span><span>maxim_bottom</span><span>: </span><span>万物可爱。</span></div></div><div><div><div>67</div></div><div><span>  </span><span>buff</span><span>:</span></div></div><div><div><div>68</div></div><div><span>    </span><span>buff_tips</span><span>: </span><span>特长</span></div></div><div><div><div>69</div></div><div><span>    </span><span>buff_top</span><span>: </span><span>脑回路新奇的 酸菜鱼</span></div></div><div><div><div>70</div></div><div><span>    </span><span>buff_bottom</span><span>: </span><span>二次元指数 MAX</span></div></div><div><div><div>71</div></div><div><span>  </span><span>game</span><span>:</span></div></div><div><div><div>72</div></div><div><span>    </span><span>game_tips</span><span>: </span><span>爱好游戏</span></div></div><div><div><div>73</div></div><div><span>    </span><span>game_title</span><span>: </span><span>原神</span></div></div><div><div><div>74</div></div><div><span>    </span><span>game_uid</span><span>: </span><span>"UID: 125766904"</span></div></div><div><div><div>75</div></div><div><span>    </span><span>game_bg</span><span>: </span><span>https://bu.dusays.com/2023/04/22/64433bf26e25d.webp</span></div></div><div><div><div>76</div></div><div><span>  </span><span>comic</span><span>:</span></div></div><div><div><div>77</div></div><div><span>    </span><span>comic_tips</span><span>: </span><span>爱好番剧</span></div></div><div><div><div>78</div></div><div><span>    </span><span>comic_title</span><span>: </span><span>追番</span></div></div><div><div><div>79</div></div><div><span>    </span><span>comic_list</span><span>:</span></div></div><div><div><div>80</div></div><div><span><span>      </span></span><span>- </span><span>name</span><span>: </span><span>约定的梦幻岛</span></div></div><div><div><div>81</div></div><div><span>        </span><span>href</span><span>: </span><span>https://www.bilibili.com/bangumi/media/md5267750/?spm_id_from=666.25.b_6d656469615f6d6f64756c65.1</span></div></div><div><div><div>82</div></div><div><span>        </span><span>cover</span><span>: </span><span>https://bu.dusays.com/2023/05/27/647166c44b414.webp</span></div></div><div><div><div>83</div></div><div><span><span>      </span></span><span>- </span><span>name</span><span>: </span><span>咒术回战</span></div></div><div><div><div>84</div></div><div><span>        </span><span>href</span><span>: </span><span>https://www.bilibili.com/bangumi/media/md28229899/?spm_id_from=666.25.b_6d656469615f6d6f64756c65.1</span></div></div><div><div><div>85</div></div><div><span>        </span><span>cover</span><span>: </span><span>https://bu.dusays.com/2023/05/24/646db4398832e.webp</span></div></div><div><div><div>86</div></div><div><span><span>      </span></span><span>- </span><span>name</span><span>: </span><span>紫罗兰永恒花园</span></div></div><div><div><div>87</div></div><div><span>        </span><span>href</span><span>: </span><span>https://www.bilibili.com/bangumi/media/md8892/?spm_id_from=666.25.b_6d656469615f6d6f64756c65.1</span></div></div><div><div><div>88</div></div><div><span>        </span><span>cover</span><span>: </span><span>https://bu.dusays.com/2023/05/24/646db43983d99.webp</span></div></div><div><div><div>89</div></div><div><span><span>      </span></span><span>- </span><span>name</span><span>: </span><span>鬼灭之刃</span></div></div><div><div><div>90</div></div><div><span>        </span><span>href</span><span>: </span><span>https://www.bilibili.com/bangumi/media/md22718131/?spm_id_from=666.25.b_6d656469615f6d6f64756c65.1</span></div></div><div><div><div>91</div></div><div><span>        </span><span>cover</span><span>: </span><span>https://bu.dusays.com/2023/05/24/646db439856a0.webp</span></div></div><div><div><div>92</div></div><div><span><span>      </span></span><span>- </span><span>name</span><span>: </span><span>JOJO的奇妙冒险 黄金之风</span></div></div><div><div><div>93</div></div><div><span>        </span><span>href</span><span>: </span><span>https://www.bilibili.com/bangumi/media/md135652/?spm_id_from=666.25.b_6d656469615f6d6f64756c65.1</span></div></div><div><div><div>94</div></div><div><span>        </span><span>cover</span><span>: </span><span>https://bu.dusays.com/2023/05/30/64760e38d651a.webp</span></div></div><div><div><div>95</div></div><div><span>  </span><span>like</span><span>:</span></div></div><div><div><div>96</div></div><div><span>    </span><span>like_tips</span><span>: </span><span>关注偏好</span></div></div><div><div><div>97</div></div><div><span>    </span><span>like_title</span><span>: </span><span>数码科技</span></div></div><div><div><div>98</div></div><div><span>    </span><span>like_bg</span><span>: </span><span>https://bu.dusays.com/2022/12/06/638f5f05ce1f7.jpg</span></div></div><div><div><div>99</div></div><div><span>    </span><span>like_bottom</span><span>: </span><span>手机、电脑软硬件</span></div></div><div><div><div>100</div></div><div><span>  </span><span>music</span><span>:</span></div></div><div><div><div>101</div></div><div><span>    </span><span>music_tips</span><span>: </span><span>音乐偏好</span></div></div><div><div><div>102</div></div><div><span>    </span><span>music_title</span><span>: </span><span>许嵩、民谣、华语流行</span></div></div><div><div><div>103</div></div><div><span>    </span><span>music_bg</span><span>: </span><span>https://p2.music.126.net/Mrg1i7DwcwjWBvQPIMt_Mg==/79164837213438.jpg</span></div></div><div><div><div>104</div></div><div><span>    </span><span>music_link</span><span>: </span><span>/music</span></div></div><div><div><div>105</div></div><div><span>  </span><span>reward_list</span><span>:</span></div></div><div><div><div>106</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>海阔蓝</span></div></div><div><div><div>107</div></div><div><span>      </span><span>amount</span><span>: </span><span>8.8</span></div></div><div><div><div>108</div></div><div><span>      </span><span>datatime</span><span>: </span><span>2023-03-28</span></div></div><div><div><div>109</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>LK66</span></div></div><div><div><div>110</div></div><div><span>      </span><span>amount</span><span>: </span><span>66.6</span></div></div><div><div><div>111</div></div><div><span>      </span><span>datatime</span><span>: </span><span>2023-03-24</span></div></div><div><div><div>112</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>张时貳</span></div></div><div><div><div>113</div></div><div><span>      </span><span>amount</span><span>: </span><span>6.6</span></div></div><div><div><div>114</div></div><div><span>      </span><span>datatime</span><span>: </span><span>2023-01-22</span></div></div><div><div><div>115</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>ZeroAf</span></div></div><div><div><div>116</div></div><div><span>      </span><span>amount</span><span>: </span><span>9.9</span></div></div><div><div><div>117</div></div><div><span>      </span><span>datatime</span><span>: </span><span>2022-12-14</span></div></div><div><div><div>118</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>LuckyWangXi</span></div></div><div><div><div>119</div></div><div><span>      </span><span>amount</span><span>: </span><span>6.6</span></div></div><div><div><div>120</div></div><div><span>      </span><span>datatime</span><span>: </span><span>2022-12-14</span></div></div><div><div><div>121</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>刀中日月长</span></div></div><div><div><div>122</div></div><div><span>      </span><span>amount</span><span>: </span><span>10</span></div></div><div><div><div>123</div></div><div><span>      </span><span>datatime</span><span>: </span><span>2022-11-16</span></div></div><div><div><div>124</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>鹿啵包</span></div></div><div><div><div>125</div></div><div><span>      </span><span>amount</span><span>: </span><span>10</span></div></div><div><div><div>126</div></div><div><span>      </span><span>datatime</span><span>: </span><span>2022-11-08</span></div></div><div><div><div>127</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>疾速k</span></div></div><div><div><div>128</div></div><div><span>      </span><span>amount</span><span>: </span><span>50</span></div></div><div><div><div>129</div></div><div><span>      </span><span>datatime</span><span>: </span><span>2022-09-20</span></div></div><div><div><div>130</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>伴舟先生大霖子</span></div></div><div><div><div>131</div></div><div><span>      </span><span>amount</span><span>: </span><span>4.03</span></div></div><div><div><div>132</div></div><div><span>      </span><span>datatime</span><span>: </span><span>2022-10-27</span></div></div><div><div><div>133</div></div><div><span>      </span><span>suffix</span><span>: </span><span>贝壳</span></div></div><div><div><div>134</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>Magica_0x0</span></div></div><div><div><div>135</div></div><div><span>      </span><span>amount</span><span>: </span><span>3.36</span></div></div><div><div><div>136</div></div><div><span>      </span><span>datatime</span><span>: </span><span>2022-10-07</span></div></div><div><div><div>137</div></div><div><span>      </span><span>suffix</span><span>: </span><span>贝壳</span></div></div><div><div><div>138</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>名字就是要短像这样</span></div></div><div><div><div>139</div></div><div><span>      </span><span>amount</span><span>: </span><span>3.36</span></div></div><div><div><div>140</div></div><div><span>      </span><span>datatime</span><span>: </span><span>2022-08-25</span></div></div><div><div><div>141</div></div><div><span>      </span><span>suffix</span><span>: </span><span>贝壳</span></div></div><div><div><div>142</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>Leviathan520</span></div></div><div><div><div>143</div></div><div><span>      </span><span>amount</span><span>: </span><span>1.34</span></div></div><div><div><div>144</div></div><div><span>      </span><span>datatime</span><span>: </span><span>2022-08-23</span></div></div><div><div><div>145</div></div><div><span>      </span><span>suffix</span><span>: </span><span>贝壳</span></div></div><div><div><div>146</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>托马斯</span></div></div><div><div><div>147</div></div><div><span>      </span><span>amount</span><span>: </span><span>10</span></div></div><div><div><div>148</div></div><div><span>      </span><span>datatime</span><span>: </span><span>2022-08-19</span></div></div><div><div><div>149</div></div><div><span><span>    </span></span><span>- </span><span>name</span><span>: </span><span>哇是猫猫欸</span></div></div><div><div><div>150</div></div><div><span>      </span><span>amount</span><span>: </span><span>1.34</span></div></div><div><div><div>151</div></div><div><span>      </span><span>datatime</span><span>: </span><span>2022-08-19</span></div></div><div><div><div>152</div></div><div><span>      </span><span>suffix</span><span>: </span><span>贝壳</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>

<table><thead><tr><th>参数</th><th>备选值/类型</th><th>解释</th></tr></thead><tbody><tr><td>class_name</td><td>关于页</td><td>【必须】页面类</td></tr><tr><td>subtitle</td><td>string</td><td>【必须】副标题</td></tr><tr><td>avatarImg</td><td>url</td><td>【必须】头像链接</td></tr><tr><td>name</td><td>string</td><td>【必须 作者名称</td></tr><tr><td>description</td><td>string</td><td>【必须】描述</td></tr><tr><td>aboutsiteTips</td><td>object</td><td>【必须】站点关于提示相关配置</td></tr><tr><td>aboutsiteTips.tips</td><td>string</td><td>【必须】站点关于提示性文字</td></tr><tr><td>aboutsiteTips.title1</td><td>string</td><td>【必须】站点关于标题文字 1</td></tr><tr><td>aboutsiteTips.title2</td><td>string</td><td>【必须】站点关于标题文字 2</td></tr><tr><td>aboutsiteTips.word</td><td>list</td><td>【必须】站点关于标题滚动文字</td></tr><tr><td>helloAbout</td><td>string</td><td>【必须】hello 文字</td></tr><tr><td>skillsTips</td><td>object</td><td>【必须】技能相关配置</td></tr><tr><td>skillsTips.tips</td><td>string</td><td>【必须】技能提示文字</td></tr><tr><td>skillsTips.title</td><td>string</td><td>【必须】技能标题</td></tr><tr><td>careers</td><td>object</td><td>【必须】生涯相关配置</td></tr><tr><td>careers.tips</td><td>string</td><td>【必须】生涯提示性文字</td></tr><tr><td>careers.title</td><td>string</td><td>【必须】生涯标题</td></tr><tr><td>careers.list</td><td>list</td><td>【可选】生涯 item</td></tr><tr><td>careers.list.desc</td><td>string</td><td>【可选】生涯 item 描述</td></tr><tr><td>careers.list.color</td><td>string</td><td>【可选】生涯 item 圆圈颜色</td></tr><tr><td>careers.img</td><td>string</td><td>【必须】生涯底部图片</td></tr><tr><td>statistic</td><td>object</td><td>【必须】统计数据相关配置</td></tr><tr><td>statistic.link</td><td>url</td><td>【必须】统计数据按钮前往链接</td></tr><tr><td>statistic.text</td><td>string</td><td>【必须】统计数据按钮文字</td></tr><tr><td>map</td><td>object</td><td>【必须】地图相关配置</td></tr><tr><td>map.title</td><td>string</td><td>【必须】地图标题</td></tr><tr><td>map.StrengthenTitle</td><td>string</td><td>【必须】地图大标题</td></tr><tr><td>map.background</td><td>url</td><td>【必须】地图亮色模式背景</td></tr><tr><td>map.backgroundDark</td><td>url</td><td>【必须】地图暗色模式背景</td></tr><tr><td>selfInfo</td><td>object</td><td>【必须】作者相关信息配置</td></tr><tr><td>selfInfo.selfInfoTips1</td><td>string</td><td>【必须】作者相关提示文字 1</td></tr><tr><td>selfInfo.selfInfoContentYear</td><td>number</td><td>【必须】作者生日年份</td></tr><tr><td>selfInfo.selfInfoTips2</td><td>string</td><td>【必须】作者相关提示文字 2</td></tr><tr><td>selfInfo.selfInfoContent2</td><td>string</td><td>【必须】作者相关内容 2</td></tr><tr><td>selfInfo.selfInfoTips3</td><td>string</td><td>【必须】作者相关提示文字 3</td></tr><tr><td>selfInfo.selfInfoContent3</td><td>string</td><td>【必须】作者相关内容 3</td></tr><tr><td>personalities</td><td>object</td><td>【必须】作者性格相关配置</td></tr><tr><td>personalities.author_name</td><td>string</td><td>【必须】作者性格名称</td></tr><tr><td>personalities.personality_type</td><td>string</td><td>【必须】作者性格类型</td></tr><tr><td>personalities.photo_url</td><td>url</td><td>【必须】作者自拍图片</td></tr><tr><td>personalities.personality_img</td><td>url</td><td>【必须】作者性格表述图片</td></tr><tr><td>personalities.name_url</td><td>url</td><td>【必须】点击性格跳转到链接</td></tr><tr><td>maxim</td><td>object</td><td>【必须】座右铭相关配置</td></tr><tr><td>maxim.maxim_tips</td><td>string</td><td>【必须】座右铭相关提示文字</td></tr><tr><td>maxim.maxim_top</td><td>string</td><td>【必须】座右铭相关顶部文字</td></tr><tr><td>maxim.maxim_bottom</td><td>string</td><td>【必须】座右铭相关底部文字</td></tr><tr><td>buff</td><td>object</td><td>【必须】特长相关配置</td></tr><tr><td>buff.buff_tips</td><td>string</td><td>【必须】特长相关提示文字</td></tr><tr><td>buff.buff_top</td><td>string</td><td>【必须】特长相关顶部文字</td></tr><tr><td>buff.buff_bottom</td><td>string</td><td>【必须】特长相关底部文字</td></tr><tr><td>game</td><td>object</td><td>【必须】爱好游戏相关配置</td></tr><tr><td>game.game_tips</td><td>string</td><td>【必须】爱好游戏提示文字</td></tr><tr><td>game.game_title</td><td>string</td><td>【必须】爱好游戏标题</td></tr><tr><td>game.game_uid</td><td>string</td><td>【必须】爱好游戏 uid</td></tr><tr><td>game.game_bg</td><td>url</td><td>【必须】爱好游戏背景</td></tr><tr><td>comic</td><td>object</td><td>【必须】追番相关配置，需要 5 条数据</td></tr><tr><td>comic.comic_tips</td><td>string</td><td>【必须】追番相关提示文字</td></tr><tr><td>comic.comic_title</td><td>string</td><td>【必须】追番相关标题</td></tr><tr><td>comic.comic_list</td><td>list</td><td>【必须】追番相关列表</td></tr><tr><td>comic.comic_list.name</td><td>string</td><td>【必须】追番 item 名称</td></tr><tr><td>comic.comic_list.href</td><td>url</td><td>【必须】追番 item 链接</td></tr><tr><td>comic.comic_list.cover</td><td>url</td><td>【必须】追番 item 的 cover</td></tr><tr><td>like</td><td>object</td><td>【必须】关注偏好相关配置</td></tr><tr><td>like.like_tips</td><td>string</td><td>【必须】关注偏好配置提示文字</td></tr><tr><td>like.like_title</td><td>string</td><td>【必须】关注偏好配置标题</td></tr><tr><td>like.like_bg</td><td>url</td><td>【必须】关注偏好配置背景</td></tr><tr><td>like.like_bottom</td><td>string</td><td>【必须】关注偏好配置底部文字</td></tr><tr><td>music</td><td>object</td><td>【必须】音乐偏好相关配置</td></tr><tr><td>music.music_tips</td><td>string</td><td>【必须】音乐偏好提示性文字</td></tr><tr><td>music.music_title</td><td>string</td><td>【必须】音乐偏好标题</td></tr><tr><td>music.music_bg</td><td>url</td><td>【必须】音乐偏好背景</td></tr><tr><td>music.music_link</td><td>url</td><td>【必须】音乐偏好按钮链接</td></tr><tr><td>reward_list</td><td>object</td><td>【可选】打赏相关配置，如果不配置将没有打赏模块</td></tr><tr><td>reward_list.name</td><td>string</td><td>【必须】打赏 item 名称</td></tr><tr><td>reward_list.amount</td><td>number</td><td>【必须】打赏 item 金额</td></tr><tr><td>reward_list.datatime</td><td>Date</td><td>【必须】打赏 item 时间</td></tr><tr><td>reward_list.suffix</td><td>string/元</td><td>【可选】打赏 item 后缀（默认元）</td></tr></tbody></table><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/12/8ef11323e01d4b4181b86c98a11a5e386432643720ef6.png!blogimg" alt="关于页" /><figcaption>关于页</figcaption></figure><p></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/ce3dfa33/</id>
      <title type="text">安装主题</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/ce3dfa33/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>搭建 Hexo 博客<a href="#搭建-hexo-博客"><span>#</span></a></h2><p>如果你还没有 Hexo 博客，请按照 <a href="https://hexo.io/zh-cn/docs/" target="_blank">Hexo 官方文档</a> 进行安装、建站。</p></section>
<section><h2>作者的话<a href="#作者的话"><span>#</span></a></h2><p>请注意<code>_config.anzhiyu.yml</code>中的配置优先级大于<code>_config.yml</code>，所以更新主题后需要比对主题文件夹中的<code>theme/anzhiyu/_config.yml</code> 文件内容，一般在<a href="https://github.com/anzhiyu-c/hexo-theme-anzhiyu/releases" target="_blank">release</a> 的说明里会特别提示或给出配置文件版本对比diff，同步修改原配置文件即可。</p><div><div><div></div><div>Tip</div></div><div><p>致主题的新用户：</p><ul>
<li>
<p>本指南经过数个版本打磨，绝大部分的功能都有详细说明，请仔细阅读，节约自己和他人的时间；</p>
</li>
<li>
<p>本指南中提到的：“<strong>站点配置</strong>” 指的 Hexo 博客目录下的 _config.yml，“<strong>主题配置</strong>” 指的是 theme/anzhiyu/_config.yml 或者 _config.anzhiyu.yml ，注意区分；</p>
</li>
<li>
<p>本指南中提到的 <code>source</code> 目录都指的是博客目录下的 <code>source</code> 文件夹，不推荐修改主题内 <code>source</code> 目录；</p>
</li>
<li>
<p>每次无论 <code>hexo g</code> 或 <code>hexo s</code>，都最好先使用 <code>hexo clean</code> 清除本地缓存；</p>
</li>
<li>
<p>页面结果以本地 <code>hexo s</code> 为准，部署后的异常大部分是线上缓存原因，在确认没有报错的情况下，等待若干时间后即可正常；</p>
</li>
<li>
<p>由于主题的不同版本会存在配置差异，本指南以最新版本为准。</p>
</li>
</ul><p>本指南不包括所有的配置说明，几乎每个配置在主题配置中都有注释，可配合指南共同参考使用。</p><p>另外本指南仅包含主题范围内的使用说明，如果是 Hexo 的使用或者 Hexo 插件的使用，请查阅各自的文档。</p><p>若存在其他主题相关的疑问请在 <a href="https://github.com/anzhiyu-c/hexo-theme-anzhiyu/issues/new" target="_blank">issues</a> 留言。</p></div></div></section>
<section><h2>主题安装<a href="#主题安装"><span>#</span></a></h2><div><div><div></div><div>Note</div></div><div><p>温馨提示</p><p>Anzhiyu主题拥有<strong>Main</strong>(稳定版)和<strong>Dev</strong>(测试版)两种版本, 我们推荐您安装使用<strong>Github</strong>(稳定版)以获得最佳的主题体验</p></div></div><p><strong>方式一(Github 推荐):</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>-b</span><span> </span><span>main</span><span> </span><span>https://github.com/anzhiyu-c/hexo-theme-anzhiyu.git</span><span> </span><span>themes/anzhiyu</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如遇安装不上可以使用以下url代理安装</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>-b</span><span> </span><span>main</span><span> </span><span>https://ghproxy.com/https://github.com/anzhiyu-c/hexo-theme-anzhiyu.git</span><span> </span><span>themes/anzhiyu</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>方式二(Release 推荐):</strong></p><p>下载 <a href="https://github.com/anzhiyu-c/hexo-theme-anzhiyu/releases" target="_blank">最新 release 版本</a> 解压到 <code>themes</code> 目录，并将解压出的文件夹重命名为 <code>anzhiyu</code>。</p><p><strong>方式三(npm安装):</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>i</span><span> </span><span>hexo-theme-anzhiyu</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>此方法只支持 Hexo 5.0.0 以上版本 通过 npm 安装并不会在 themes 里生成主题文件夹，而是在 node_modules 里生成</p><p><strong>测试版Dev</strong></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>-b</span><span> </span><span>dev</span><span> </span><span>https://github.com/anzhiyu-c/hexo-theme-anzhiyu.git</span><span> </span><span>themes/anzhiyu</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>测试版可能存在 bug，追求稳定的请安装稳定版</p></section>
<section><h2>应用主题<a href="#应用主题"><span>#</span></a></h2><p>打开 <strong>Hexo</strong> 根目录下的 <code>config.yml</code>, 找到以下配置项，把主题改为<code>anzhiyu</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># Extensions</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>## Plugins: https://hexo.io/plugins/</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>## Themes: https://hexo.io/themes/</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>theme</span><span>: </span><span>anzhiyu</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>安装 pug 和 stylus 渲染插件<a href="#安装-pug-和-stylus-渲染插件"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>hexo-renderer-pug</span><span> </span><span>hexo-renderer-stylus</span><span> </span><span>--save</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>无法安装可以使用cnpm进行安装</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>hexo-renderer-pug</span><span> </span><span>hexo-renderer-stylus</span><span> </span><span>--save</span><span> </span><span>--registry=http://registry.npmmirror.com</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>覆盖配置<a href="#覆盖配置"><span>#</span></a></h2><p>覆盖配置可以使<code>主题配置</code>放置在 anzhiyu 目录之外，避免在更新主题时丢失自定义的配置。</p><p>通过 Npm 安装主题的用户可忽略，其他用户建议学习使用。</p><ul>
<li>macos/linux 在博客根目录运行</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cp</span><span> </span><span>-rf</span><span> </span><span>./themes/anzhiyu/_config.yml</span><span> </span><span>./_config.anzhiyu.yml</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>windows 复制<code>/themes/anzhiyu/_config.yml</code>此文件到 hexo 根目录，并重命名为<code>_config.anzhiyu.yml</code></li>
</ul><p>以后如果修改任何主题配置，都只需修改 _config.anzhiyu.yml 的配置即可。</p><p>注意：</p><ul>
<li>只要存在于 <code>_config.anzhiyu.yml</code> 的配置都是高优先级，修改原 <code>_config.yml</code> 是无效的。</li>
<li>每次更新主题可能存在配置变更，请注意更新说明，可能需要手动对 <code>_config.anzhiyu.yml</code> 同步修改。</li>
<li>想查看覆盖配置有没有生效，可以通过 <code>hexo g --debug</code> 查看命令行输出。</li>
<li>如果想将某些配置覆盖为空，注意不要把主键删掉，不然是无法覆盖的</li>
</ul></section>
<section><h2>本地启动 hexo<a href="#本地启动-hexo"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>hexo</span><span> </span><span>cl</span></div></div><div><div><div>2</div></div><div><span>hexo</span><span> </span><span>g</span></div></div><div><div><div>3</div></div><div><span>hexo</span><span> </span><span>s</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>此时就能在看到效果了。</p></section>
<section><h2>升级方法<a href="#升级方法"><span>#</span></a></h2><p><strong>方式一</strong></p><blockquote><p>适用于通过 Github 或 Release 压缩包主题，且没有自行修改任何代码的情况。</p></blockquote><ol>
<li>
<p>先将原文件夹重命名为别的名称，例如 <code>anzhiyu-bkp</code>，用于升级失败进行回退；</p>
</li>
<li>
<p>选择自己的安装方式升级</p>
</li>
</ol><p><code>Github</code>：重新重新执行安装命令即可</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>-b</span><span> </span><span>main</span><span> </span><span>https://github.com/anzhiyu-c/hexo-theme-anzhiyu.git</span><span> </span><span>themes/anzhiyu</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><code>Release</code>：按照安装步骤，下载 <a href="https://github.com/anzhiyu-c/hexo-theme-anzhiyu/releases" target="_blank">release</a> 并解压重命名为 <code>anzhiyu</code>；</p><ol>
<li>比对升级后的配置文件<code>_config.yml</code>，如果某些配置发生了变化（改名或弃用），<a href="https://github.com/anzhiyu-c/hexo-theme-anzhiyu/releases" target="_blank">release</a> 的说明里会特别提示或给出配置文件版本对比diff，同步修改原配置文件即可。</li>
</ol><p><strong>方式二</strong></p><blockquote><p>适用于通过 Npm 安装主题。</p></blockquote><p>在博客目录下执行命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>update</span><span> </span><span>--save</span><span> </span><span>hexo-theme-anzhiyu</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>比对升级后的配置文件<code>_config.yml</code>,如果某些配置发生了变化（改名或弃用），<a href="https://github.com/anzhiyu-c/hexo-theme-anzhiyu/releases" target="_blank">release</a> 的说明里会特别提示或给出配置文件版本对比diff，同步修改原配置文件即可。</p><p><strong>方式三</strong></p><p>全量更新：删除<strong>theme/anzhiyu</strong>文件夹，然后重新执行安装命令即可。</p><p>比对升级后的配置文件<code>_config.yml</code>,如果某些配置发生了变化（改名或弃用），<a href="https://github.com/anzhiyu-c/hexo-theme-anzhiyu/releases" target="_blank">release</a> 的说明里会特别提示或给出配置文件版本对比diff，同步修改原配置文件即可。</p><div><div><div></div><div>Note</div></div><div><p>视频教程</p><p>什么？你还是不会？这里有视频 <a href="https://www.bilibili.com/video/BV1Rs4y127hu/?spm_id_from=333.788&amp;vd_source=4d9717102296e4b7a60ecdfad55ae2dd" target="_blank">AnZhiYu 主题安装教程</a></p></div></div></section>
<section><h2>版本号释义<a href="#版本号释义"><span>#</span></a></h2><p>本项目的版本号为 X.Y.Z 格式，但与常见的<a href="https://semver.org/lang/zh-CN/" target="_blank">语义化版本号规范</a>有部分区别，具体释义如下：</p><p>X: 产品层面的重新设计，包含重大框架重构，会涉及大范围功能变更与配置变更，更新前必须阅读相关文档</p><p>Y: 包含中大型新功能，及无法向下兼容的功能变更与配置变更，更新该版本号可能会需要修改配置或者移除一些原功能</p><p>Z: 不仅包含 BUG 修复、小型新功能，还会包含可以向下兼容的原功能更新与配置变更，原则上更新该版本号无需额外动作</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/e1914f00/</id>
      <title type="text">留言板配置</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/e1914f00/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>留言板页面配置<a href="#留言板页面配置"><span>#</span></a></h2><p>在博客根目录执行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>hexo-butterfly-envelope</span><span> </span><span>--save</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在站点配置文件<code>_config.yml</code>中添加以下内容配置，更多配置请查看信笺样式留言板</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#envelope_comment</span></div></div><div><div><div>2</div></div><div><span>#seehttps://akilar.top/posts/e2d3c450/</span></div></div><div><div><div>3</div></div><div><span>envelope_comment</span><span>:</span></div></div><div><div><div>4</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span><span> </span><span>#控制开关</span></div></div><div><div><div>5</div></div><div><span>  </span><span>custom_pic</span><span>:</span></div></div><div><div><div>6</div></div><div><span>    </span><span>cover</span><span>: </span><span>https://npm.elemecdn.com/hexo-butterfly-envelope/lib/violet.jpg</span><span> </span><span>#信笺头部图片</span></div></div><div><div><div>7</div></div><div><span>    </span><span>line</span><span>: </span><span>https://npm.elemecdn.com/hexo-butterfly-envelope/lib/line.png</span><span> </span><span>#信笺底部图片</span></div></div><div><div><div>8</div></div><div><span>    </span><span>beforeimg</span><span>: </span><span>https://npm.elemecdn.com/hexo-butterfly-envelope/lib/before.png</span><span> </span><span># 信封前半部分</span></div></div><div><div><div>9</div></div><div><span>    </span><span>afterimg</span><span>: </span><span>https://npm.elemecdn.com/hexo-butterfly-envelope/lib/after.png</span><span> </span><span># 信封后半部分</span></div></div><div><div><div>10</div></div><div><span>  </span><span>message</span><span>: </span><span>#信笺正文，多行文本，写法如下</span></div></div><div><div><div>11</div></div><div><span><span>    </span></span><span>- </span><span>有什么想问的？</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>- </span><span>有什么想说的？</span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>- </span><span>有什么想吐槽的？</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>- </span><span>哪怕是有什么想吃的，都可以告诉我哦~</span></div></div><div><div><div>15</div></div><div><span>  </span><span>bottom</span><span>: </span><span>自动书记人偶竭诚为您服务！</span><span> </span><span>#仅支持单行文本</span></div></div><div><div><div>16</div></div><div><span>  </span><span>height</span><span>: </span><span>#1024px，信封划出的高度</span></div></div><div><div><div>17</div></div><div><span>  </span><span>path</span><span>: </span><span>#【可选】comments 的路径名称。默认为 comments，生成的页面为 comments/index.html</span></div></div><div><div><div>18</div></div><div><span>  </span><span>front_matter</span><span>: </span><span>#【可选】comments页面的 front_matter 配置</span></div></div><div><div><div>19</div></div><div><span>    </span><span>title</span><span>: </span><span>留言板</span></div></div><div><div><div>20</div></div><div><span>    </span><span>comments</span><span>: </span><span>true</span></div></div><div><div><div>21</div></div><div><span>    </span><span>top_img</span><span>: </span><span>false</span></div></div><div><div><div>22</div></div><div><span>    </span><span>type</span><span>: </span><span>envelope</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/e3ca322b/</id>
      <title type="text">追番页面配置</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/e3ca322b/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>追番页面配置<a href="#追番页面配置"><span>#</span></a></h2><p>在博客根目录执行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>hexo-bilibili-bangumi</span><span> </span><span>--save</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在 hexo 配置文件<code>_config.yml</code>中加入以下配置，注意不是主题配置文件，更多配置请参考<a href="https://github.com/HCLonely/hexo-bilibili-bangumi" target="_blank">hexo-bilibili-bangumi</a></p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 追番插件</span></div></div><div><div><div>2</div></div><div><span># https://github.com/HCLonely/hexo-bilibili-bangumi</span></div></div><div><div><div>3</div></div><div><span>bangumi</span><span>: </span><span># 追番设置</span></div></div><div><div><div>4</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>  </span><span>source</span><span>: </span><span>bili</span></div></div><div><div><div>6</div></div><div><span>  </span><span>path</span><span>:</span></div></div><div><div><div>7</div></div><div><span>  </span><span>vmid</span><span>: </span><span>372204786</span></div></div><div><div><div>8</div></div><div><span>  </span><span>title</span><span>: </span><span>"追番列表"</span></div></div><div><div><div>9</div></div><div><span>  </span><span>quote</span><span>: </span><span>"生命不息，追番不止！"</span></div></div><div><div><div>10</div></div><div><span>  </span><span>show</span><span>: </span><span>1</span></div></div><div><div><div>11</div></div><div><span>  </span><span>lazyload</span><span>: </span><span>false</span></div></div><div><div><div>12</div></div><div><span>  </span><span>loading</span><span>:</span></div></div><div><div><div>13</div></div><div><span>  </span><span>showMyComment</span><span>: </span><span>false</span></div></div><div><div><div>14</div></div><div><span>  </span><span>pagination</span><span>: </span><span>false</span></div></div><div><div><div>15</div></div><div><span>  </span><span>metaColor</span><span>:</span></div></div><div><div><div>16</div></div><div><span>  </span><span>color</span><span>:</span></div></div><div><div><div>17</div></div><div><span>  </span><span>webp</span><span>:</span></div></div><div><div><div>18</div></div><div><span>  </span><span>progress</span><span>:</span></div></div><div><div><div>19</div></div><div><span>  </span><span>extraOrder</span><span>:</span></div></div><div><div><div>20</div></div><div><span>  </span><span>proxy</span><span>:</span></div></div><div><div><div>21</div></div><div><span>    </span><span>host</span><span>: </span><span>"代理host"</span></div></div><div><div><div>22</div></div><div><span>    </span><span>port</span><span>: </span><span>"代理端口"</span></div></div><div><div><div>23</div></div><div><span>  </span><span>extra_options</span><span>:</span></div></div><div><div><div>24</div></div><div><span>    </span><span>top_img</span><span>: </span><span>false</span></div></div><div><div><div>25</div></div><div><span>    </span><span>lazyload</span><span>:</span></div></div><div><div><div>26</div></div><div><span>      </span><span>enable</span><span>: </span><span>false</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/12/454df2e226b24f7e97cefae309b8f49d20251218170054295.png" alt="追番页" /><figcaption>追番页</figcaption></figure><p></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/e5ac434e/</id>
      <title type="text">标签页配置</title>
      <published>2025-01-23T12:32:13.000Z</published>
      <updated>2025-01-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/e5ac434e/"/>
      <summary type="text">如果能给我一个star那将是对我莫大的鼓励。使用这个主题之前，你应该明白它是一个 Hexo 主题，它的基本逻辑离不开 Hexo，关于如何新建分类，如何新建标签这些问题应该在使用之前就从互联网或官方文档了解详情 🔎。安知鱼主题 是基于 Hexo 的一款 简单、美丽 的主题，由 安知鱼 负责开发与维护。</summary>
      <content type="html"><![CDATA[<section><h2>标签页配置<a href="#标签页配置"><span>#</span></a></h2><ol>
<li>
<p>前往你的 Hexo 博客的根目录</p>
</li>
<li>
<p>在 Hexo 博客根目录 <code>[blog]</code>下打开终端，输入</p>
</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>hexo</span><span> </span><span>new</span><span> </span><span>page</span><span> </span><span>tags</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>
<p>你会找到 <code>source/tags/index.md</code> 这个文件</p>
</li>
<li>
<p>修改这个文件： 记得添加 <code>type: "tags"</code></p>
</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title: 标签</span></div></div><div><div><div>3</div></div><div><span>date: 2021-04-06 12:01:51</span></div></div><div><div><div>4</div></div><div><span>type: "tags"</span></div></div><div><div><div>5</div></div><div><span>comments: false</span></div></div><div><div><div>6</div></div><div><span>top_img: false</span></div></div><div><div><div>7</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<table><thead><tr><th>参数</th><th>解释</th></tr></thead><tbody><tr><td>type</td><td>【必须】页面类型，必须为 tags</td></tr><tr><td>comments</td><td>【可选】是否显示评论</td></tr><tr><td>top_img</td><td>【可选】是否显示顶部图</td></tr><tr><td>orderby</td><td>【可选】排序方式 ：random/name/length</td></tr><tr><td>order</td><td>【可选】排序次序： 1, asc for ascending; -1, desc for descending</td></tr></tbody></table><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/a0e1f8302afd43129afe8bd6ef2040156432634045c13.png!blogimg" alt="标签页详情" /><figcaption>标签页详情</figcaption></figure><p></p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/11/d038b794a859478ea126794cf83d376e6432637cecf77.png!blogimg" alt="" /></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/8ddfbcd7/</id>
      <title type="text">Visual Studio 修改NuGet 包缓存路径</title>
      <published>2024-12-23T12:32:13.000Z</published>
      <updated>2024-12-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/8ddfbcd7/"/>
      <summary type="text">Visual Studio 下载的NuGet包默认会缓存到 C:\Users{Windows用户名}.nuget\packages 下，时间一长就会导致 C盘空间严重不足。 那么怎样去设置，让包缓存文件保存到其他盘呢？</summary>
      <content type="html"><![CDATA[<section><h2>Visual Studio 修改NuGet 包缓存路径<a href="#visual-studio-修改nuget-包缓存路径"><span>#</span></a></h2><p>Visual Studio 下载的NuGet包默认会缓存到 <code>C:\Users{Windows用户名}.nuget\packages</code> 下，时间一长就会导致 C盘空间严重不足。</p><p>那么怎样去设置，让包缓存文件保存到其他盘呢？</p><p>首先我们要找到 <code>Microsoft.VisualStudio.Offline.config</code> 这个文件，它在哪呢？ 在 <code>C:\Program Files (x86)\NuGet\Config</code>。</p><p>再到文件并用记事本打开 如下：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/03/image-20250320152927827.png" alt="image-20250320152927827" /><figcaption>image-20250320152927827</figcaption></figure><p></p><p>我们在中间增加如下配置内容：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>  </span></span><span>&lt;</span><span>config</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span><span>      </span></span><span>&lt;</span><span>add</span><span> </span><span>key</span><span>=</span><span>"globalPackagesFolder"</span><span> </span><span>value</span><span>=</span><span>"D:\Nuget\.nuget\packages"</span><span> /&gt;</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>&lt;/</span><span>config</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>最终效果如下图：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/03/image-20250320153015594.png" alt="image-20250320153015594" /><figcaption>image-20250320153015594</figcaption></figure><p></p><p>这样就配置好了，重新打开 Visual Studio 下载 NuGet 包文件后，查看包的引用地址就会发现地址为修改后的地址。</p><p><strong>温馨提示</strong>：在配置好地址后，可将原来已经缓存的包文件全部拷贝到新的目录中。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/46bd4ea2/</id>
      <title type="text">47k Star：一款开源免费的 Markdown 编辑器</title>
      <published>2024-12-15T20:31:13.000Z</published>
      <updated>2024-12-15T20:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/46bd4ea2/"/>
      <summary type="text">MarkText 是一款简单优雅的 Markdown 编辑器，适用于 Linux、macOS 和 Windows 系统。它拥有简洁干净的界面设计，没有过多复杂的菜单和按钮，使得用户可以专注于内容创作。无论是新手还是习惯简洁风格的用户，都能轻松上手并享受高效的写作体验。</summary>
      <content type="html"><![CDATA[<section><h3>简介<a href="#简介"><span>#</span></a></h3><p>MarkText 是一款简单优雅的 Markdown 编辑器，适用于 Linux、macOS 和 Windows 系统。它拥有简洁干净的界面设计，没有过多复杂的菜单和按钮，使得用户可以专注于内容创作。无论是新手还是习惯简洁风格的用户，都能轻松上手并享受高效的写作体验。</p></section>
<section><h3>主要特点<a href="#主要特点"><span>#</span></a></h3><ul>
<li><strong>跨平台：</strong> 支持 Linux、macOS 和 Windows 等多个操作系统，用户可以在不同的设备和系统上使用相同的编辑工具，方便在不同平台上进行写作和编辑。</li>
<li><strong>简洁界面：</strong> 界面设计简洁，去除了多余的菜单和按钮，让用户更加专注于内容创作。</li>
<li><strong>实时预览：</strong> 提供实时预览功能（WYSIWYG），用户在编辑过程中可以即时看到最终的呈现效果，无需频繁切换预览模式，方便用户及时调整格式和内容，提高写作效率。</li>
<li><strong>丰富的语法支持：</strong> 支持 CommonMark Spec、GitHub Flavored Markdown Spec 等多种 Markdown 规范，对基础语法以及数学表达式（KaTeX）、front matter 和 emojis 等扩展语法都有很好的支持，能够满足用户多样化的写作需求。</li>
<li><strong>多种编辑模式：</strong> 具有源代码模式、打字机模式、焦点模式等多种编辑模式，可以满足用户在不同场景下的写作需求。例如，在源代码模式下可以专注于代码的编写，在打字机模式下可以享受打字时自动滚动屏幕的流畅体验。</li>
<li><strong>强大的表格功能：</strong> 表格功能较为强大，支持直接插入预先定义大小的表格，并且可以方便地用鼠标移动列和行，操作简单，无需过多关注底层代码。</li>
<li><strong>开源免费：</strong> 采用 MIT 许可证开源，用户可以免费使用，并且开源的特性也使得代码透明度高，安全性有一定保障，同时吸引了众多开发者为其贡献代码，能够不断改进和完善。</li>
<li><strong>丰富的主题：</strong> 提供了多种主题，如 Cadmium Light、Material Dark 等，用户可以根据自己的喜好选择主题，并且还支持自定义 CSS 样式，满足用户对于界面个性化的需求。</li>
<li><strong>丰富的快捷键：</strong> 提供了丰富的快捷键操作，方便用户快速执行常用的功能，如保存、加粗、斜体、插入代码块、插入表格等，提高编辑效率。</li>
</ul><blockquote><p>编辑模式展示</p></blockquote><ul>
<li>源代码模式
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/12/640.gif" alt="" /></li>
<li>打字机模式
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/12/641.gif" alt="" /></li>
<li>焦点模式
<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/12/642.gif" alt="" /></li>
</ul></section>
<section><h3>总结<a href="#总结"><span>#</span></a></h3><p>MarkText 是一个非常适合撰写文档、博客和技术文章的工具，尤其适合喜欢 Markdown 格式的用户。其简洁的界面、丰富的功能和跨平台支持使其成为一款不可多得的 Markdown 编辑器。无论是初学者还是资深用户，都能在 MarkText 中找到满意的使用体验。</p></section>
<section><h3>下载地址<a href="#下载地址"><span>#</span></a></h3><ul>
<li>官网地址：<a href="https://www.marktext.cc/" target="_blank">https://www.marktext.cc/</a></li>
<li>github地址：<a href="https://github.com/marktext/marktext" target="_blank">https://github.com/marktext/marktext</a></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/6508e70d/</id>
      <title type="text">Linux系统Tomcat启动指定JDK版本</title>
      <published>2024-12-09T08:31:13.000Z</published>
      <updated>2024-12-09T08:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/6508e70d/"/>
      <summary type="text">在linux系统上启动tomcat指定jdk版本，多版本环境</summary>
      <content type="html"><![CDATA[<section><h2>Linux系统Tomcat启动指定JDK版本<a href="#linux系统tomcat启动指定jdk版本"><span>#</span></a></h2><blockquote><p>JDK安装目录</p></blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>/usr/local/java</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>修改catalina.sh和setclasspath.sh文件<a href="#修改catalinash和setclasspathsh文件"><span>#</span></a></h2><blockquote><p>进入tomcat bin目录</p></blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>.</span><span>./apache-tomcat-8.5.35/bin</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>两个文件都加入以下内容</p></blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>export</span><span> </span><span>JAVA_HOME</span><span><span>=</span><span>/</span></span><span>usr</span><span>/</span><span>local</span><span>/</span><span>java</span><span>/</span><span>jdk1</span><span>.</span><span>8</span><span>.</span><span>0_131</span><span>/</span></div></div><div><div><div>2</div></div><div><span>export</span><span> </span><span>JRE_HOME</span><span><span>=</span><span>/</span></span><span>usr</span><span>/</span><span>local</span><span>/</span><span>java</span><span>/</span><span>jdk1</span><span>.</span><span>8</span><span>.</span><span>0_131</span><span>/</span><span>jre</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>注意：”=” 左右两边不要有空格，否则会报错!!!!!</strong></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/ee64e7e0/</id>
      <title type="text">git常用命令</title>
      <published>2024-11-23T12:32:13.000Z</published>
      <updated>2024-11-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/ee64e7e0/"/>
      <summary type="text">Git是一个强大的分布式版本控制系统，它提供了许多命令来帮助开发者管理代码的变更历史和协作</summary>
      <content type="html"><![CDATA[<section><h3>初始化和配置<a href="#初始化和配置"><span>#</span></a></h3><ol>
<li><code>git init</code> - 初始化一个新的Git仓库。</li>
<li><code>git config --global user.name "Your Name"</code> - 设置全局用户名，用于提交。</li>
<li><code>git config --global user.email "your_email@example.com"</code> - 设置全局用户邮箱，用于提交。</li>
</ol></section>
<section><h3>文件操作<a href="#文件操作"><span>#</span></a></h3><ol>
<li><code>git status</code> - 查看当前工作目录的状态，显示有变更的文件。</li>
<li><code>git add &lt;file&gt;</code> - 将指定文件添加到暂存区。</li>
<li><code>git add .</code> - 添加当前目录下所有变更的文件到暂存区。</li>
<li><code>git add -A</code> - 添加所有新文件和变更的文件到暂存区。</li>
<li><code>git reset &lt;file&gt;</code> - 取消暂存区中指定文件的变更。</li>
<li><code>git rm &lt;file&gt;</code> - 删除指定文件，并将其添加到暂存区。</li>
<li><code>git rm --cached &lt;file&gt;</code> - 从暂存区中移除指定文件，但不删除工作目录中的文件。</li>
</ol></section>
<section><h3>提交和历史<a href="#提交和历史"><span>#</span></a></h3><ol>
<li><code>git commit -m "Commit message"</code> - 提交暂存区中的变更，并添加提交信息。</li>
<li><code>git log</code> - 查看提交历史。</li>
<li><code>git diff</code> - 查看工作目录和最后一次提交之间的差异。</li>
<li><code>git diff HEAD~1</code> - 查看上一次提交的变更。</li>
<li><code>git diff --cached</code> - 查看暂存区和最后一次提交之间的差异。</li>
</ol></section>
<section><h3>分支和标签<a href="#分支和标签"><span>#</span></a></h3><ol>
<li><code>git branch</code> - 列出所有本地分支。</li>
<li><code>git branch &lt;branchname&gt;</code> - 创建一个新分支。</li>
<li><code>git checkout &lt;branchname&gt;</code> - 切换到指定分支。</li>
<li><code>git merge &lt;branchname&gt;</code> - 将指定分支合并到当前分支。</li>
<li><code>git branch -d &lt;branchname&gt;</code> - 删除指定的本地分支。</li>
<li><code>git push origin &lt;branchname&gt;</code> - 推送本地分支到远程仓库。</li>
<li><code>git pull</code> - 从远程仓库拉取变更并合并到当前分支。</li>
<li><code>git tag &lt;tagname&gt;</code> - 为当前提交打上标签。</li>
<li><code>git push origin --tags</code> - 推送所有标签到远程仓库。</li>
</ol></section>
<section><h3>远程仓库<a href="#远程仓库"><span>#</span></a></h3><ol>
<li><code>git clone &lt;repository&gt;</code> - 克隆一个远程仓库到本地。</li>
<li><code>git remote add origin &lt;repository&gt;</code> - 添加一个远程仓库。</li>
<li><code>git remote -v</code> - 显示所有远程仓库的URL。</li>
<li><code>git fetch</code> - 从远程仓库获取最新变更，但不合并。</li>
<li><code>git push</code> - 将本地变更推送到远程仓库。</li>
<li><code>git pull</code> - 从远程仓库拉取变更并合并到当前分支。</li>
</ol></section>
<section><h3>撤销和修复<a href="#撤销和修复"><span>#</span></a></h3><ol>
<li><code>git reset --soft HEAD~1</code> - 回退到上一次提交，保留变更在暂存区。</li>
<li><code>git reset --mixed HEAD~1</code> - 回退到上一次提交，将变更移回工作目录。</li>
<li><code>git reset --hard HEAD~1</code> - 回退到上一次提交，丢弃所有工作目录和暂存区的变更。</li>
<li><code>git revert &lt;commit&gt;</code> - 创建一个新的提交，撤销指定提交的变更。</li>
</ol></section>
<section><h3>其他有用的命令<a href="#其他有用的命令"><span>#</span></a></h3><ol>
<li><code>git stash</code> - 临时保存工作目录的变更。</li>
<li><code>git stash list</code> - 列出所有储藏的变更。</li>
<li><code>git stash apply</code> - 应用储藏的变更。</li>
<li><code>git stash drop</code> - 删除指定的储藏变更。</li>
<li><code>git gc</code> - 清理不必要的文件和优化本地仓库。</li>
</ol><p>这些命令是Git中最基础和最常用的命令，掌握它们可以帮助您更有效地使用Git进行版本控制和代码管理。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/ba3c9851/</id>
      <title type="text">【音乐】洛雪音乐助手</title>
      <published>2024-10-29T22:32:13.000Z</published>
      <updated>2024-10-29T22:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/ba3c9851/"/>
      <summary type="text">本文介绍了“洛雪音乐助手”，一个基于 Electron + Vue 开发的开源免费音乐软件。该软件聚合了多个音乐平台的功能，支持在 Windows、Mac OS、Linux 和 Android 平台上运行。软件提供搜索、试听、收藏和下载功能（已不支持无损下载）。项目开源发布于 GitHub，旨在为技术学习交流提供资源</summary>
      <content type="html"><![CDATA[<blockquote><p>简介</p></blockquote>
<p>一个基于 Electron + Vue 开发的开源免费音乐软件，聚合各音乐平台，完善软件设计，覆盖多平台（MAC、windows），搜索、试听、收藏、下载（已不支持无损下载）样样行。</p>
<blockquote><p>开源</p></blockquote>
<ul>
<li>本项目开源发布于 GitHub 面向全世界人用作对技术的学习交流使用</li>
</ul>
<blockquote><p>免费且无广告</p></blockquote>
<ul>
<li>本项目开发的初衷仅是为了对新技术的学习与研究，因此软件直至停止维护都将会一直保持纯净</li>
</ul>
<blockquote><p>多端支持</p></blockquote>
<ul>
<li>本项目支持在Windows、Mac OS、Linux、Android平台上运行。</li>
</ul>
<blockquote><p>说明</p></blockquote>
<ul>
<li>
<p>本项目不计划支持IOS。当前版本比128k更高的音质已失效！</p>
</li>
<li>
<p>官方网站：<a href="https://github.com/lyswhut/lx-music-desktop" target="_blank">https://github.com/lyswhut/lx-music-desktop</a></p>
</li>
<li>
<p>更新记录：<a href="https://github.com/lyswhut/lx-music-desktop/blob/master/CHANGELOG.md" target="_blank">https://github.com/lyswhut/lx-music-desktop/blob/master/CHANGELOG.md</a></p>
</li>
</ul>

<blockquote><p>下载</p></blockquote>
<p>桌面端：</p>
<ul>
<li><a href="https://github.com/lyswhut/lx-music-desktop/releases" target="_blank">github下载</a></li>
<li><a href="https://www.lanzoui.com/b0bf2cfa/" target="_blank">蓝凑云下载</a> 密码：<code>glqw</code></li>
</ul>
<p>移动端：</p>
<ul>
<li><a href="https://github.com/lyswhut/lx-music-mobile/releases" target="_blank">github下载</a></li>
<li><a href="https://www.lanzoui.com/b0bf2cfa/" target="_blank">蓝凑云下载</a> 密码：<code>glqw</code></li>
</ul>
<blockquote><p><strong>若链接无法打开请百度：蓝奏云链接打不开</strong></p></blockquote>
<blockquote><p>自定义音源</p></blockquote>
<ol>
<li>
<p>下载并解压 六音自定义音源 <a href="https://www.sixyin.com/8498.html" target="_blank">官方页面</a> | <a href="https://soso.lanzouj.com/b00p9c94f#8mno" target="_blank">下载链接</a>(提取码：8mno)</p>
</li>
<li>
<p><strong>解压，解压，一定要解压！！</strong></p>
</li>
<li>
<p>打开 <code>设置</code> &gt; <code>基本设置</code> &gt; <code>音乐来源</code> &gt; <code>自定义源管理</code></p>
</li>
</ol>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/10/202410301131186.png" alt="自定义源管理" /><figcaption>自定义源管理</figcaption></figure><p></p>
<ol>
<li>点本地导入，把下载的文件导进去</li>
</ol>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/10/202410301133552.png" alt="文件导入" /><figcaption>文件导入</figcaption></figure><p></p>
<ol>
<li>退出来把钩子打上，等待初始化即可。初始化完看起来是这样：</li>
</ol>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/10/202410301133920.png" alt="初始化" /><figcaption>初始化</figcaption></figure><p></p>
<ol>
<li>设置 &gt; 下载设置 &gt; 是否启用下载功能 勾上✅</li>
</ol>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/10/202410301134748.png" alt="启用下载功能" /><figcaption>启用下载功能</figcaption></figure><p></p>
<ol>
<li>去搜索歌曲现在就可以下载了</li>
</ol>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/10/202410301135664.png" alt="搜索歌曲" /><figcaption>搜索歌曲</figcaption></figure><p></p>
<blockquote><p>在线音源</p></blockquote>
<p><strong>1、在线音源-原始链接</strong></p>

<table><thead><tr><th>音源名称</th><th>音源链接</th></tr></thead><tbody><tr><td>SixYin</td><td><a href="https://coolcpt.cn/go?_=0f0e3d671baHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Bkb25lL2x4LW11c2ljLXNvdXJjZS9tYWluL3NpeHlpbi9sYXRlc3QuanM%3D" target="_blank">https://raw.githubusercontent.com/pdone/lx-music-source/main/sixyin/latest.js</a></td></tr><tr><td>monster</td><td><a href="https://www.huhaha.vip/static/lxmusic/zh-monster-v1.5.5.js" target="_blank"> https://www.huhaha.vip/static/lxmusic/zh-monster-v1.5.5.js</a></td></tr><tr><td>all-api</td><td><a href="https://www.huhaha.vip/static/lxmusic/all-api-v3.js" target="_blank">https://www.huhaha.vip/static/lxmusic/all-api-v3.js</a></td></tr><tr><td>Huibq</td><td><a href="https://fastly.jsdelivr.net/gh/Huibq/keep-alive/render_api.js" target="_blank">https://fastly.jsdelivr.net/gh/Huibq/keep-alive/render_api.js</a></td></tr></tbody></table>
<p><strong>2、在线音源-加速链接</strong></p>

<table><thead><tr><th>音源名称</th><th>音源链接</th></tr></thead><tbody><tr><td>SixYin</td><td><a href="https://coolcpt.cn/go?_=0a24637d23aHR0cHM6Ly9naHByb3h5Lm5ldC9odHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcGRvbmUvbHgtbXVzaWMtc291cmNlL21haW4vc2l4eWluL2xhdGVzdC5qcw%3D%3D" target="_blank">https://ghproxy.net/https://raw.githubusercontent.com/pdone/lx-music-source/main/sixyin/latest.js</a></td></tr><tr><td>Huibq</td><td><a href="https://coolcpt.cn/go?_=ee8a436268aHR0cHM6Ly9naHByb3h5Lm5ldC9odHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcGRvbmUvbHgtbXVzaWMtc291cmNlL21haW4vaHVpYnEvbGF0ZXN0Lmpz" target="_blank">https://ghproxy.net/https://raw.githubusercontent.com/pdone/lx-music-source/main/huibq/latest.js</a></td></tr><tr><td>Flower</td><td><a href="https://coolcpt.cn/go?_=b0fcd1f57eaHR0cHM6Ly9naHByb3h5Lm5ldC9odHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcGRvbmUvbHgtbXVzaWMtc291cmNlL21haW4vZmxvd2VyL2xhdGVzdC5qcw%3D%3D" target="_blank">https://ghproxy.net/https://raw.githubusercontent.com/pdone/lx-music-source/main/flower/latest.js</a></td></tr><tr><td>Grass</td><td><a href="https://coolcpt.cn/go?_=5576d5d5c3aHR0cHM6Ly90dC50ZW5tZW5nLmNvbS9tb29udWUvanMveWVjYW8yMDI0MTIuanM%3D" target="_blank">https://tt.tenmeng.com/moonue/js/yecao202412.js</a></td></tr></tbody></table>
<p>加速链接仅推荐访问 GitHub 受限的用户使用，如果你的网络可以流畅访问 GitHub，建议直接使用原始链接。</p>
<p><strong>3、其它加速站点</strong></p>
<p>当以上链接无法访问时，可将连接开头的 <a href="https://ghproxy.net/" target="_blank">https://ghproxy.net/</a> 替换为下边任一地址，然后重试。</p>
<blockquote><p><a href="https://coolcpt.cn/go?_=1c67f674c0aHR0cHM6Ly9naC5sbGtrLmNjLw%3D%3D" target="_blank">https://gh.llkk.cc/</a>
<a href="https://coolcpt.cn/go?_=b680ec4a78aHR0cHM6Ly9naXRodWIubW9leXkueHl6Lw%3D%3D" target="_blank">https://github.moeyy.xyz/</a>
<a href="https://coolcpt.cn/go?_=d3ba9ef82daHR0cHM6Ly9naHByb3h5LmNuLw%3D%3D" target="_blank">https://ghproxy.cn/</a>
<a href="https://coolcpt.cn/go?_=59e4acf4f4aHR0cHM6Ly9naC5hcGkuOTk5ODg4NjYueHl6Lw%3D%3D" target="_blank">https://gh.api.99988866.xyz/</a>
<a href="https://coolcpt.cn/go?_=22dcaf0ce9aHR0cHM6Ly9naHAuY2kv" target="_blank">https://ghp.ci/</a></p></blockquote>
<p>例如，将 <a href="https://coolcpt.cn/go?_=b35e60d8c1aHR0cHM6Ly9naHByb3h5Lm5ldC8%3D" target="_blank">https://ghproxy.net/</a><a href="https://coolcpt.cn/go?_=0f0e3d671baHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Bkb25lL2x4LW11c2ljLXNvdXJjZS9tYWluL3NpeHlpbi9sYXRlc3QuanM%3D" target="_blank">https://raw.githubusercontent.com/pdone/lx-music-source/main/sixyin/latest.js</a> 链接替换为 <a href="https://coolcpt.cn/go?_=1c67f674c0aHR0cHM6Ly9naC5sbGtrLmNjLw%3D%3D" target="_blank">https://gh.llkk.cc/</a><a href="https://coolcpt.cn/go?_=0f0e3d671baHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Bkb25lL2x4LW11c2ljLXNvdXJjZS9tYWluL3NpeHlpbi9sYXRlc3QuanM%3D" target="_blank">https://raw.githubusercontent.com/pdone/lx-music-source/main/sixyin/latest.js</a></p>
<p><strong>4、在线音源使用方法</strong></p>
<p>如果你是桌面端Win/Mac等设备，请参考下图教程导入：</p>
<p>1、打开洛雪音乐软件，依次进入 [设置] – [基本设置] – [音乐来源] – [自定义源管理]</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/02/image-20250211101015906.png" alt="image-20250211101015906" /><figcaption>image-20250211101015906</figcaption></figure><p></p>
<p>2、选择 [在线导入]</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/02/image-20250211101029065.png" alt="image-20250211101029065" /><figcaption>image-20250211101029065</figcaption></figure><p></p>
<p>3、粘贴在线音源链接，单击 [导入] 按钮</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/02/image-20250211101103801.png" alt="image-20250211101103801" /><figcaption>image-20250211101103801</figcaption></figure><p></p>
<p>4、选中音源，提示初始化成功即可。</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/02/image-20250211101119852.png" alt="image-20250211101119852" /><figcaption>image-20250211101119852</figcaption></figure><p></p>
<blockquote><p>大功告成</p></blockquote>
<p>剩下的功能自己探索吧，接下来我们一起愉快的听歌吧</p>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/13d4ef64/</id>
      <title type="text">【影视】TVBoxAPP</title>
      <published>2024-10-29T21:31:13.000Z</published>
      <updated>2024-10-29T21:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/13d4ef64/"/>
      <summary type="text">“TVBox开源版APP”，一个专为安卓平台设计的影视播放应用。该应用通过导入特定资源接口，解析各类爬虫源、XP源和采集源，完全无广告且无任何限制。新版本支持多jar（爬虫包）、直播节目预告等功能，并优化了UI聚合检索和阿里网盘资源读取。文章提供了配置方法、相关版本下载链接和多个资源中心地址，帮助用户更好地使用该应用。</summary>
      <content type="html"><![CDATA[<img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/10/202410301031512.png" alt="图片描述" width="100" height="100" />
<blockquote><p>简介
“TVBox开源版APP”，一个专为安卓平台设计的影视播放应用。该应用通过导入特定资源接口，解析各类爬虫源、XP源和采集源，完全无广告且无任何限制。新版本支持多jar（爬虫包）、直播节目预告等功能，并优化了UI聚合检索和阿里网盘资源读取。文章提供了配置方法、相关版本下载链接和多个资源中心地址，帮助用户更好地使用该应用。</p></blockquote>
<p>平台：</p>
<ul>
<li>安卓</li>
</ul>
<p>类型：</p>
<ul>
<li>影视</li>
</ul>

<blockquote><p>TVbox开源版</p></blockquote>
<ul>
<li>
<p>通过导入特点资源接口,解析各类爬虫源、XP源、采集源等。完全无任何限制,也无任何广告。</p>
</li>
<li>
<p>原版支持本地功能，聚合模式，支持多种视频格式，增加分辨率、时间及缓冲速度显示，优化采集等等。</p>
</li>
<li>
<p>新UI聚合检索(长按影片)，支持读取挂载阿里网盘资源，其他功能同原版。</p>
</li>
<li>
<p>设置 — 配置地址 — 输入你的站源规则 — 确定即可；</p>
</li>
<li>
<p>新版支持多jar(爬虫包)，增加直播节目预告 EGP。</p>
</li>
<li>
<p>编辑器 PC Web版 CatVodTVJsonEditor</p>
</li>
<li>
<p>配置地址---输入站源---确定即可 URL站源规则</p>
</li>
</ul>
<blockquote><p>相关版本</p></blockquote>
<p>由于开源版已很久没人维护更新，所以现在网上大部分都是根据该版二开衍生的各种版本</p>
<p>这里引用了 奇奇乐享 公众号上的一个下载链接，里面包含了大部分的TVBOX相关的版本</p>
<p><a href="https://qiqi2020.lanzouw.com/b09svqv1c" target="_blank">https://qiqi2020.lanzouw.com/b09svqv1c</a></p>
<p>推荐较多有 影迷 和 影视仓 仅作参考，也可能其他版本你更喜欢！</p>
<blockquote><p>资源中心</p></blockquote>
<p>资源仅来源于网络，不保证最新。如有失效或推荐，可联系站长重新整理和添加！</p>

<table><thead><tr><th>名称</th><th>地址</th></tr></thead><tbody><tr><td>dxawi</td><td><a href="https://dxawi.github.io/0/0.json" target="_blank">https://dxawi.github.io/0/0.json</a></td></tr><tr><td>饭太硬</td><td><a href="http://www.%E9%A5%AD%E5%A4%AA%E7%A1%AC.com/tv" target="_blank">http://www.饭太硬.com/tv</a></td></tr><tr><td>小米</td><td><a href="http://xhww.fun:63/%E5%B0%8F%E7%B1%B3/DEMO.json" target="_blank">http://xhww.fun:63/小米/DEMO.json</a></td></tr><tr><td>唐三</td><td><a href="https://gcore.jsdelivr.net/gh/gaotianliuyun/gao/0828.json" target="_blank">https://gcore.jsdelivr.net/gh/gaotianliuyun/gao/0828.json</a></td></tr><tr><td>小米</td><td><a href="http://xhww.fun:63/%E5%B0%8F%E7%B1%B3/DEMO.json" target="_blank">http://xhww.fun:63/小米/DEMO.json</a></td></tr><tr><td>FongMI</td><td><a href="https://gcore.jsdelivr.net/gh/gaotianliuyun/gao/0827.json" target="_blank">https://gcore.jsdelivr.net/gh/gaotianliuyun/gao/0827.json</a></td></tr><tr><td>纯一</td><td><a href="https://100km.top/0" target="_blank">https://100km.top/0</a></td></tr><tr><td>巧儿</td><td><a href="http://pandown.pro/tvbox/tvbox.json" target="_blank">http://pandown.pro/tvbox/tvbox.json</a></td></tr><tr><td>霜灰</td><td><a href="https://gcore.jsdelivr.net/gh/lm317379829/PyramidStore/pyramid/py.json" target="_blank">https://gcore.jsdelivr.net/gh/lm317379829/PyramidStore/pyramid/py.json</a></td></tr><tr><td>更多地址</td><td><a href="https://www.yck2.com/index/applist/tvbox.html" target="_blank">https://www.yck2.com/index/applist/tvbox.html</a></td></tr></tbody></table>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/1b4d6191/</id>
      <title type="text">【漫画】异次元APP</title>
      <published>2024-10-29T20:32:13.000Z</published>
      <updated>2024-10-29T20:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/1b4d6191/"/>
      <summary type="text">“异次元APP”，一个专为安卓平台设计的漫画阅读应用。该应用界面干净清爽，无广告，完全免费，支持下载缓存和离线阅读。用户可以通过添加多个图源，实现一次搜索多源漫画，享受近乎无限的资源。文章还提供了多个图源链接和相关下载地址，帮助用户更好地使用该应用。</summary>
      <content type="html"><![CDATA[<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/10/202410301004368.png" alt="异次元APP" /><figcaption>异次元APP</figcaption></figure><p></p>
<blockquote><p>简介</p></blockquote>
<p>平台：</p>
<ul>
<li>安卓</li>
</ul>
<p>类型：</p>
<ul>
<li>漫画</li>
</ul>

<blockquote><p>异次元</p></blockquote>
<ol>
<li>
<p>应用界面超级干净清爽，无广告，无多余花哨的东西。</p>
</li>
<li>
<p>完全免费，没有会员，没有广告骚扰</p>
</li>
<li>
<p>支持下载缓存，支持离线阅读</p>
</li>
<li>
<p>支持添加多个图源源，拥有近乎无限的资源，可随时切换源</p>
</li>
<li>
<p>可一次搜索多源漫画。</p>
</li>
<li>
<p>加入定制源地址后，可以在一个APP中免费观看全网漫画</p>
</li>
<li>
<p>现在只支持Android平台，不支持iPhone/iOS</p>
</li>
</ol>
<blockquote><p>图源(不定时更新)</p></blockquote>
<ul>
<li>
<p><a href="https://www.yck2.com/yiciyuan/tuyuan/content/id/785.html" target="_blank">九妖漫画👙 https://app.jymhapp.com</a></p>
</li>
<li>
<p><a href="https://www.yck2.com/yiciyuan/tuyuan/content/id/784.html" target="_blank">禁漫天堂[国内] https://18comic-hok.vip</a></p>
</li>
<li>
<p><a href="https://www.yck2.com/yiciyuan/tuyuan/content/id/783.html" target="_blank">漫蛙 https://manwasb.cc</a></p>
</li>
</ul>
<blockquote><p>图源合集（不定时更新）</p></blockquote>
<ul>
<li>
<p><a href="https://www.yck2.com/yiciyuan/tuyuans/content/id/50.html" target="_blank">2024.10.06 伪官方图源合集</a></p>
</li>
<li>
<p><a href="https://www.yck2.com/yiciyuan/tuyuans/content/id/48.html" target="_blank">自用整合（已检校）</a></p>
</li>
<li>
<p><a href="https://www.yck2.com/yiciyuan/tuyuans/content/id/46.html" target="_blank">又在鬼混（自用6.13校验）</a></p>
</li>
</ul>
<blockquote><p>相关链接</p></blockquote>
<ul>
<li>
<p><a href="https://www.yck2.com/yiciyuan/index/index.html" target="_blank">异次元-源仓库地址</a></p>
</li>
<li>
<p><a href="https://yiciyuan.lanzoui.com/b00ej0kba" target="_blank">异次元-下载地址</a></p>
</li>
</ul>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/306a73ac/</id>
      <title type="text">音乐自动化神器！Melody Hub 让你躺着听新歌，订阅歌单自动更新下载</title>
      <published>2024-10-29T20:32:13.000Z</published>
      <updated>2024-10-29T20:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/306a73ac/"/>
      <summary type="text">今天我要给大家介绍一个彻底解决这些问题的神器——**Melody Hub**，它不仅继承了洛雪音乐的所有优点，还增加了订阅歌单和定时下载功能，让你的音乐体验实现完全自动化！</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！我发现了一个音乐爱好者的终极神器！<a href="#朋友们我发现了一个音乐爱好者的终极神器"><span>#</span></a></h2><p>前阵子我给大家推荐了 LX Music（洛雪音乐）和 COCO 音乐下载站，它们分别解决了我们听音乐和下载音乐的需求。但是，不知道你们有没有遇到过这样的问题：</p><ul>
<li>喜欢的歌单更新了，需要手动去下载新歌曲</li>
<li>想下载新歌，但是没时间手动操作</li>
<li>音乐文件散落在各个地方，管理起来很麻烦</li>
</ul><p>今天我要给大家介绍一个彻底解决这些问题的神器——<strong>Melody Hub</strong>，它不仅继承了洛雪音乐的所有优点，还增加了订阅歌单和定时下载功能，让你的音乐体验实现完全自动化！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/493bb3ef786d4073995cc2bcb945a0e520260402135550254.png" alt="" /></p></section>
<section><h2>什么是 Melody Hub？<a href="#什么是-melody-hub"><span>#</span></a></h2><p>Melody Hub 是基于洛雪音乐的 Docker 定制版本，它继承了洛雪音乐原有的一切特性，同时增加了订阅歌单和定时下载等自动化功能，为用户提供了更加智能的音乐体验。</p></section>
<section><h2>为什么 Melody Hub 是音乐爱好者的终极神器？<a href="#为什么-melody-hub-是音乐爱好者的终极神器"><span>#</span></a></h2><section><h3>1️⃣ 订阅歌单，自动更新<a href="#1️⃣-订阅歌单自动更新"><span>#</span></a></h3><p>这是 Melody Hub 最强大的功能之一！你可以订阅你喜欢的歌单，当歌单更新时，Melody Hub 会自动同步更新，让你永远不会错过新音乐。</p><p>想象一下，你喜欢的歌手发了新专辑，或者你关注的歌单更新了，你不需要手动去下载，Melody Hub 会自动帮你搞定，等你打开音乐播放器时，新歌曲已经在你的播放列表里了！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/fe0fc54789764d7a84e1e378809199ac20260402135624636.png" alt="" /></p></section><section><h3>2️⃣ 定时下载，解放双手<a href="#2️⃣-定时下载解放双手"><span>#</span></a></h3><p>Melody Hub 支持设置定时下载任务，你可以根据自己的需求，设置在特定的时间自动下载你订阅的歌单或指定的音乐。</p><p>比如，你可以设置每天凌晨自动下载更新的歌单，这样每天早上起床，你就能听到最新的音乐了！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/7094c962dab64948b1aa28335bba942320260402135639838.png" alt="" /></p></section><section><h3>3️⃣ 专为 NAS 用户优化<a href="#3️⃣-专为-nas-用户优化"><span>#</span></a></h3><p>Melody Hub 特别为 NAS 用户进行了优化，支持 Docker 部署，让你可以在 NAS 上轻松运行，实现音乐的集中管理和多设备访问。</p><p>这样，你的音乐文件都存储在 NAS 上，既安全又方便，所有设备都可以访问同一个音乐库。</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/6fd2a1ec5c67427280d31b6ca9b084be20260402135713346.png" alt="" /></p></section><section><h3>4️⃣ 继承洛雪音乐的所有优点<a href="#4️⃣-继承洛雪音乐的所有优点"><span>#</span></a></h3><p>Melody Hub 完全继承了洛雪音乐的优点，包括：</p><ul>
<li>多平台支持（Windows、macOS、Linux）</li>
<li>多音乐源集成</li>
<li>数据同步服务</li>
<li>无广告、免费使用</li>
</ul></section><section><h3>5️⃣ 与 COCO 下载站完美配合<a href="#5️⃣-与-coco-下载站完美配合"><span>#</span></a></h3><p>Melody Hub 可以和 COCO 音乐下载站完美配合：</p><ul>
<li>用 COCO 音乐下载站手动搜索和下载特定音乐</li>
<li>用 Melody Hub 订阅歌单和定时自动下载</li>
<li>用 LX Music 在各种设备上播放音乐</li>
</ul></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>前几天我在我的 NAS 上部署了 Melody Hub，使用体验真的惊艳到我了：</p><ol>
<li>
<p><strong>订阅歌单</strong>：我订阅了几个喜欢的歌单，包括我最喜欢的歌手的官方歌单和一些音乐推荐歌单。</p>
</li>
<li>
<p><strong>设置定时下载</strong>：我设置了每天凌晨 2 点自动下载更新的歌单。</p>
</li>
<li>
<p><strong>自动更新</strong>：第二天早上，我打开音乐播放器，发现歌单已经自动更新了，新添加的歌曲也已经下载完成，真的太方便了！</p>
</li>
<li>
<p><strong>多设备访问</strong>：我可以在手机、电脑、平板上都能访问同一个音乐库，随时随地听我喜欢的音乐。</p>
</li>
<li>
<p><strong>集中管理</strong>：所有的音乐文件都存储在 NAS 上，管理起来非常方便，再也不用担心音乐文件散落在各个地方了。</p>
</li>
</ol></section>
<section><h2>Docker 部署方法<a href="#docker-部署方法"><span>#</span></a></h2><p>部署 Melody Hub 非常简单，只需要使用 Docker 即可：</p><ol>
<li>确保你的设备上安装了 Docker</li>
<li>运行以下命令拉取并运行 Melody Hub 容器：</li>
</ol><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>services</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>melodyhub</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image</span><span>: </span><span>geelonn/melodyhub:latest</span></div></div><div><div><div>4</div></div><div><span>    </span><span>container_name</span><span>: </span><span>melodyhub</span></div></div><div><div><div>5</div></div><div><span>    </span><span>restart</span><span>: </span><span>unless-stopped</span></div></div><div><div><div>6</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- </span><span>"3000:3000"</span></div></div><div><div><div>8</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>- </span><span>melodyhub-data:/app/data</span></div></div><div><div><div>10</div></div><div><span><span>      </span></span><span>- </span><span>melodyhub-files:/app/music</span></div></div><div><div><div>11</div></div><div><span>    </span><span>environment</span><span>:</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>- </span><span>NODE_ENV=production</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span>- </span><span>PORT=3000</span></div></div><div><div><div>14</div></div><div><span><span>      </span></span><span>- </span><span>DATA_DIR=/app/data</span></div></div><div><div><div>15</div></div><div><span><span>      </span></span><span>- </span><span>MUSIC_DIR=/app/music</span></div></div><div><div><div>16</div></div><div><span><span>      </span></span><span>- </span><span>JWT_SECRET=your-secure-secret-key</span></div></div><div><div><div>17</div></div><div><span><span>      </span></span><span>- </span><span>TZ=Asia/Shanghai</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>volumes</span><span>:</span></div></div><div><div><div>20</div></div><div><span>  </span><span>melodyhub-data</span><span>:</span></div></div><div><div><div>21</div></div><div><span>  </span><span>melodyhub-files</span><span>:</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><ol>
<li>打开浏览器访问 <code>http://你的服务器IP:3000</code>，你就可以开始使用了！，端口如果占用了，你可以修改配置文件中的左边的端口号。</li>
</ol></section>
<section><h2>如何获取音源文件？<a href="#如何获取音源文件"><span>#</span></a></h2><p>要使用 Melody Hub 的全部功能，你需要配置音源文件。找不到音源文件的朋友，可以私信我发送【音乐】获取。</p></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>音乐爱好者</strong>：想要自动获取最新音乐</li>
<li><strong>NAS 用户</strong>：想在 NAS 上部署音乐服务</li>
<li><strong>忙碌的人</strong>：没有时间手动下载音乐</li>
<li><strong>歌单控</strong>：喜欢关注和收藏各种歌单</li>
<li><strong>多设备用户</strong>：需要在多个设备上访问同一音乐库</li>
<li><strong>已经使用洛雪音乐的用户</strong>：想体验自动化的音乐管理</li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时是怎么管理和更新音乐的？有没有遇到过手动下载的麻烦？用了 Melody Hub 后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你有任何关于部署或使用的问题，也可以在评论区留言，我会尽力回答！</p></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><ul>
<li><strong>GitHub 仓库</strong>：<a href="https://github.com/gefl24/melody-hub" target="_blank">https://github.com/gefl24/melody-hub</a></li>
</ul><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="https://mp.weixin.qq.com/s/vOxJd-TJlnK8zO1s-e9EVg?token=2046857375&amp;lang=zh_CN" target="_blank">发现宝藏音乐播放器！MusicFree 让你告别广告和会员</a></li>
<li><a href="http://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2046857375&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
<li><a href="http://mp.weixin.qq.com/s/vs0eBElh1Tq9AbbVd126WA?token=2046857375&amp;lang=zh_CN" target="_blank">LX Sync Server 部署指南：轻松搭建自己的洛雪音乐服务</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/3a1c4628/</id>
      <title type="text">【漫画/小说/影视/音乐】益达APP</title>
      <published>2024-10-29T20:32:13.000Z</published>
      <updated>2024-10-29T20:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/3a1c4628/"/>
      <summary type="text">“益达APP”，一个基于 Flutter + Rust 开发的跨平台娱乐应用。该应用支持小说、影视、漫画和音频等多种内容类型，适用于安卓、iOS、Mac 和 Windows 平台。文章提供了安装包下载链接、规则导入链接和规则说明文档，帮助用户更好地使用该应用。</summary>
      <content type="html"><![CDATA[<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/10/202410301009719.png" alt="益达APP" /><figcaption>益达APP</figcaption></figure><p></p>
<blockquote><p>简介</p></blockquote>
<p>平台：</p>
<ul>
<li>全平台(安卓\IOS\MAC\WIN)</li>
</ul>
<p>类型：</p>
<ul>
<li>小说</li>
<li>影视</li>
<li>漫画</li>
<li>音频</li>
</ul>

<blockquote><p>flutter + rust 开发! 跨平台</p></blockquote>
<ul>
<li>安装包获取:<a href="https://github.com/xiaohucode/yidaRule/releases" target="_blank">https://github.com/xiaohucode/yidaRule/releases</a></li>
<li>规则导入：<a href="https://github.com/xiaohucode/yidaRule/raw/main/siteRule/ydSource.yds" target="_blank">https://github.com/xiaohucode/yidaRule/raw/main/siteRule/ydSource.yds</a></li>
<li>规则说明文档: <a href="https://github.com/xiaohucode/yidaRule/blob/main/Document.md" target="_blank">https://github.com/xiaohucode/yidaRule/blob/main/Document.md</a></li>
<li>PS: 规则中有很多失效的了，重在学习怎么制作源！</li>
<li>源第三方地址：<a href="https://gcore.jsdelivr.net/gh/xiaohucode/yidaRule/siteRule/ydSource.yds" target="_blank">https://gcore.jsdelivr.net/gh/xiaohucode/yidaRule/siteRule/ydSource.yds</a></li>
</ul>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/f045e55a/</id>
      <title type="text">音乐下载新选择！COCO音乐下载站让你轻松获取无损音乐，Docker 部署超简单</title>
      <published>2024-10-29T20:32:13.000Z</published>
      <updated>2024-10-29T20:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/f045e55a/"/>
      <summary type="text">前阵子我给大家推荐了洛雪音乐和 MusicFree，它们都是非常优秀的音乐播放器，让我们告别了广告和会员限制。但是，不知道你们有没有遇到过这样的问题：有时候听到喜欢的歌曲，想下载下来保存，却发现下载起来很麻烦？</summary>
      <content type="html"><![CDATA[<section><h2>朋友们！音乐爱好者的福利来了！<a href="#朋友们音乐爱好者的福利来了"><span>#</span></a></h2><p>前阵子我给大家推荐了洛雪音乐和 MusicFree，它们都是非常优秀的音乐播放器，让我们告别了广告和会员限制。但是，不知道你们有没有遇到过这样的问题：有时候听到喜欢的歌曲，想下载下来保存，却发现下载起来很麻烦？</p><p>今天我要给大家介绍一个专门的音乐下载工具——<strong>COCO音乐下载站</strong>，它可以帮你轻松下载各种音乐，甚至包括无损音质！</p><p><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2026/04/c0514566e2c3440495b913830b8745d420260402113711945.png" alt="" /></p></section>
<section><h2>什么是 COCO音乐下载站？<a href="#什么是-coco音乐下载站"><span>#</span></a></h2><p>COCO音乐下载站是一个基于 Next.js 16 构建的现代化音乐搜索与下载平台，界面设计简约纯净，支持多渠道音乐搜索、在线试听、批量下载，还配备了丝滑的暗黑模式。</p></section>
<section><h2>为什么推荐 COCO音乐下载站？<a href="#为什么推荐-coco音乐下载站"><span>#</span></a></h2><section><h3>1️⃣ 多源聚合搜索，想听什么搜什么<a href="#1️⃣-多源聚合搜索想听什么搜什么"><span>#</span></a></h3><p>COCO音乐下载站支持全网聚合搜索，内置多种音乐源渠道，包括歌曲宝、歌曲海、布谷、QQ音乐、咪咕等，一键切换，再也不用担心找不到想要的歌曲了！</p></section><section><h3>2️⃣ 在线试听，确认后再下载<a href="#2️⃣-在线试听确认后再下载"><span>#</span></a></h3><p>内置精美悬浮播放器，支持播放/暂停、进度拖拽、音量调节等功能，你可以先试听确认是你想要的歌曲，再进行下载，避免下载错误。</p></section><section><h3>3️⃣ 批量下载，效率更高<a href="#3️⃣-批量下载效率更高"><span>#</span></a></h3><p>支持多选歌曲，一键批量打包下载选中的音乐，节省你的时间。</p></section><section><h3>4️⃣ 支持无损音质<a href="#4️⃣-支持无损音质"><span>#</span></a></h3><p>部分音源（如咪咕、QQMP3等）在资源允许的情况下会自动解析出 FLAC 无损格式，让你享受更高品质的音乐。</p></section><section><h3>5️⃣ 丝滑的暗黑模式<a href="#5️⃣-丝滑的暗黑模式"><span>#</span></a></h3><p>完美适配深色/浅色模式，独家定制的涟漪扩散切换动画，视觉效果惊艳。</p></section></section>
<section><h2>Docker 部署方法<a href="#docker-部署方法"><span>#</span></a></h2><p>部署 COCO音乐下载站非常简单，只需要使用 Docker 即可，即使你是技术小白，也能轻松搞定！</p><section><h3>步骤1：docker-common.yml 一键部署（推荐）<a href="#步骤1docker-commonyml-一键部署推荐"><span>#</span></a></h3><p>打开终端或命令行工具，执行以下命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>services:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>coco-downloader:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>image:</span><span> </span><span>markcxx/coco-downloader:latest</span></div></div><div><div><div>4</div></div><div><span>    </span><span>container_name:</span><span> </span><span>coco-downloader</span></div></div><div><div><div>5</div></div><div><span>    </span><span>restart:</span><span> </span><span>always</span></div></div><div><div><div>6</div></div><div><span>    </span><span>ports:</span></div></div><div><div><div>7</div></div><div><span>      </span><span># 左侧是你宿主机端口，右侧是容器内部固定端口 3000</span></div></div><div><div><div>8</div></div><div><span>      </span><span>-</span><span> </span><span>"3000:3000"</span><span>  </span><span># 默认端口</span></div></div><div><div><div>9</div></div><div><span>      </span><span># 如果你想自定义端口，例如 8080，就改成：</span></div></div><div><div><div>10</div></div><div><span>      </span><span># - "8080:3000"</span></div></div><div><div><div>11</div></div><div><span>    </span><span>environment:</span></div></div><div><div><div>12</div></div><div><span>      </span><span># 容器内部端口固定 3000，不要改</span></div></div><div><div><div>13</div></div><div><span>      </span><span>-</span><span> </span><span>PORT=</span><span>3000</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤2：手动部署（可选）<a href="#步骤2手动部署可选"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 拉取 Docker 镜像</span></div></div><div><div><div>2</div></div><div><span>docker</span><span> </span><span>pull</span><span> </span><span>markcxx/coco-downloader:latest</span></div></div><div><div><div>3</div></div><div><span># 方式1：默认端口（3000）运行容器，默认端口（3000）</span></div></div><div><div><div>4</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>-p</span><span> </span><span>3000:3000</span><span> </span><span>--name</span><span> </span><span>coco-downloader</span><span> </span><span>markcxx/coco-downloader:latest</span></div></div><div><div><div>5</div></div><div><span># 方式2：自定义端口（例如 8080）</span></div></div><div><div><div>6</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>-p</span><span> </span><span>8080:3000</span><span> </span><span>-e</span><span> </span><span>PORT=</span><span>3000</span><span> </span><span>--name</span><span> </span><span>coco-downloader</span><span> </span><span>markcxx/coco-downloader:latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>步骤3：访问 COCO音乐下载站<a href="#步骤3访问-coco音乐下载站"><span>#</span></a></h3><p>部署完成后，打开浏览器访问 <code>http://你的服务器IP:3000</code>（如果使用了自定义端口，就访问 <code>http://你的服务器IP:8080</code>），你就可以开始使用了！</p></section></section>
<section><h2>我的使用体验<a href="#我的使用体验"><span>#</span></a></h2><p>前几天我部署了 COCO音乐下载站，使用体验真的很棒：</p><ol>
<li>界面简洁美观，操作流畅</li>
<li>搜索功能强大，能找到很多平台的音乐</li>
<li>在线试听功能很实用，可以确认歌曲是否正确</li>
<li>批量下载功能节省了我很多时间</li>
<li>暗黑模式看起来很舒服，眼睛不累</li>
</ol><p>我用它下载了一些喜欢的歌曲，音质很好，有些还支持无损格式，太香了！</p></section>
<section><h2>与洛雪音乐、MusicFree 配合使用<a href="#与洛雪音乐musicfree-配合使用"><span>#</span></a></h2><p>COCO音乐下载站可以和洛雪音乐、MusicFree 完美配合：</p><ol>
<li>用 COCO音乐下载站下载你喜欢的音乐</li>
<li>将下载的音乐导入到洛雪音乐或 MusicFree 中</li>
<li>在洛雪音乐或 MusicFree 中享受无广告的音乐体验</li>
</ol><p>这样，你就拥有了一个完整的音乐生态系统，既能下载音乐，又能无广告播放！</p></section>
<section><h2>适合谁用？<a href="#适合谁用"><span>#</span></a></h2><ul>
<li><strong>音乐爱好者</strong>：想下载喜欢的音乐保存</li>
<li><strong>音质追求党</strong>：想要无损音质的音乐</li>
<li><strong>收集控</strong>：喜欢收集各种音乐</li>
<li><strong>podcast 爱好者</strong>：下载 podcast 离线收听</li>
<li><strong>任何人</strong>：需要下载音乐的人</li>
</ul></section>
<section><h2>互动时间<a href="#互动时间"><span>#</span></a></h2><p>你们平时都是怎么下载音乐的？遇到过什么困扰？用了 COCO音乐下载站后有什么感受？欢迎在评论区分享你的故事！</p><p>如果你有任何关于部署或使用的问题，也可以在评论区留言，我会尽力回答！</p></section>
<section><h2>项目地址<a href="#项目地址"><span>#</span></a></h2><ul>
<li><strong>GitHub 仓库</strong>：<a href="https://github.com/markcxx/coco-downloader" target="_blank">https://github.com/markcxx/coco-downloader</a></li>
<li><strong>demo站</strong>：<a href="https://cocodownloader.markqq.com/" target="_blank">https://cocodownloader.markqq.com/</a></li>
</ul></section>
<section><h2>温馨提示<a href="#温馨提示"><span>#</span></a></h2><p>COCO音乐下载站仅供个人学习与技术交流使用，严禁用于任何商业用途。所有音乐资源均来源于互联网第三方网站，本项目仅提供数据聚合与检索服务，不存储任何音乐文件。</p><hr /><p><strong>推荐阅读</strong>：</p><ul>
<li><a href="http://mp.weixin.qq.com/s/-0EpStViNdKEJXPzGfVSVw?token=2046857375&amp;lang=zh_CN" target="_blank">发现宝藏音乐软件！LX Music 让你告别多 app 切换，一个软件听遍所有平台</a></li>
<li><a href="http://mp.weixin.qq.com/s/vs0eBElh1Tq9AbbVd126WA?token=2046857375&amp;lang=zh_CN" target="_blank">LX Sync Server 部署指南：轻松搭建自己的洛雪音乐服务</a></li>
</ul><p>（注：文章部分信息来源于项目官方文档和个人使用体验）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/e047a4b0/</id>
      <title type="text">【小说】阅读APP</title>
      <published>2024-10-29T20:31:13.000Z</published>
      <updated>2024-10-29T20:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/e047a4b0/"/>
      <summary type="text">“阅读APP”，一个专为安卓平台设计的小说阅读应用。该应用支持自定义书源和规则，用户可以轻松抓取网页数据，方便找书和看书。软件提供高度自定义的阅读界面，包括字体、颜色、背景、行距、段距等设置，并支持替换净化功能，去除广告。此外，还支持本地TXT和EPUB阅读，多种翻页模式供用户选择。</summary>
      <content type="html"><![CDATA[<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/10/202410300947397.png" alt="图片" /><figcaption>图片</figcaption></figure><p></p>
<blockquote><p>简介
【阅读APP】，一个专为安卓平台设计的小说阅读应用。该应用支持自定义书源和规则，用户可以轻松抓取网页数据，方便找书和看书。软件提供高度自定义的阅读界面，包括字体、颜色、背景、行距、段距等设置，并支持替换净化功能，去除广告。此外，还支持本地TXT和EPUB阅读，多种翻页模式供用户选择。文章提供了开源地址、书源订阅源和官方下载链接，帮助用户更好地使用该应用。
平台：</p></blockquote>
<ul>
<li>安卓</li>
</ul>
<p>类型：</p>
<ul>
<li>小说</li>
</ul>
<blockquote><p>阅读</p></blockquote>
<ol>
<li>
<p>自定义书源，自己设置规则，抓取网页数据，规则简单易懂，软件内有规则说明</p>
</li>
<li>
<p>书源规则支持搜索及发现，所有找书看书功能全部自定义，找书更方便</p>
</li>
<li>
<p>支持高度自定义阅读界面，切换字体、颜色、背景、行距、段距、加粗、简繁转换等</p>
</li>
<li>
<p>支持替换净化，去除广告替换内容很方便</p>
</li>
<li>
<p>支持本地TXT、EPUB阅读，手动浏览，智能扫描</p>
</li>
<li>
<p>支持多种翻页模式，覆盖、仿真、滑动、滚动等</p>
</li>
</ol>
<blockquote><p>相关链接</p></blockquote>
<ul>
<li>
<p><a href="https://github.com/gedoor/legado" target="_blank">阅读APP开源地址</a></p>
</li>
<li>
<p><a href="https://dy.mgz6.cc/" target="_blank">喵公子-喵公子订阅源</a></p>
</li>
<li>
<p><a href="https://www.gitlink.org.cn/yi-c/yd/tree/master/README.md" target="_blank">一程的书源，RSS源，更新地址</a></p>
</li>
<li>
<p><a href="https://legado.aoaostar.com/" target="_blank">「阅读」APP 源</a></p>
</li>
<li>
<p><a href="https://yckceo.vip/" target="_blank">源仓库发布页（防走丢）</a></p>
</li>
<li>
<p><a href="https://www.yuque.com/legado/wiki/pgk7m1" target="_blank"><strong>使用说明（必看）</strong></a></p>
</li>
</ul>
<blockquote><p>APP下载</p></blockquote>
<ul>
<li>
<p><a href="https://github.com/gedoor/legado/releases" target="_blank">官方下载地址</a></p>
</li>
<li>
<p><a href="https://www.coolapk.com/apk/256030" target="_blank">酷安下载地址</a></p>
</li>
</ul>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/7b05deaf/</id>
      <title type="text">记录Dotnet6中使用Redis共享Session的实现</title>
      <published>2024-10-23T12:32:13.000Z</published>
      <updated>2024-10-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/7b05deaf/"/>
      <summary type="text">如何在Dotnet 6项目中使用Redis实现Session的共享。在多服务器环境下，由于Session默认存储在内存中导致的会话信息丢失问题。通过安装必要的NuGet包、修改startup.cs或Program.cs文件以配置Redis作为Session存储的步骤，可以有效解决Session共享问题</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>因项目中实际需要，需要对dotnet服务做横向扩展，但是Session默认存储在<code>MemoryCache</code>中，无法实现多台服务器共享<code>Session</code>,导致通过<code>nginx</code>做负载均衡后出现跳登录的情况，因此需要使用Redis共享Session解决此问题。</p></section>
<section><h2>实现<a href="#实现"><span>#</span></a></h2><section><h3>安装依赖<a href="#安装依赖"><span>#</span></a></h3><ul>
<li>Microsoft.AspNetCore.DataProtection.StackExchangeRedis 6.0.35</li>
<li>Microsoft.Extensions.Caching.StackExchangeRedis 6.0.35</li>
</ul></section><section><h3>修改startup.cs/Program.cs<a href="#修改startupcsprogramcs"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>        </span></span><span>public void ConfigureServices(IServiceCollection services)</span></div></div><div><div><div>2</div></div><div><span><span>        </span></span><span>{</span></div></div><div><div><div>3</div></div><div><span><span>            </span></span><span>// ... 其他中间件</span></div></div><div><div><div>4</div></div><div><span><span>            </span></span><span>services.AddHttpContextAccessor();</span></div></div><div><div><div>5</div></div><div><span><span>            </span></span><span>services.AddMvc().AddSessionStateTempDataProvider();</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span><span>            </span></span><span>services.AddHttpClient();</span></div></div><div><div><div>8</div></div><div><span><span>            </span></span><span>// 注入Session</span></div></div><div><div><div>9</div></div><div><span><span>            </span></span><span>services.AddSessionService("CacheProvider");</span></div></div><div><div><div>10</div></div><div><span><span>            </span></span><span>// 使用Redis作为系统缓存</span></div></div><div><div><div>11</div></div><div><span><span>            </span></span><span>services.AddCacheService("CacheProvider");</span></div></div><div><div><div>12</div></div><div><span><span>            </span></span><span>services.AddControllersWithViews(ConfigureMvcOptions)</span></div></div><div><div><div>13</div></div><div><span><span>                </span></span><span>.AddNewtonsoftJson(options =&gt;</span></div></div><div><div><div>14</div></div><div><span><span>                </span></span><span>{</span></div></div><div><div><div>15</div></div><div><span><span>                    </span></span><span>options.UseMemberCasing();</span></div></div><div><div><div>16</div></div><div><span><span>                    </span></span><span>// 格式化时间</span></div></div><div><div><div>17</div></div><div><span><span>                    </span></span><span>options.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;</span></div></div><div><div><div>18</div></div><div><span><span>                </span></span><span>});</span></div></div><div><div><div>19</div></div><div><span><span>            </span></span><span>// ... 其他中间件</span></div></div><div><div><div>20</div></div><div><span><span>        </span></span><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><blockquote><p>services.AddSessionService(“CacheProvider”) 的实现方法</p></blockquote><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>public static void AddSessionService(this IServiceCollection services, string key)</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>{</span></div></div><div><div><div>3</div></div><div><span><span>     </span></span><span>using (ServiceProvider provider = services.BuildServiceProvider())</span></div></div><div><div><div>4</div></div><div><span><span>     </span></span><span>{</span></div></div><div><div><div>5</div></div><div><span><span>         </span></span><span>IConfiguration configuration = provider.GetRequiredService&lt;IConfiguration&gt;();</span></div></div><div><div><div>6</div></div><div><span><span>         </span></span><span>if (configuration == null)</span></div></div><div><div><div>7</div></div><div><span><span>         </span></span><span>{</span></div></div><div><div><div>8</div></div><div><span><span>             </span></span><span>throw new ArgumentNullException(nameof(IConfiguration));</span></div></div><div><div><div>9</div></div><div><span><span>         </span></span><span>}</span></div></div><div><div><div>10</div></div><div><span><span>         </span></span><span>IConfigurationSection section = configuration.GetSection(key);</span></div></div><div><div><div>11</div></div><div><span><span>         </span></span><span>if (!section.Exists())</span></div></div><div><div><div>12</div></div><div><span><span>         </span></span><span>{</span></div></div><div><div><div>13</div></div><div><span><span>             </span></span><span>Console.WriteLine($"appsetting.json 文件中不存在 '{key}' 配置项，如需使用redis缓存，请增加此配置。将使用系统缓存。");</span></div></div><div><div><div>14</div></div><div><span><span>         </span></span><span>}</span></div></div><div><div><div>15</div></div><div><span><span>         </span></span><span>CacheOptions options = section.Get&lt;CacheOptions&gt;();</span></div></div><div><div><div>16</div></div><div><span><span>         </span></span><span>if (options == null)</span></div></div><div><div><div>17</div></div><div><span><span>         </span></span><span>{</span></div></div><div><div><div>18</div></div><div><span><span>             </span></span><span>Console.WriteLine($"读取appsetting.json中'{key}'配置项失败，请正确配置。将使用系统缓存");</span></div></div><div><div><div>19</div></div><div><span><span>         </span></span><span>}</span></div></div><div><div><div>20</div></div><div>
</div></div><div><div><div>21</div></div><div><span><span>         </span></span><span>if (options?.CacheType == CacheTypeEnum.Redis.ToString())</span></div></div><div><div><div>22</div></div><div><span><span>         </span></span><span>{</span></div></div><div><div><div>23</div></div><div><span><span>             </span></span><span>Console.WriteLine($"将使用Redis缓存Session信息");</span></div></div><div><div><div>24</div></div><div>
</div></div><div><div><div>25</div></div><div><span><span>             </span></span><span>var connStr = options.RedisConnectionString;</span></div></div><div><div><div>26</div></div><div><span><span>             </span></span><span>var dic =</span></div></div><div><div><div>27</div></div><div><span><span>                 </span></span><span>connStr.Contains(',') &amp;&amp; !connStr.Contains(';') ?</span></div></div><div><div><div>28</div></div><div><span><span>                     </span></span><span>connStr.SplitAsDictionary("=", ",", true) :</span></div></div><div><div><div>29</div></div><div><span><span>                     </span></span><span>connStr.SplitAsDictionary("=", ";", true);</span></div></div><div><div><div>30</div></div><div>
</div></div><div><div><div>31</div></div><div><span><span>             </span></span><span>var Server = dic["Server"]?.Trim();</span></div></div><div><div><div>32</div></div><div><span><span>             </span></span><span>var UserName = dic["UserName"]?.Trim();</span></div></div><div><div><div>33</div></div><div><span><span>             </span></span><span>var Password = dic["Password"]?.Trim();</span></div></div><div><div><div>34</div></div><div>
</div></div><div><div><div>35</div></div><div><span><span>             </span></span><span>#region 配置说明</span></div></div><div><div><div>36</div></div><div>
</div></div><div><div><div>37</div></div><div><span><span>             </span></span><span>// var options = new ConfigurationOptions</span></div></div><div><div><div>38</div></div><div><span><span>             </span></span><span>// {</span></div></div><div><div><div>39</div></div><div><span><span>             </span></span><span>//     AbortOnConnectFail = false, // 连接失败时是否中止</span></div></div><div><div><div>40</div></div><div><span><span>             </span></span><span>//     AllowAdmin = false, // 是否允许使用管理命令</span></div></div><div><div><div>41</div></div><div><span><span>             </span></span><span>//     ConnectTimeout = 5000, // 连接超时时间（毫秒）</span></div></div><div><div><div>42</div></div><div><span><span>             </span></span><span>//     SyncTimeout = 5000, // 同步操作超时时间（毫秒）</span></div></div><div><div><div>43</div></div><div><span><span>             </span></span><span>//     ResponseTimeout = 5000, // 响应超时时间（毫秒）</span></div></div><div><div><div>44</div></div><div><span><span>             </span></span><span>//     ReconnectRetryPolicy = new LinearRetry(1000), // 重连策略</span></div></div><div><div><div>45</div></div><div><span><span>             </span></span><span>//     DefaultDatabase = 0, // 默认数据库索引</span></div></div><div><div><div>46</div></div><div><span><span>             </span></span><span>//     EndPoints = { "localhost:6379" }, // Redis节点的地址和端口</span></div></div><div><div><div>47</div></div><div><span><span>             </span></span><span>//     Ssl = false, // 是否使用SSL加密连接</span></div></div><div><div><div>48</div></div><div><span><span>             </span></span><span>//     SslHost = "localhost", // SSL连接时的主机名验证</span></div></div><div><div><div>49</div></div><div><span><span>             </span></span><span>//     Password = "yourpassword", // Redis认证密码</span></div></div><div><div><div>50</div></div><div><span><span>             </span></span><span>//     ClientName = "MyClient", // 客户端名称</span></div></div><div><div><div>51</div></div><div><span><span>             </span></span><span>//     KeepAlive = 1800000 // 保持连接间隔时间（毫秒）</span></div></div><div><div><div>52</div></div><div><span><span>             </span></span><span>// };</span></div></div><div><div><div>53</div></div><div><span><span>             </span></span><span>#endregion</span></div></div><div><div><div>54</div></div><div>
</div></div><div><div><div>55</div></div><div><span><span>             </span></span><span>//获取Redis 连接字符串</span></div></div><div><div><div>56</div></div><div><span><span>             </span></span><span>ConfigurationOptions redisConfigOption = new ConfigurationOptions();</span></div></div><div><div><div>57</div></div><div><span><span>             </span></span><span>redisConfigOption.EndPoints.Add(Server);</span></div></div><div><div><div>58</div></div><div><span><span>             </span></span><span>redisConfigOption.AllowAdmin = false;</span></div></div><div><div><div>59</div></div><div><span><span>             </span></span><span>redisConfigOption.Password = Password;</span></div></div><div><div><div>60</div></div><div><span><span>             </span></span><span>redisConfigOption.ConnectTimeout = 60000;</span></div></div><div><div><div>61</div></div><div><span><span>             </span></span><span>redisConfigOption.ResponseTimeout = 60000;</span></div></div><div><div><div>62</div></div><div><span><span>             </span></span><span>redisConfigOption.SyncTimeout = 60000;</span></div></div><div><div><div>63</div></div><div><span><span>             </span></span><span>redisConfigOption.ReconnectRetryPolicy = new LinearRetry(1000);// 重连策略</span></div></div><div><div><div>64</div></div><div><span><span>             </span></span><span>var redis = ConnectionMultiplexer.Connect(redisConfigOption);//建立Redis 连接</span></div></div><div><div><div>65</div></div><div>
</div></div><div><div><div>66</div></div><div><span><span>             </span></span><span>//添加数据保护服务，设置统一应用程序名称，并指定使用Reids存储私钥</span></div></div><div><div><div>67</div></div><div><span><span>             </span></span><span>services.AddDataProtection()</span></div></div><div><div><div>68</div></div><div><span><span>                 </span></span><span>.SetApplicationName("YZ")</span></div></div><div><div><div>69</div></div><div><span><span>                 </span></span><span>.PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys");</span></div></div><div><div><div>70</div></div><div>
</div></div><div><div><div>71</div></div><div><span><span>             </span></span><span>//添加Redis缓存用于分布式Session</span></div></div><div><div><div>72</div></div><div><span><span>             </span></span><span>services.AddStackExchangeRedisCache(options =&gt;</span></div></div><div><div><div>73</div></div><div><span><span>             </span></span><span>{</span></div></div><div><div><div>74</div></div><div><span><span>                 </span></span><span>options.ConfigurationOptions = redisConfigOption;</span></div></div><div><div><div>75</div></div><div><span><span>                 </span></span><span>options.InstanceName = "YZ";</span></div></div><div><div><div>76</div></div><div><span><span>             </span></span><span>});</span></div></div><div><div><div>77</div></div><div><span><span>         </span></span><span>}</span></div></div><div><div><div>78</div></div><div><span><span>         </span></span><span>//添加Session</span></div></div><div><div><div>79</div></div><div><span><span>         </span></span><span>services.AddSession(options =&gt;</span></div></div><div><div><div>80</div></div><div><span><span>         </span></span><span>{</span></div></div><div><div><div>81</div></div><div><span><span>             </span></span><span>options.Cookie.Name = "YZ";</span></div></div><div><div><div>82</div></div><div><span><span>             </span></span><span>options.IdleTimeout = TimeSpan.FromMinutes(60 * 60); //设置session的过期时间</span></div></div><div><div><div>83</div></div><div><span><span>             </span></span><span>options.Cookie.HttpOnly = true; //设置在浏览器不能通过js获得该cookie的值</span></div></div><div><div><div>84</div></div><div><span><span>             </span></span><span>options.Cookie.IsEssential = true;</span></div></div><div><div><div>85</div></div><div><span><span>         </span></span><span>});</span></div></div><div><div><div>86</div></div><div>
</div></div><div><div><div>87</div></div><div><span><span>     </span></span><span>}</span></div></div><div><div><div>88</div></div><div><span><span> </span></span><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><blockquote><p>services.AddCacheService(“CacheProvider”); 实现方法</p></blockquote><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>    </span></span><span>/// &lt;summary&gt;</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>/// 缓存注册（新生命Redis组件）</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>/// &lt;/summary&gt;</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>/// &lt;param name="services"&gt;&lt;/param&gt;</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>public static void AddCacheService(this IServiceCollection services, string key)</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>7</div></div><div><span><span>        </span></span><span>using (ServiceProvider provider = services.BuildServiceProvider())</span></div></div><div><div><div>8</div></div><div><span><span>        </span></span><span>{</span></div></div><div><div><div>9</div></div><div><span><span>            </span></span><span>ICache cache = NewLife.Caching.Cache.Default;</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span><span>            </span></span><span>IConfiguration configuration = provider.GetRequiredService&lt;IConfiguration&gt;();</span></div></div><div><div><div>12</div></div><div><span><span>            </span></span><span>if (configuration == null)</span></div></div><div><div><div>13</div></div><div><span><span>            </span></span><span>{</span></div></div><div><div><div>14</div></div><div><span><span>                </span></span><span>throw new ArgumentNullException(nameof(IConfiguration));</span></div></div><div><div><div>15</div></div><div><span><span>            </span></span><span>}</span></div></div><div><div><div>16</div></div><div><span><span>            </span></span><span>IConfigurationSection section = configuration.GetSection(key);</span></div></div><div><div><div>17</div></div><div><span><span>            </span></span><span>if (!section.Exists())</span></div></div><div><div><div>18</div></div><div><span><span>            </span></span><span>{</span></div></div><div><div><div>19</div></div><div><span><span>                </span></span><span>Console.WriteLine($"appsetting.json 文件中不存在 '{key}' 配置项，如需使用redis缓存，请增加此配置。将使用系统缓存。");</span></div></div><div><div><div>20</div></div><div><span><span>            </span></span><span>}</span></div></div><div><div><div>21</div></div><div><span><span>            </span></span><span>CacheOptions options = section.Get&lt;CacheOptions&gt;();</span></div></div><div><div><div>22</div></div><div><span><span>            </span></span><span>if (options == null)</span></div></div><div><div><div>23</div></div><div><span><span>            </span></span><span>{</span></div></div><div><div><div>24</div></div><div><span><span>                </span></span><span>Console.WriteLine($"读取appsetting.json中'{key}'配置项失败，请正确配置。将使用系统缓存");</span></div></div><div><div><div>25</div></div><div><span><span>            </span></span><span>}</span></div></div><div><div><div>26</div></div><div>
</div></div><div><div><div>27</div></div><div><span><span>            </span></span><span>if (options?.CacheType == CacheTypeEnum.Redis.ToString())</span></div></div><div><div><div>28</div></div><div><span><span>            </span></span><span>{</span></div></div><div><div><div>29</div></div><div><span><span>                </span></span><span>Console.WriteLine($"将使用Redis缓存");</span></div></div><div><div><div>30</div></div><div><span><span>                </span></span><span>var redis = new FullRedis();</span></div></div><div><div><div>31</div></div><div><span><span>                </span></span><span>redis.Init(options.RedisConnectionString);</span></div></div><div><div><div>32</div></div><div><span><span>                </span></span><span>cache = redis;</span></div></div><div><div><div>33</div></div><div>
</div></div><div><div><div>34</div></div><div><span><span>            </span></span><span>}</span></div></div><div><div><div>35</div></div><div>
</div></div><div><div><div>36</div></div><div><span><span>            </span></span><span>services.AddSingleton(cache);</span></div></div><div><div><div>37</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>38</div></div><div><span><span>    </span></span><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><blockquote><p>按照以上的配置，就可以实现使用redis共享Session了。</p></blockquote></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/ee64e7e7/</id>
      <title type="text">.NET 开发者必备：全面整理常用 dotnet 命令</title>
      <published>2024-10-23T12:32:13.000Z</published>
      <updated>2024-10-23T12:32:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/ee64e7e7/"/>
      <summary type="text">作为 .NET 开发者，你是否经常需要查找命令行指令？本文为你整理了开发过程中最常用的 `dotnet` 命令，涵盖项目创建、构建、测试、部署等多个方面，助你提升开发效率！</summary>
      <content type="html"><![CDATA[<p>作为 .NET 开发者，你是否经常需要查找命令行指令？本文为你整理了开发过程中最常用的 <code>dotnet</code> 命令，涵盖项目创建、构建、测试、部署等多个方面，助你提升开发效率！</p>
<hr />
<section><h2>重要的操作命令<a href="#重要的操作命令"><span>#</span></a></h2><p>一些常用的命名</p><section><h3>创建并添加项目到解决方案<a href="#创建并添加项目到解决方案"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 创建 Web API 项目</span></div></div><div><div><div>2</div></div><div><span>dotnet</span><span> </span><span>new</span><span> </span><span>webapi</span><span> </span><span>-o</span><span> </span><span>MyWebApi</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 创建空解决方案</span></div></div><div><div><div>5</div></div><div><span>dotnet</span><span> </span><span>new</span><span> </span><span>sln</span><span> </span><span>-o</span><span> </span><span>MySolution</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 进入解决方案目录</span></div></div><div><div><div>8</div></div><div><span>cd</span><span> </span><span>MySolution</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 将 Web API 项目添加到解决方案中</span></div></div><div><div><div>11</div></div><div><span>dotnet</span><span> </span><span>sln</span><span> </span><span>add</span><span> </span><span>../MyWebApi/MyWebApi.csproj</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>发布为独立部署应用（带运行时）<a href="#发布为独立部署应用带运行时"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 发布 Web API 项目，配置为 Release，平台为 win-x64，且自带运行时</span></div></div><div><div><div>2</div></div><div><span>dotnet</span><span> </span><span>publish</span><span> </span><span>../MyWebApi/MyWebApi.csproj</span><span> </span><span>-c</span><span> </span><span>Release</span><span> </span><span>-r</span><span> </span><span>win-x64</span><span> </span><span>--self-contained</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>查看 SDK 和运行时信息<a href="#查看-sdk-和运行时信息"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 查看所有已安装的 .NET SDK 版本</span></div></div><div><div><div>2</div></div><div><span>dotnet</span><span> </span><span>--list-sdks</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 查看所有已安装的 .NET 运行时版本</span></div></div><div><div><div>5</div></div><div><span>dotnet</span><span> </span><span>--list-runtimes</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>运行命令<a href="#运行命令"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 指定运行环境为 Development / Production</span></div></div><div><div><div>2</div></div><div><span>dotnet</span><span> </span><span>run</span><span> </span><span>--environment</span><span> </span><span>Development</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 指定监听地址（适用于 ASP.NET Core）</span></div></div><div><div><div>5</div></div><div><span>dotnet</span><span> </span><span>run</span><span> </span><span>--urls</span><span> </span><span>"http://*:5000;https://localhost:5001"</span></div></div><div><div><div>6</div></div><div><span>#localhost:5000 表示仅本机访问。</span></div></div><div><div><div>7</div></div><div><span># 0.0.0.0:5001 表示允许外部机器通过 IP 访问。 Ubantu使用添加</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span># 运行指定项目的代码（不切换目录）</span></div></div><div><div><div>10</div></div><div><span>dotnet</span><span> </span><span>run</span><span> </span><span>-p</span><span> </span><span>../MyWebApi/MyWebApi.csproj</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span># 显示详细构建日志输出</span></div></div><div><div><div>13</div></div><div><span>dotnet</span><span> </span><span>run</span><span> </span><span>--verbosity</span><span> </span><span>detailed</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>📁 一、项目与解决方案管理<a href="#-一项目与解决方案管理"><span>#</span></a></h2><section><h3>✅ 创建新项目<a href="#-创建新项目"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 创建控制台应用程序</span></div></div><div><div><div>2</div></div><div><span>dotnet</span><span> </span><span>new</span><span> </span><span>console</span><span> </span><span>-o</span><span> </span><span>MyConsoleApp</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 创建类库项目（Class Library）</span></div></div><div><div><div>5</div></div><div><span>dotnet</span><span> </span><span>new</span><span> </span><span>classlib</span><span> </span><span>-o</span><span> </span><span>MyLibrary</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 创建 ASP.NET Core Web API 项目</span></div></div><div><div><div>8</div></div><div><span>dotnet</span><span> </span><span>new</span><span> </span><span>webapi</span><span> </span><span>-o</span><span> </span><span>MyWebApi</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 创建 Blazor Server 项目</span></div></div><div><div><div>11</div></div><div><span>dotnet</span><span> </span><span>new</span><span> </span><span>blazorserver</span><span> </span><span>-o</span><span> </span><span>MyBlazorApp</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>📂 管理解决方案（.sln）<a href="#-管理解决方案sln"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 创建一个新的解决方案文件</span></div></div><div><div><div>2</div></div><div><span>dotnet</span><span> </span><span>new</span><span> </span><span>sln</span><span> </span><span>-o</span><span> </span><span>MySolution</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 将项目添加到解决方案中</span></div></div><div><div><div>5</div></div><div><span>dotnet</span><span> </span><span>sln</span><span> </span><span>add</span><span> </span><span>MyProject.csproj</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 从解决方案中移除项目</span></div></div><div><div><div>8</div></div><div><span>dotnet</span><span> </span><span>sln</span><span> </span><span>remove</span><span> </span><span>MyProject.csproj</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 查看当前解决方案包含的所有项目</span></div></div><div><div><div>11</div></div><div><span>dotnet</span><span> </span><span>sln</span><span> </span><span>list</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section>
<section><h2>⚙️ 二、构建与运行项目<a href="#️-二构建与运行项目"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 恢复所有 NuGet 包依赖项</span></div></div><div><div><div>2</div></div><div><span>dotnet</span><span> </span><span>restore</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 构建项目，默认是 Debug 配置</span></div></div><div><div><div>5</div></div><div><span>dotnet</span><span> </span><span>build</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 构建发布版本（Release）</span></div></div><div><div><div>8</div></div><div><span>dotnet</span><span> </span><span>build</span><span> </span><span>--configuration</span><span> </span><span>Release</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 运行项目（自动先构建再运行）</span></div></div><div><div><div>11</div></div><div><span>dotnet</span><span> </span><span>run</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section>
<section><h2>📦 三、发布应用程序<a href="#-三发布应用程序"><span>#</span></a></h2><p>你可以选择发布为<strong>独立部署（Self-contained）<strong>或</strong>框架依赖（Framework-dependent）</strong>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 发布为独立部署应用（包含运行时），适用于目标机器无 .NET 安装的情况</span></div></div><div><div><div>2</div></div><div><span>dotnet</span><span> </span><span>publish</span><span> </span><span>-r</span><span> </span><span>win-x64</span><span> </span><span>--self-contained</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 发布为框架依赖应用（需目标机器安装对应 .NET 运行时）</span></div></div><div><div><div>5</div></div><div><span>dotnet</span><span> </span><span>publish</span><span> </span><span>-r</span><span> </span><span>win-x64</span><span> </span><span>--framework-dependent</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section>
<section><h2>🧪 四、测试与维护<a href="#-四测试与维护"><span>#</span></a></h2><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 运行项目中的所有单元测试</span></div></div><div><div><div>2</div></div><div><span>dotnet</span><span> </span><span>test</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 只运行指定名称的测试方法/类</span></div></div><div><div><div>5</div></div><div><span>dotnet</span><span> </span><span>test</span><span> </span><span>--filter</span><span> </span><span>MyTest</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 列出当前项目直接引用的 NuGet 包</span></div></div><div><div><div>8</div></div><div><span>dotnet</span><span> </span><span>list</span><span> </span><span>package</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 列出包括传递依赖在内的所有包信息</span></div></div><div><div><div>11</div></div><div><span>dotnet</span><span> </span><span>list</span><span> </span><span>package</span><span> </span><span>--include-transitive</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># 添加一个 NuGet 包引用</span></div></div><div><div><div>14</div></div><div><span>dotnet</span><span> </span><span>add</span><span> </span><span>package</span><span> </span><span>Newtonsoft.Json</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span># 移除一个 NuGet 包引用</span></div></div><div><div><div>17</div></div><div><span>dotnet</span><span> </span><span>remove</span><span> </span><span>package</span><span> </span><span>Newtonsoft.Json</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span># 添加对本地项目的引用（如类库）</span></div></div><div><div><div>20</div></div><div><span>dotnet</span><span> </span><span>add</span><span> </span><span>reference</span><span> </span><span>../MyLib/MyLib.csproj</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><hr /></section>
<section><h2>🧰 五、SDK 与环境信息<a href="#-五sdk-与环境信息"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 显示当前默认使用的 SDK 和运行时详细信息</span></div></div><div><div><div>2</div></div><div><span>dotnet</span><span> </span><span>--info</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 列出系统中已安装的所有 .NET SDK 版本</span></div></div><div><div><div>5</div></div><div><span>dotnet</span><span> </span><span>--list-sdks</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 列出系统中已安装的所有 .NET 运行时版本</span></div></div><div><div><div>8</div></div><div><span>dotnet</span><span> </span><span>--list-runtimes</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 显示 dotnet CLI 的帮助信息</span></div></div><div><div><div>11</div></div><div><span>dotnet</span><span> </span><span>help</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># 使用指定版本的 SDK 执行某个命令（例如使用 6.0.100）</span></div></div><div><div><div>14</div></div><div><span>dotnet</span><span> </span><span>--sdk-version</span><span> </span><span>6.0.100</span><span> </span><span>build</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section>
<section><h2>📦 六、NuGet 包管理<a href="#-六nuget-包管理"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 恢复所有 NuGet 包（等价于 restore）</span></div></div><div><div><div>2</div></div><div><span>dotnet</span><span> </span><span>restore</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 清除本地 NuGet 缓存（解决缓存导致的问题）</span></div></div><div><div><div>5</div></div><div><span>dotnet</span><span> </span><span>nuget</span><span> </span><span>locals</span><span> </span><span>all</span><span> </span><span>--clear</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 将项目打包成 .nupkg 文件（用于私有或公共 NuGet 源发布）</span></div></div><div><div><div>8</div></div><div><span>dotnet</span><span> </span><span>pack</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 将 NuGet 包推送到指定源（如 nuget.org）</span></div></div><div><div><div>11</div></div><div><span>dotnet</span><span> </span><span>nuget</span><span> </span><span>push</span><span> </span><span>MyPackage.nupkg</span><span> </span><span>--source</span><span> </span><span>https://api.nuget.org/v3/index.json</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section>
<section><h2>🔧 七、其他实用命令<a href="#-七其他实用命令"><span>#</span></a></h2><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 调用 MSBuild 并执行自定义目标（Target）</span></div></div><div><div><div>2</div></div><div><span>dotnet</span><span> </span><span>msbuild</span><span> </span><span>/t:CustomTarget</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 查看详细的构建日志输出（用于调试构建问题）</span></div></div><div><div><div>5</div></div><div><span>dotnet</span><span> </span><span>build</span><span> </span><span>--verbosity</span><span> </span><span>detailed</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 启动 .NET Interactive 工具（支持 C# 即时执行和 Jupyter Notebook）</span></div></div><div><div><div>8</div></div><div><span>dotnet</span><span> </span><span>interactive</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 查看构建性能摘要（优化构建耗时）</span></div></div><div><div><div>11</div></div><div><span>dotnet</span><span> </span><span>build</span><span> </span><span>--performance-summary</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># 使用本地安装的 dotnet tool</span></div></div><div><div><div>14</div></div><div><span>dotnet</span><span> </span><span>tool</span><span> </span><span>run</span><span> </span><span>&lt;tool-name&gt;</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span># 启用源码链接调试（调试 NuGet 包时跳转 GitHub）</span></div></div><div><div><div>17</div></div><div><span>dotnet</span><span> </span><span>run</span><span> </span><span>--sourceLink</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><hr /></section>
<section><h2>🧪 八、调试与性能分析相关命令<a href="#-八调试与性能分析相关命令"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 启用 AOT 编译（.NET 7+ 功能）</span></div></div><div><div><div>2</div></div><div><span>dotnet</span><span> </span><span>run</span><span> </span><span>--aot</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 收集内存使用情况（用于 PerfView 分析）</span></div></div><div><div><div>5</div></div><div><span>dotnet</span><span> </span><span>run</span><span> </span><span>--collect:Memory</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 启用单文件发布并运行（.NET 6+）</span></div></div><div><div><div>8</div></div><div><span>dotnet</span><span> </span><span>publish</span><span> </span><span>-r</span><span> </span><span>win-x64</span><span> </span><span>--self-contained</span><span> </span><span>-p:PublishSingleFile=true</span></div></div><div><div><div>9</div></div><div><span>dotnet</span><span> </span><span>run</span><span> </span><span>--no-build</span><span> </span><span>--framework</span><span> </span><span>net6.0</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /><hr /><p><strong>如果你觉得这篇文章对你有帮助，欢迎点赞、收藏并分享给更多开发者！让我们一起学习，共同进步！</strong></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/a473e677/</id>
      <title type="text">集群环境下，你不得不注意的ASP.NET Core Data Protection 机制</title>
      <published>2024-10-23T12:31:13.000Z</published>
      <updated>2024-10-23T12:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/a473e677/"/>
      <summary type="text">在集群环境中使用ASP.NET Core时遇到的数据保护问题。在单个容器中正常运行的Web应用，在扩展到多个容器后出现的会话信息丢失问题，并分析了其根本原因在于每个容器生成的私钥不同。提供了使用Redis作为存储介质来实现私钥共享的具体步骤，包括添加必要的NuGet包和配置数据保护服务及分布式Session的方法</summary>
      <content type="html"><![CDATA[<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>最近线上环境遇到一个问题，就是ASP.NET Core Web应用在单个容器使用正常，扩展多个容器无法访问的问题。查看容器日志，发现以下异常：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>warn</span><span>: </span><span>Microsoft</span><span>.</span><span>AspNetCore</span><span>.</span><span>Session</span><span>.</span><span>SessionMiddleware</span><span>[</span></span><span>7</span><span><span>] </span><span>Error</span><span> </span><span>unprotecting</span><span> </span><span>the</span><span> </span><span>session</span><span> </span><span>cookie</span><span>. </span><span>System</span><span>.</span><span>Security</span><span>.</span><span>Cryptography</span><span>.</span><span>CryptographicException</span><span>: </span><span>The</span><span> </span><span>key</span><span> {</span></span><span>3b046482</span><span>-</span><span>7cff</span><span>-</span><span>475b</span><span><span>-</span><span>b252</span><span>-</span><span>d12ab389d6c3</span><span>} </span><span>was</span><span> </span><span>not</span><span> </span><span>found</span><span> </span><span>in</span><span> </span><span>the</span><span> </span><span>key</span><span> </span><span>ring</span><span>. </span><span>For</span><span> </span><span>more</span><span> </span><span>information</span><span> </span><span>go</span><span> </span><span>to</span><span> </span><span>http</span><span>:</span></span><span>//aka.ms/dataprotectionwarning at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus&amp; status) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean&amp; requiresMigration, Boolean&amp; wasRevoked) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData) at Microsoft.AspNetCore.Session.CookieProtection.Unprotect(IDataProtector protector, String protectedText, ILogger logger)</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>通过排查，发现了是由于 <a href="https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/introduction?view=aspnetcore-3.0" target="_blank">ASP.NET Core Data Protection</a> 机制引起的。</p></section>
<section><h2>ASP.NET Core Data Protection 机制<a href="#aspnet-core-data-protection-机制"><span>#</span></a></h2><blockquote><p>Data Protection（数据安全）机制：为了确保Web应用敏感数据的安全存储，该机制提供了一个简单、基于非对称加密改进的、性能良好的、开箱即用的加密API用于数据保护。
它不需要开发人员自行生成密钥，它会根据当前应用的运行环境，生成该应用独有的一个私钥。这在单一部署的情况下没有问题。
一旦在集群环境下进行水平扩展，那么每个独立的应用都有一个独立的私钥。这样在负载均衡时，一个请求先在A容器建立的Session会话，该机制会通过当前容器的密钥加密Cookie写入到客户端，下个请求路由到B容器，携带的Cookie在B容器是无法通过B容器的密钥进行解密。
进而会导致会话信息丢失的问题。所以<strong>在集群情况下，为了确保加密数据的互通，应用必须共享私钥</strong>。</p></blockquote></section>
<section><h2>私钥共享<a href="#私钥共享"><span>#</span></a></h2><p>这里以使用Redis来共享私钥举例，添加<code>Microsoft.AspNetCore.DataProtection.StackExchangeRedis</code> Nuget包用于存储密钥。
添加<code>Microsoft.Extensions.Caching.StackExchangeRedis</code>Nuget包用于配置分布式Session。</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>public</span><span> </span><span>IServiceProvider</span><span> </span><span>ConfigureServices</span><span>(</span><span>IServiceCollection</span><span><span> </span><span>services</span><span>)</span></span></div></div><div><div><div>2</div></div><div><span>{</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>//获取Redis 连接字符串</span></div></div><div><div><div>5</div></div><div><span>    </span><span>var</span><span><span> </span><span>redisConnStr</span><span> </span><span>=</span><span> </span></span><span>this</span><span><span>.</span><span>Configuration</span><span>.</span></span><span>GetValue</span><span>&lt;</span><span>string</span><span><span>&gt;(</span><span>SigeAppSettings</span><span>.</span><span>Redis_Endpoint</span><span>);</span></span></div></div><div><div><div>6</div></div><div><span>    </span><span>var</span><span><span> </span><span>redis</span><span> </span><span>=</span><span> </span><span>ConnectionMultiplexer</span><span>.</span></span><span>Connect</span><span><span>(</span><span>redisConnStr</span><span>);</span></span><span>//建立Redis 连接</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>//添加数据保护服务，设置统一应用程序名称，并指定使用Reids存储私钥</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>services</span><span>.</span><span>AddDataProtection</span><span>()</span></div></div><div><div><div>10</div></div><div><span><span>        </span></span><span>.</span><span>SetApplicationName</span><span><span>(</span><span>Assembly</span><span>.</span></span><span>GetExecutingAssembly</span><span><span>().</span><span>FullName</span><span>)</span></span></div></div><div><div><div>11</div></div><div><span><span>        </span></span><span>.</span><span>PersistKeysToStackExchangeRedis</span><span><span>(</span><span>redis</span><span>, </span></span><span>"DataProtection-Keys"</span><span>);</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>//添加Redis缓存用于分布式Session</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>services</span><span>.</span><span>AddStackExchangeRedisCache</span><span><span>(</span><span>options</span><span> =&gt;</span></span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>16</div></div><div><span><span>        </span></span><span>options</span><span>.</span><span>Configuration</span><span> </span><span>=</span><span> </span><span>redisConnStr</span><span>;</span></div></div><div><div><div>17</div></div><div><span><span>        </span></span><span>options</span><span>.</span><span>InstanceName</span><span> </span><span>=</span><span>Assembly</span><span>.</span><span>GetExecutingAssembly</span><span><span>().</span><span>FullName</span><span>;</span></span></div></div><div><div><div>18</div></div><div><span><span>    </span></span><span>});</span></div></div><div><div><div>19</div></div><div>
</div></div><div><div><div>20</div></div><div><span><span>    </span></span><span>//添加Session</span></div></div><div><div><div>21</div></div><div><span><span>    </span></span><span>services</span><span>.</span><span>AddSession</span><span><span>(</span><span>options</span><span> =&gt;</span></span></div></div><div><div><div>22</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>23</div></div><div><span><span>        </span></span><span>options</span><span>.</span><span>Cookie</span><span>.</span><span>Name</span><span> </span><span>=</span><span> </span><span>Assembly</span><span>.</span><span>GetExecutingAssembly</span><span><span>().</span><span>FullName</span><span>;</span></span></div></div><div><div><div>24</div></div><div><span><span>        </span></span><span>options</span><span>.</span><span>IdleTimeout</span><span> </span><span>=</span><span> </span><span>TimeSpan</span><span>.</span><span>FromMinutes</span><span>(</span><span>20</span><span>);</span><span>//设置session的过期时间</span></div></div><div><div><div>25</div></div><div><span><span>        </span></span><span>options</span><span>.</span><span>Cookie</span><span>.</span><span>HttpOnly</span><span> </span><span>=</span><span> </span><span>true</span><span>;</span><span>//设置在浏览器不能通过js获得该cookie的值</span></div></div><div><div><div>26</div></div><div><span><span>        </span></span><span>options</span><span>.</span><span>Cookie</span><span>.</span><span>IsEssential</span><span> </span><span>=</span><span> </span><span>true</span><span>;</span></div></div><div><div><div>27</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>28</div></div><div><span><span>   </span></span><span>);</span></div></div><div><div><div>29</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/100f83f6/</id>
      <title type="text">Tailscale：不用公网IP，不用配置防火墙，3分钟搞定异地组网！</title>
      <published>2024-09-09T20:31:13.000Z</published>
      <updated>2024-09-09T20:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/100f83f6/"/>
      <summary type="text">简单来说，Tailscale能让你把不同地方的设备，组成一个虚拟局域网。不管是Windows、macOS、Linux，还是iOS、ndroid、NAS，它全支持。而且，不用公网IP，不用配置路由器，不用开端口，3分钟搞定。</summary>
      <content type="html"><![CDATA[<section><h3>【前言】<a href="#前言"><span>#</span></a></h3><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/c68cbc7c0bd34bba90a5a5ead0f9f354640%3Fwx_fmt%3Dpng%26from%3Dappmsg%23imgIndex%3D0" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>兄弟们，先别急着滑走！</p><p>今天阿江要给你们安利一款<strong>内网穿透神器</strong>——<strong>Tailscale</strong>。</p><p>不是广告，不是恰饭，纯纯是我最近被它惊艳到，忍不住来分享。</p><p>如果你也和我一样，经常遇到以下情况：</p><ul>
<li>
<p>家里NAS在公司访问不了</p>
</li>
<li>
<p>远程桌面连不上</p>
</li>
<li>
<p>异地组网太复杂，公网IP、端口映射、防火墙一头雾水</p>
</li>
</ul><p>那你一定要看完这篇文章。</p><p>我敢说，<strong>Tailscale可能是2025年最被低估的网络工具之一</strong>。</p><hr /></section>
<section><h3>【一、Tailscale到底是啥？】<a href="#一tailscale到底是啥"><span>#</span></a></h3><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/7e663bdff3c04e9ebd8e88c396f582b3640%3Fwx_fmt%3Dpng%26from%3Dappmsg%23imgIndex%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>先别被它的名字吓到，Tailscale不是啥尾巴 scale，也不是宠物美容品牌。</p><p>它是一个<strong>基于WireGuard的异地组网工具</strong>，主打的就是一个“简单“。</p><p>官网地址我放这儿了，自己去看：</p><p>👉 <a href="https://tailscale.com" target="_blank">https://tailscale.com</a></p><p>简单来说，Tailscale能让你<strong>把不同地方的设备，组成一个虚拟局域网</strong>。</p><p>不管是Windows、macOS、Linux，还是iOS、Android、NAS，它全支持。</p><p>而且，<strong>不用公网IP，不用配置路由器，不用开端口，3分钟搞定</strong>。</p><hr /></section>
<section><h3>【二、3个场景，彻底被圈粉】<a href="#二3个场景彻底被圈粉"><span>#</span></a></h3><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/a197c536ecea41fbbd4eda63f4670152640%3Fwx_fmt%3Dpng%26from%3Dappmsg%23imgIndex%3D2" alt="图片" /><figcaption>图片</figcaption></figure><p></p><section><h4>✅ 场景1：公司访问家里NAS，像本地一样打开<a href="#-场景1公司访问家里nas像本地一样打开"><span>#</span></a></h4><p>我人在深圳，家里有一台群晖NAS，装了很多资料。</p><p>以前想远程访问，得搞公网IP、DDNS、端口映射，折腾一下午还不一定成功。</p><p>现在我用Tailscale，<strong>3分钟装好，直接访问192.168.x.x</strong>，像本地一样打开。</p><p><strong>不用公网IP，不用路由器设置，甚至不用重启NAS。</strong></p><p>那一刻，我真的有点感动。</p></section><section><h4>✅ 场景2：异地远程桌面，延迟低到离谱<a href="#-场景2异地远程桌面延迟低到离谱"><span>#</span></a></h4><p>我老家有台Windows主机，装了Pr和Ae。</p><p>那天我回湖南过年，临时要剪个片子。</p><p>我用Tailscale连上老家电脑，<strong>直接远程桌面开Pr</strong>，操作丝滑得像本地一样。</p><p><strong>延迟不到30ms</strong>，我甚至还能实时预览1080p素材。</p><p><strong>不用向日葵，不用TeamViewer，不用开端口。</strong></p></section><section><h4>✅ 场景3：手机远程控制树莓派，SSH秒连<a href="#-场景3手机远程控制树莓派ssh秒连"><span>#</span></a></h4><p>我在广州，树莓派放在北京朋友家，做内网监控。</p><p>以前想SSH上去，得让他帮我开端口，还经常掉线。</p><p>现在我用Tailscale，<strong>手机打开Termius，直接SSH连接</strong>，秒连。</p><p><strong>不走公网，不暴露端口，端到端加密。</strong></p><hr /></section></section>
<section><h3>【三、Tailscale凭啥这么简单？】<a href="#三tailscale凭啥这么简单"><span>#</span></a></h3><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/cf71673bc3de457cb594f9804c76cf80640%3Fwx_fmt%3Dpng%26from%3Dappmsg%23imgIndex%3D3" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>我研究了一下，Tailscale之所以能这么猛，主要靠这几招：</p><p>技术点</p><p>说人话</p><p><strong>基于WireGuard</strong></p><p>最安全、最快的VPN协议之一</p><p><strong>NAT穿透</strong></p><p>不用公网IP，也能打洞成功</p><p><strong>控制服务器中转</strong></p><p>打洞失败时，官方服务器 relay，不丢包</p><p><strong>端到端加密</strong></p><p>数据不经过第三方，隐私安全</p><p><strong>P2P直连</strong></p><p>一旦打洞成功，速度直接拉满</p><p>一句话总结：<strong>它不是VPN，它是“魔法局域网”。</strong></p><hr /></section>
<section><h3>【四、Tailscale到底适合谁？】<a href="#四tailscale到底适合谁"><span>#</span></a></h3><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/1774f7308df444dc94ddd7f9dad9dbbb640%3Fwx_fmt%3Dpng%26from%3Dappmsg%23imgIndex%3D4" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>人群</p><p>用途</p><p><strong>NAS用户</strong></p><p>远程访问群晖、威联通、UNRAID</p><p><strong>程序员</strong></p><p>远程SSH、访问内网Git、调试服务器</p><p><strong>远程办公族</strong></p><p>远程桌面、访问公司内网、打印机等</p><p><strong>家庭用户</strong></p><p>异地访问摄像头、智能家居、下载机</p><p><strong>技术爱好者</strong></p><p>组网、穿透、内网服务暴露</p><p><strong>一句话：只要你有多台设备，Tailscale就能让它们“像在同一屋檐下”。</strong></p><hr /></section>
<section><h3>【五、Tailscale怎么用？】<a href="#五tailscale怎么用"><span>#</span></a></h3><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/b8c19e631bba4e3cb97090efe3845ca0640%3Fwx_fmt%3Dpng%26from%3Dappmsg%23imgIndex%3D5" alt="图片" /><figcaption>图片</figcaption></figure><p></p><section><h4>✅ 第一步：下载安装<a href="#-第一步下载安装"><span>#</span></a></h4><p>官网：<a href="https://tailscale.com" target="_blank">https://tailscale.com</a></p><p>支持Windows、macOS、Linux、iOS、Android、NAS（群晖、威联通、UNRAID）</p></section><section><h4>✅ 第二步：注册账号<a href="#-第二步注册账号"><span>#</span></a></h4><p>用Google、Microsoft、GitHub账号一键登录。</p></section><section><h4>✅ 第三步：安装并登录<a href="#-第三步安装并登录"><span>#</span></a></h4><p>每台设备都装Tailscale，登录同一个账号。</p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/99422e8004444e89b90f4afb509fb755640%3Fwx_fmt%3Dpng%26from%3Dappmsg%23imgIndex%3D6" alt="图片" /><figcaption>图片</figcaption></figure><img src="https://mp.weixin.qq.com" alt="" /><p></p></section><section><h4>✅ 第四步：查看虚拟IP<a href="#-第四步查看虚拟ip"><span>#</span></a></h4><p>每台设备会分配一个<strong>100.x.x.x</strong>的IP地址，<strong>全网唯一</strong>。</p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/5912405762de4e039287231eeebc460c640%3Fwx_fmt%3Dpng%26from%3Dappmsg%23imgIndex%3D8" alt="图片" /><figcaption>图片</figcaption></figure><img src="https://gitee.com/wbgithub/pic-bak/raw/master//f4823aa11320488196ba7f8f673aadbcmp.weixin.qq.com" alt="" /><p></p></section><section><h4>✅ 第五步：直接访问<a href="#-第五步直接访问"><span>#</span></a></h4><p></p><figure><img src="https://gitee.com/wbgithub/pic-bak/raw/master//06fd2ddc66144859ad96afe5a65bd70c640" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>比如：</p><ul>
<li>
<p>家里NAS：<code>100.64.0.1:5000</code></p>
</li>
<li>
<p>公司电脑：<code>100.64.0.2:3389</code></p>
</li>
<li>
<p>树莓派：<code>100.64.0.3:22</code></p>
</li>
</ul><p><strong>无需端口映射，无需公网IP，直接访问。</strong></p><hr /></section></section>
<section><h3>【六、Tailscale的隐藏彩蛋】<a href="#六tailscale的隐藏彩蛋"><span>#</span></a></h3><p></p><figure><img src="https://gitee.com/wbgithub/pic-bak/raw/master//0916afb37bfa4d6f910a4f8490ff6b9a640" alt="图片" /><figcaption>图片</figcaption></figure><p></p><section><h4>✅ 支持ACL权限控制<a href="#-支持acl权限控制"><span>#</span></a></h4><p>你可以设置<strong>谁能访问谁</strong>，比如：</p><ul>
<li>
<p>只允许自己访问NAS</p>
</li>
<li>
<p>只允许同事访问测试服务器</p>
</li>
</ul><p><strong>图形化配置，不用写防火墙规则。</strong></p></section><section><h4>✅ 支持Exit Node<a href="#-支持exit-node"><span>#</span></a></h4><p>你可以把<strong>某台设备设置为出口节点</strong>，比如：</p><ul>
<li>
<p>人在国外，想走家里IP访问国内网站</p>
</li>
<li>
<p>人在公司，想走家里网络访问内网</p>
</li>
</ul><p><strong>一键切换，比VPN还方便。</strong></p></section><section><h4>✅ 支持MagicDNS<a href="#-支持magicdns"><span>#</span></a></h4><p>每台设备都有一个<strong>自定义域名</strong>，比如：</p><ul>
<li><code>nas.tailnet.ts.net</code></li>
<li><code>pi.tailnet.ts.net</code></li>
</ul><p><strong>不用记IP，直接域名访问。</strong></p><hr /></section></section>
<section><h3>【七、Tailscale的缺点】<a href="#七tailscale的缺点"><span>#</span></a></h3><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/f56709a7abe24e18bf1a627344737cf2640%3Fwx_fmt%3Dpng%26from%3Dappmsg%23imgIndex%3D12" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>阿江不吹不黑，Tailscale也不是完美。</p><p>缺点</p><p>说明</p><p><strong>免费版设备限制</strong></p><p>最多100台设备，个人够用</p><p><strong>国内网络偶尔抽风</strong></p><p>打洞失败时会走官方中继，速度一般</p><p><strong>需要登录第三方账号</strong></p><p>不支持国内邮箱注册</p><p><strong>企业版收费不便宜</strong></p><p>高级功能需付费，个人用户无感</p><p>但说实话，<strong>这些缺点在它的优点面前，真的不算啥</strong>。</p><hr /></section>
<section><h3>【八、Tailscale vs 其他内网穿透工具】<a href="#八tailscale-vs-其他内网穿透工具"><span>#</span></a></h3><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/9d2c3a5f9795440987f00b59741dbd7e640%3Fwx_fmt%3Dpng%26from%3Dappmsg%23imgIndex%3D13" alt="图片" /><figcaption>图片</figcaption></figure><p></p>

<table><thead><tr><th>工具</th><th>是否需公网IP</th><th>是否需配置</th><th>是否加密</th><th>是否P2P</th><th>是否免费</th></tr></thead><tbody><tr><td><strong>Tailscale</strong></td><td>❌</td><td>❌</td><td>✅</td><td>✅</td><td>✅</td></tr><tr><td><strong>FRP</strong></td><td>✅</td><td>✅</td><td>✅</td><td>❌</td><td>✅</td></tr><tr><td><strong>NPS</strong></td><td>✅</td><td>✅</td><td>✅</td><td>❌</td><td>✅</td></tr><tr><td><strong>ZeroTier</strong></td><td>❌</td><td>❌</td><td>✅</td><td>✅</td><td>✅</td></tr><tr><td><strong>花生壳</strong></td><td>❌</td><td>❌</td><td>❌</td><td>❌</td><td>❌</td></tr></tbody></table><p><strong>结论：Tailscale就是“懒人版内网穿透天花板”。</strong></p><hr /></section>
<section><h3>【九、建议】<a href="#九建议"><span>#</span></a></h3><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/27b390094e734fb5b98064ac3c8ffa4e640%3Fwx_fmt%3Dpng%26from%3Dappmsg%23imgIndex%3D14" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p>如果你：</p><ul>
<li>
<p>有NAS，想远程访问</p>
</li>
<li>
<p>有多台设备，想异地组网</p>
</li>
<li>
<p>不想折腾路由器、防火墙、公网IP</p>
</li>
<li>
<p>想安全、稳定、快速地访问内网</p>
</li>
</ul><p><strong>Tailscale，真的值得你试试。</strong></p><p>它不是万能，但它在你需要的场景里，<strong>几乎就是最优解</strong>。</p><hr /></section>
<section><h3>【十、写在最后】<a href="#十写在最后"><span>#</span></a></h3><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/10/8ad6328e06a34ec0a1c07ed075ec5934640%3Fwx_fmt%3Dpng%26from%3Dappmsg%23imgIndex%3D15" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/161c3e54/</id>
      <title type="text">PicList-轻松管理你的图片库，让美好瞬间触手可及</title>
      <published>2024-09-09T20:31:13.000Z</published>
      <updated>2024-09-09T20:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/161c3e54/"/>
      <summary type="text">PicList，一款基于 PicGo 深度二次开发的图片管理工具。PicList 不仅继承了 PicGo 的所有优秀特性，如支持多种图床服务（GitHub、SM.MS 等），还新增了相册同步、多图床支持、云存储管理、链接复制和预览功能等高级特性。如何安装、配置和使用 PicList，及其他使用技巧。</summary>
      <content type="html"><![CDATA[<section><h2>🚀 发现 PicList：超越 PicGo 的图片管理新星！<a href="#-发现-piclist超越-picgo-的图片管理新星"><span>#</span></a></h2><p>在日常工作中，我们经常需要上传、管理和分享图片。无论是开发者还是普通用户，找到一个好用的工具来辅助这项任务都是至关重要的。今天，我要向大家推荐一个在 <code>PicGo</code> 基础上进行了深度二次开发的图片管理工具——<code>PicList</code>。它不仅继承了 <code>PicGo</code> 的所有优秀特性，如支持多种图床服务（如 GitHub、SM.MS 等），而且还引入了更多高级功能，使其成为图片管理领域的佼佼者。🌈</p><section><h3>为什么选择 <code>PicList</code>？<a href="#为什么选择-piclist"><span>#</span></a></h3><p><code>PicList</code> 是一款高效且易于使用的云存储和图床管理工具。它不仅完美保留了 <code>PicGo</code> 的所有优点，还增添了许多令人惊喜的新功能。</p></section><section><h3>新增特性一览<a href="#新增特性一览"><span>#</span></a></h3><ul>
<li><strong>相册同步</strong>：支持云端文件的同步删除，确保本地和云端的一致性。</li>
<li><strong>多图床支持</strong>：除了常见的图床选项外，<code>PicList</code> 还内置了 WebDav、本地图床和 SFTP 等多种图床服务。</li>
<li><strong>云存储管理</strong>：增加了完整的云端存储管理功能，包括目录查看、文件搜索、批量上传下载及删除文件。</li>
<li><strong>链接复制</strong>：能够复制多种格式的文件链接，方便在不同场景下使用。</li>
<li><strong>预览功能</strong>：支持图片、Markdown 文档、文本和视频的预览，无需离开应用即可查看文件内容。</li>
</ul></section></section>
<section><h2>如何开始使用 <code>PicList</code>？<a href="#如何开始使用-piclist"><span>#</span></a></h2><section><h4>安装<a href="#安装"><span>#</span></a></h4><p>首先，你需要从官方网站下载适用于你操作系统的 <code>PicList</code> 版本。安装过程非常直观，只需按照安装向导的指示操作即可完成。</p></section><section><h4>配置<a href="#配置"><span>#</span></a></h4><p>启动 <code>PicList</code> 后，你需要配置你常用的图床服务。这通常涉及到输入访问凭证或者创建一个新的账户。<code>PicList</code> 的用户界面设计友好，每一步都有明确的提示，因此即便是第一次使用也能轻松搞定。</p></section><section><h4>使用技巧<a href="#使用技巧"><span>#</span></a></h4><ul>
<li><strong>批量上传</strong>：当需要上传大量图片时，可以利用批量上传功能，极大地提高了工作效率。</li>
<li><strong>云端同步</strong>：保持本地文件夹与云端图床的实时同步，确保任何时候都能访问到最新版本的图片。</li>
<li><strong>预览功能</strong>：在上传前，先使用预览功能检查图片是否符合要求，避免不必要的重复上传。</li>
</ul></section></section>
<section><h2>结语<a href="#结语"><span>#</span></a></h2><p><code>PicList</code> 不仅仅是一款工具，更是图片管理领域的一次革新。它不仅简化了图片上传的过程，还通过丰富的功能增强了用户体验。如果你正在寻找一个既强大又灵活的图片管理解决方案，那么 <code>PicList</code> 绝对值得一试！🚀</p><p>希望这篇博客能帮助你更好地了解 <code>PicList</code> 的优势，并鼓励更多的用户尝试使用它。如果你有任何疑问或想要了解更多细节，欢迎访问 <code>PicList</code> 的官方网站或者加入社区讨论！🤝</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/3efe8d37/</id>
      <title type="text">JSDelivr &amp; NPM CDN 国内加速节点</title>
      <published>2024-09-08T20:31:13.000Z</published>
      <updated>2024-09-08T20:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/3efe8d37/"/>
      <summary type="text"></summary>
      <content type="html"><![CDATA[<section><h2>JSDelivr 节点<a href="#jsdelivr-节点"><span>#</span></a></h2>

<table><thead><tr><th>节点名称</th><th>描述</th><th>可用性</th></tr></thead><tbody><tr><td>cdn.jsdelivr.net</td><td>通用节点</td><td>低</td></tr><tr><td>gcore.jsdelivr.net</td><td>Gcore 节点</td><td>高</td></tr><tr><td>testingcf.jsdelivr.net</td><td>Cloudflare 节点</td><td>高</td></tr><tr><td>quantil.jsdelivr.net</td><td>Quantil 节点</td><td>尚可</td></tr><tr><td>fastly.jsdelivr.net</td><td>Fastly 节点</td><td>尚可</td></tr><tr><td>originfastly.jsdelivr.net</td><td>Fastly 节点</td><td>低</td></tr><tr><td>test1.jsdelivr.net</td><td>Cloudflare 节点</td><td>低</td></tr></tbody></table></section>
<section><h2>第三方提供的 jsdelivr 节点：<a href="#第三方提供的-jsdelivr-节点"><span>#</span></a></h2><ul>
<li>jsd.cdn.zzko.cn：国内 CDN</li>
<li>jsd.onmicrosoft.cn：国内 CDN</li>
<li>jsdelivr.b-cdn.net：台湾 CDN</li>
<li>cdn.jsdelivr.us：Anycast（国内速度很快，但稳定性未知）</li>
</ul></section>
<section><h2>NPM 节点<a href="#npm-节点"><span>#</span></a></h2>

<table><thead><tr><th>节点名称</th><th>描述</th><th>注意事项</th></tr></thead><tbody><tr><td>unpkg.com</td><td>国内几乎不可用</td><td>-</td></tr><tr><td>npm.elemecdn.com</td><td>饿了么</td><td>同步快，缺的多</td></tr><tr><td>npm.onmicrosoft.cn</td><td>公益</td><td>需准确的版本号</td></tr><tr><td>unpkg.zhimg.com</td><td>知乎</td><td>同步慢</td></tr><tr><td>npm.akass.cn</td><td>公益</td><td>需准确的版本号</td></tr><tr><td>cdn.chuqis.com/npm/</td><td>公益</td><td>需准确的版本号</td></tr><tr><td>code.bdstatic.com/npm</td><td>百度</td><td>仅同步热门包</td></tr></tbody></table></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/309e6522/</id>
      <title type="text">效率提升利器，一个全龄段友好的DotNET万能工具库</title>
      <published>2024-09-03T12:31:13.000Z</published>
      <updated>2024-09-03T12:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/309e6522/"/>
      <summary type="text">介绍了Masuit.Tools库，这是一个适用于所有水平开发者的C#/.NET工具库。描述了该库的功能，包括加密解密、反射操作、树结构、文件探测、权重随机筛选算法、分布式短ID生成、表达式树、LINQ扩展、文件压缩、多线程下载、硬件信息获取、字符串扩展方法、日期时间操作、中国农历、大文件拷贝、图像裁剪等功能</summary>
      <content type="html"><![CDATA[<section><h2><strong>项目介绍</strong><a href="#项目介绍"><span>#</span></a></h2><p>Masuit.Tools(码数吐司库)是一个全龄段友好的C#/.NET万能工具库，不管你是菜鸟新手还是骨灰级玩家都能轻松上手。</p></section>
<section><h2><strong>包含功能</strong><a href="#包含功能"><span>#</span></a></h2><p>这个库包含一些常用的操作类，大都是静态类，加密解密，反射操作，树结构，文件探测，权重随机筛选算法，分布式短id，表达式树，linq扩展，文件压缩，多线程下载，硬件信息，字符串扩展方法，日期时间扩展操作，中国农历，大文件拷贝，图像裁剪，验证码，断点续传，集合扩展、Excel导出等常用封装。</p><blockquote><p>诸多功能集一身，代码量不到2MB！</p></blockquote><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/09/640%3Fwx_fmt%3Dpng%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h2><strong>建议开发环境</strong><a href="#建议开发环境"><span>#</span></a></h2><ul>
<li>操作系统：Windows 11 23H2及以上版本.</li>
<li>开发工具：VisualStudio2022 v17.8及以上版本.</li>
<li>SDK：.Net Core 2.1.0及以上所有版本.</li>
</ul></section>
<section><h2><strong>字符串检查</strong><a href="#字符串检查"><span>#</span></a></h2><blockquote><p>检验字符串是否是Email、手机号、URL、IP地址、身份证号等</p></blockquote><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>var</span><span><span> (isMatch, match) </span><span>=</span><span> </span></span><span>"337845818@qq.com"</span><span>.</span><span>MatchEmail</span><span>(); </span><span>// 可在appsetting.json中添加EmailDomainWhiteList和EmailDomainBlockList配置邮箱域名黑白名单，逗号分隔，如"EmailDomainBlockList": "^\\w{1,5}@qq.com,^\\w{1,5}@163.com,^\\w{1,5}@gmail.com,^\\w{1,5}@outlook.com",</span></div></div><div><div><div>2</div></div><div><span>bool</span><span><span> </span><span>isInetAddress</span><span> </span><span>=</span><span> </span></span><span>"114.114.114.114"</span><span>.</span><span>MatchInetAddress</span><span>(); </span><span>// 匹配IP地址</span></div></div><div><div><div>3</div></div><div><span>bool</span><span><span> </span><span>isUrl</span><span> </span><span>=</span><span> </span></span><span>"http://masuit.org/20/history"</span><span>.</span><span>MatchUrl</span><span>(); </span><span>// 匹配url</span></div></div><div><div><div>4</div></div><div><span>bool</span><span><span> </span><span>isPhoneNumber</span><span> </span><span>=</span><span> </span></span><span>"15205201520"</span><span>.</span><span>MatchPhoneNumber</span><span>(); </span><span>// 匹配手机号</span></div></div><div><div><div>5</div></div><div><span>bool</span><span><span> </span><span>isLandline</span><span> </span><span>=</span><span> </span></span><span>"01088888888"</span><span>.</span><span>MatchLandline</span><span>(); </span><span>// 匹配座机号</span></div></div><div><div><div>6</div></div><div><span>bool</span><span><span> </span><span>isIdentifyCard</span><span> </span><span>=</span><span> </span></span><span>"312000199502230660"</span><span>.</span><span>MatchIdentifyCard</span><span>();</span><span>// 校验中国大陆身份证号</span></div></div><div><div><div>7</div></div><div><span>bool</span><span><span> </span><span>isCNPatentNumber</span><span> </span><span>=</span><span> </span></span><span>"200410018477.9"</span><span>.</span><span>MatchCNPatentNumber</span><span>(); </span><span>// 校验中国专利申请号或专利号，是否带校验位，校验位前是否带“.”，都可以校验，待校验的号码前不要带CN、ZL字样的前缀</span></div></div><div><div><div>8</div></div><div><span>bool</span><span><span> </span><span>isUSCC</span><span> </span><span>=</span><span> </span></span><span>"200410018477.9"</span><span>.</span><span>MatchUSCC</span><span>(); </span><span>// 校验企业统一社会信用代码</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2><strong>硬件监测</strong><a href="#硬件监测"><span>#</span></a></h2><blockquote><p>硬件监测(需要管理员权限，仅支持Windows，部分函数仅支持物理机模式)!</p></blockquote><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>float</span><span><span> </span><span>load</span><span> </span><span>=</span><span> </span><span>SystemInfo</span><span>.</span><span>CpuLoad</span><span>;</span></span><span>// 获取CPU占用率</span></div></div><div><div><div>2</div></div><div><span>long</span><span><span> </span><span>physicalMemory</span><span> </span><span>=</span><span> </span><span>SystemInfo</span><span>.</span><span>PhysicalMemory</span><span>;</span></span><span>// 获取物理内存总数</span></div></div><div><div><div>3</div></div><div><span>long</span><span><span> </span><span>memoryAvailable</span><span> </span><span>=</span><span> </span><span>SystemInfo</span><span>.</span><span>MemoryAvailable</span><span>;</span></span><span>// 获取物理内存可用率</span></div></div><div><div><div>4</div></div><div><span>double</span><span><span> </span><span>freePhysicalMemory</span><span> </span><span>=</span><span> </span><span>SystemInfo</span><span>.</span></span><span>GetFreePhysicalMemory</span><span>();</span><span>// 获取可用物理内存</span></div></div><div><div><div>5</div></div><div><span>double</span><span><span> </span><span>temperature</span><span> </span><span>=</span><span> </span><span>SystemInfo</span><span>.</span></span><span>GetCPUTemperature</span><span>();</span><span>// 获取CPU温度</span></div></div><div><div><div>6</div></div><div><span>int</span><span><span> </span><span>cpuCount</span><span> </span><span>=</span><span> </span><span>SystemInfo</span><span>.</span></span><span>GetCpuCount</span><span>();</span><span>// 获取CPU核心数</span></div></div><div><div><div>7</div></div><div><span>var</span><span><span> </span><span>ipAddress</span><span> </span><span>=</span><span> </span><span>SystemInfo</span><span>.</span></span><span>GetLocalIPs</span><span>();</span><span>// 获取本机所有IP地址</span></div></div><div><div><div>8</div></div><div><span>string</span><span><span> </span><span>localUsedIp</span><span> </span><span>=</span><span> </span><span>SystemInfo</span><span>.</span></span><span>GetLocalUsedIP</span><span>();</span><span>// 获取本机当前正在使用的IP地址</span></div></div><div><div><div>9</div></div><div><span>IList</span><span>&lt;</span><span>string</span><span><span>&gt; </span><span>macAddress</span><span> </span><span>=</span><span> </span><span>SystemInfo</span><span>.</span></span><span>GetMacAddress</span><span>();</span><span>// 获取本机所有网卡mac地址</span></div></div><div><div><div>10</div></div><div><span>string</span><span><span> </span><span>osVersion</span><span> </span><span>=</span><span> </span><span>Windows</span><span>.</span></span><span>GetOsVersion</span><span>();</span><span>// 获取操作系统版本</span></div></div><div><div><div>11</div></div><div><span>RamInfo</span><span><span> </span><span>ramInfo</span><span> </span><span>=</span><span> </span><span>SystemInfo</span><span>.</span></span><span>GetRamInfo</span><span>();</span><span>// 获取内存信息</span></div></div><div><div><div>12</div></div><div><span>var</span><span><span> </span><span>cpuSN</span><span>=</span><span>SystemInfo</span><span>.</span></span><span>GetCpuInfo</span><span>()[</span><span>0</span><span><span>].</span><span>SerialNumber</span><span>; </span></span><span>// CPU序列号</span></div></div><div><div><div>13</div></div><div><span>var</span><span><span> </span><span>driveSN</span><span>=</span><span>SystemInfo</span><span>.</span></span><span>GetDiskInfo</span><span>()[</span><span>0</span><span><span>].</span><span>SerialNumber</span><span>; </span></span><span>// 硬盘序列号</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>// 快速方法</span></div></div><div><div><div>16</div></div><div><span>var</span><span><span> </span><span>cpuInfos</span><span> </span><span>=</span><span> </span><span>CpuInfo</span><span>.</span><span>Locals</span><span>; </span></span><span>// 快速获取CPU的信息</span></div></div><div><div><div>17</div></div><div><span>var</span><span><span> </span><span>ramInfo</span><span> </span><span>=</span><span> </span><span>RamInfo</span><span>.</span><span>Local</span><span>; </span></span><span>// 快速获取内存的信息</span></div></div><div><div><div>18</div></div><div><span>var</span><span><span> </span><span>diskInfos</span><span> </span><span>=</span><span> </span><span>DiskInfo</span><span>.</span><span>Locals</span><span>; </span></span><span>// 快速获取硬盘的信息</span></div></div><div><div><div>19</div></div><div><span>var</span><span><span> </span><span>biosInfo</span><span> </span><span>=</span><span> </span><span>BiosInfo</span><span>.</span><span>Local</span><span>; </span></span><span>// 快速获取主板的信息</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>
<section><h2><strong>LinqExtension</strong><a href="#linqextension"><span>#</span></a></h2><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>using</span><span> </span><span>System</span><span>;</span></div></div><div><div><div>2</div></div><div><span>using</span><span> </span><span>System</span><span>.</span><span>Collections</span><span>.</span><span>Generic</span><span>;</span></div></div><div><div><div>3</div></div><div><span>using</span><span> </span><span>System</span><span>.</span><span>Linq</span><span>.</span><span>Expressions</span><span>;</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>namespace</span><span> </span><span>Masuit</span><span>.</span><span>Tools</span><span>.</span><span>Linq</span><span>;</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>/// </span><span>&lt;</span><span>summary</span><span>&gt;</span></div></div><div><div><div>8</div></div><div><span>/// LINQ扩展方法</span></div></div><div><div><div>9</div></div><div><span>/// </span><span>&lt;/</span><span>summary</span><span>&gt;</span></div></div><div><div><div>10</div></div><div><span>public</span><span> </span><span>static</span><span> </span><span>class</span><span> </span><span>LinqExtension</span></div></div><div><div><div>11</div></div><div><span>{</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>summary</span><span>&gt;</span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>/// 与连接</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;/</span><span>summary</span><span>&gt;</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>typeparam</span><span> </span><span>name</span><span>=</span><span>"T"</span><span>&gt;</span><span>类型</span><span>&lt;/</span><span>typeparam</span><span>&gt;</span></div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"left"</span><span>&gt;</span><span>左条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>17</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"right"</span><span>&gt;</span><span>右条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>18</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>returns</span><span>&gt;</span><span>新表达式</span><span>&lt;/</span><span>returns</span><span>&gt;</span></div></div><div><div><div>19</div></div><div><span>    </span><span>public</span><span> </span><span>static</span><span> </span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span>&gt;&gt; </span><span>And</span><span>&lt;</span><span>T</span><span>&gt;(</span><span>this</span><span> </span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span><span>&gt;&gt; </span><span>left</span><span>, </span></span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span><span>&gt;&gt; </span><span>right</span><span>)</span></span></div></div><div><div><div>20</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>21</div></div><div><span>        </span><span>return</span><span> </span><span>CombineLambdas</span><span><span>(</span><span>left</span><span>, </span><span>right</span><span>, </span><span>ExpressionType</span><span>.</span><span>AndAlso</span><span>);</span></span></div></div><div><div><div>22</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>23</div></div><div>
</div></div><div><div><div>24</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>summary</span><span>&gt;</span></div></div><div><div><div>25</div></div><div><span><span>    </span></span><span>/// 与连接</span></div></div><div><div><div>26</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;/</span><span>summary</span><span>&gt;</span></div></div><div><div><div>27</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>typeparam</span><span> </span><span>name</span><span>=</span><span>"T"</span><span>&gt;</span><span>类型</span><span>&lt;/</span><span>typeparam</span><span>&gt;</span></div></div><div><div><div>28</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"left"</span><span>&gt;</span><span>左条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>29</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"condition"</span><span>&gt;</span><span>符合什么条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>30</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"right"</span><span>&gt;</span><span>右条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>31</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>returns</span><span>&gt;</span><span>新表达式</span><span>&lt;/</span><span>returns</span><span>&gt;</span></div></div><div><div><div>32</div></div><div><span>    </span><span>public</span><span> </span><span>static</span><span> </span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span>&gt;&gt; </span><span>AndIf</span><span>&lt;</span><span>T</span><span>&gt;(</span><span>this</span><span> </span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span><span>&gt;&gt; </span><span>left</span><span>, </span></span><span>bool</span><span><span> </span><span>condition</span><span>, </span></span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span><span>&gt;&gt; </span><span>right</span><span>)</span></span></div></div><div><div><div>33</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>34</div></div><div><span>        </span><span>return</span><span><span> </span><span>condition</span><span> ? </span></span><span>CombineLambdas</span><span><span>(</span><span>left</span><span>, </span><span>right</span><span>, </span><span>ExpressionType</span><span>.</span><span>AndAlso</span><span>) : </span><span>left</span><span>;</span></span></div></div><div><div><div>35</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>36</div></div><div>
</div></div><div><div><div>37</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>summary</span><span>&gt;</span></div></div><div><div><div>38</div></div><div><span><span>    </span></span><span>/// 与连接</span></div></div><div><div><div>39</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;/</span><span>summary</span><span>&gt;</span></div></div><div><div><div>40</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>typeparam</span><span> </span><span>name</span><span>=</span><span>"T"</span><span>&gt;</span><span>类型</span><span>&lt;/</span><span>typeparam</span><span>&gt;</span></div></div><div><div><div>41</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"left"</span><span>&gt;</span><span>左条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>42</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"condition"</span><span>&gt;</span><span>符合什么条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>43</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"right"</span><span>&gt;</span><span>右条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>44</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>returns</span><span>&gt;</span><span>新表达式</span><span>&lt;/</span><span>returns</span><span>&gt;</span></div></div><div><div><div>45</div></div><div><span>    </span><span>public</span><span> </span><span>static</span><span> </span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span>&gt;&gt; </span><span>AndIf</span><span>&lt;</span><span>T</span><span>&gt;(</span><span>this</span><span> </span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span><span>&gt;&gt; </span><span>left</span><span>, </span></span><span>Func</span><span>&lt;</span><span>bool</span><span><span>&gt; </span><span>condition</span><span>, </span></span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span><span>&gt;&gt; </span><span>right</span><span>)</span></span></div></div><div><div><div>46</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>47</div></div><div><span>        </span><span>return</span><span> </span><span>condition</span><span>() ? </span><span>CombineLambdas</span><span><span>(</span><span>left</span><span>, </span><span>right</span><span>, </span><span>ExpressionType</span><span>.</span><span>AndAlso</span><span>) : </span><span>left</span><span>;</span></span></div></div><div><div><div>48</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>49</div></div><div>
</div></div><div><div><div>50</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>summary</span><span>&gt;</span></div></div><div><div><div>51</div></div><div><span><span>    </span></span><span>/// 或连接</span></div></div><div><div><div>52</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;/</span><span>summary</span><span>&gt;</span></div></div><div><div><div>53</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>typeparam</span><span> </span><span>name</span><span>=</span><span>"T"</span><span>&gt;</span><span>类型</span><span>&lt;/</span><span>typeparam</span><span>&gt;</span></div></div><div><div><div>54</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"left"</span><span>&gt;</span><span>左条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>55</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"right"</span><span>&gt;</span><span>右条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>56</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>returns</span><span>&gt;</span><span>新表达式</span><span>&lt;/</span><span>returns</span><span>&gt;</span></div></div><div><div><div>57</div></div><div><span>    </span><span>public</span><span> </span><span>static</span><span> </span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span>&gt;&gt; </span><span>Or</span><span>&lt;</span><span>T</span><span>&gt;(</span><span>this</span><span> </span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span><span>&gt;&gt; </span><span>left</span><span>, </span></span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span><span>&gt;&gt; </span><span>right</span><span>)</span></span></div></div><div><div><div>58</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>59</div></div><div><span>        </span><span>return</span><span> </span><span>CombineLambdas</span><span><span>(</span><span>left</span><span>, </span><span>right</span><span>, </span><span>ExpressionType</span><span>.</span><span>OrElse</span><span>);</span></span></div></div><div><div><div>60</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>61</div></div><div>
</div></div><div><div><div>62</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>summary</span><span>&gt;</span></div></div><div><div><div>63</div></div><div><span><span>    </span></span><span>/// 或连接</span></div></div><div><div><div>64</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;/</span><span>summary</span><span>&gt;</span></div></div><div><div><div>65</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>typeparam</span><span> </span><span>name</span><span>=</span><span>"T"</span><span>&gt;</span><span>类型</span><span>&lt;/</span><span>typeparam</span><span>&gt;</span></div></div><div><div><div>66</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"left"</span><span>&gt;</span><span>左条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>67</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"condition"</span><span>&gt;</span><span>符合什么条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>68</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"right"</span><span>&gt;</span><span>右条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>69</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>returns</span><span>&gt;</span><span>新表达式</span><span>&lt;/</span><span>returns</span><span>&gt;</span></div></div><div><div><div>70</div></div><div><span>    </span><span>public</span><span> </span><span>static</span><span> </span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span>&gt;&gt; </span><span>OrIf</span><span>&lt;</span><span>T</span><span>&gt;(</span><span>this</span><span> </span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span><span>&gt;&gt; </span><span>left</span><span>, </span></span><span>bool</span><span><span> </span><span>condition</span><span>, </span></span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span><span>&gt;&gt; </span><span>right</span><span>)</span></span></div></div><div><div><div>71</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>72</div></div><div><span>        </span><span>return</span><span><span> </span><span>condition</span><span> ? </span></span><span>CombineLambdas</span><span><span>(</span><span>left</span><span>, </span><span>right</span><span>, </span><span>ExpressionType</span><span>.</span><span>OrElse</span><span>) : </span><span>left</span><span>;</span></span></div></div><div><div><div>73</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>74</div></div><div>
</div></div><div><div><div>75</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>summary</span><span>&gt;</span></div></div><div><div><div>76</div></div><div><span><span>    </span></span><span>/// 或连接</span></div></div><div><div><div>77</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;/</span><span>summary</span><span>&gt;</span></div></div><div><div><div>78</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>typeparam</span><span> </span><span>name</span><span>=</span><span>"T"</span><span>&gt;</span><span>类型</span><span>&lt;/</span><span>typeparam</span><span>&gt;</span></div></div><div><div><div>79</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"left"</span><span>&gt;</span><span>左条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>80</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"condition"</span><span>&gt;</span><span>符合什么条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>81</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>param</span><span> </span><span>name</span><span>=</span><span>"right"</span><span>&gt;</span><span>右条件</span><span>&lt;/</span><span>param</span><span>&gt;</span></div></div><div><div><div>82</div></div><div><span><span>    </span></span><span>/// </span><span>&lt;</span><span>returns</span><span>&gt;</span><span>新表达式</span><span>&lt;/</span><span>returns</span><span>&gt;</span></div></div><div><div><div>83</div></div><div><span>    </span><span>public</span><span> </span><span>static</span><span> </span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span>&gt;&gt; </span><span>OrIf</span><span>&lt;</span><span>T</span><span>&gt;(</span><span>this</span><span> </span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span><span>&gt;&gt; </span><span>left</span><span>, </span></span><span>Func</span><span>&lt;</span><span>bool</span><span><span>&gt; </span><span>condition</span><span>, </span></span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span><span>&gt;&gt; </span><span>right</span><span>)</span></span></div></div><div><div><div>84</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>85</div></div><div><span>        </span><span>return</span><span> </span><span>condition</span><span>() ? </span><span>CombineLambdas</span><span><span>(</span><span>left</span><span>, </span><span>right</span><span>, </span><span>ExpressionType</span><span>.</span><span>OrElse</span><span>) : </span><span>left</span><span>;</span></span></div></div><div><div><div>86</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>87</div></div><div>
</div></div><div><div><div>88</div></div><div><span>    </span><span>private</span><span> </span><span>static</span><span> </span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span>&gt;&gt; </span><span>CombineLambdas</span><span>&lt;</span><span>T</span><span>&gt;(</span><span>this</span><span> </span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span><span>&gt;&gt; </span><span>left</span><span>, </span></span><span>Expression</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span><span>&gt;&gt; </span><span>right</span><span>, </span></span><span>ExpressionType</span><span><span> </span><span>expressionType</span><span>)</span></span></div></div><div><div><div>89</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>90</div></div><div><span>        </span><span>var</span><span><span> </span><span>visitor</span><span> </span><span>=</span><span> new </span></span><span>SubstituteParameterVisitor</span></div></div><div><div><div>91</div></div><div><span><span>        </span></span><span>{</span></div></div><div><div><div>92</div></div><div><span><span>            </span></span><span>Sub</span><span> </span><span>=</span></div></div><div><div><div>93</div></div><div><span><span>            </span></span><span>{</span></div></div><div><div><div>94</div></div><div><span><span>                </span></span><span>[</span><span>right</span><span>.</span><span>Parameters</span><span>[</span><span>0</span><span><span>]] </span><span>=</span><span> </span><span>left</span><span>.</span><span>Parameters</span><span>[</span></span><span>0</span><span>]</span></div></div><div><div><div>95</div></div><div><span><span>            </span></span><span>}</span></div></div><div><div><div>96</div></div><div><span><span>        </span></span><span>};</span></div></div><div><div><div>97</div></div><div>
</div></div><div><div><div>98</div></div><div><span>        </span><span>Expression</span><span><span> </span><span>body</span><span> </span><span>=</span><span> </span><span>Expression</span><span>.</span></span><span>MakeBinary</span><span><span>(</span><span>expressionType</span><span>, </span><span>left</span><span>.</span><span>Body</span><span>, </span><span>visitor</span><span>.</span></span><span>Visit</span><span><span>(</span><span>right</span><span>.</span><span>Body</span><span>));</span></span></div></div><div><div><div>99</div></div><div><span>        </span><span>return</span><span><span> </span><span>Expression</span><span>.</span></span><span>Lambda</span><span>&lt;</span><span>Func</span><span>&lt;</span><span>T</span><span>, </span><span>bool</span><span><span>&gt;&gt;(</span><span>body</span><span>, </span><span>left</span><span>.</span><span>Parameters</span><span>[</span></span><span>0</span><span>]);</span></div></div><div><div><div>100</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>101</div></div><div><span>}</span></div></div><div><div><div>102</div></div><div>
</div></div><div><div><div>103</div></div><div><span>internal</span><span> </span><span>class</span><span> </span><span>SubstituteParameterVisitor</span><span> : </span><span>ExpressionVisitor</span></div></div><div><div><div>104</div></div><div><span>{</span></div></div><div><div><div>105</div></div><div><span>    </span><span>public</span><span> </span><span>Dictionary</span><span>&lt;</span><span>Expression</span><span>, </span><span>Expression</span><span>&gt; </span><span>Sub</span><span><span> </span><span>=</span><span> new();</span></span></div></div><div><div><div>106</div></div><div>
</div></div><div><div><div>107</div></div><div><span>    </span><span>protected</span><span> </span><span>override</span><span> </span><span>Expression</span><span> </span><span>VisitParameter</span><span>(</span><span>ParameterExpression</span><span><span> </span><span>node</span><span>)</span></span></div></div><div><div><div>108</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>109</div></div><div><span>        </span><span>return</span><span><span> </span><span>Sub</span><span>.</span></span><span>TryGetValue</span><span><span>(</span><span>node</span><span>, </span></span><span>out</span><span> </span><span>var</span><span><span> </span><span>newValue</span><span>) ? </span><span>newValue</span><span> : </span><span>node</span><span>;</span></span></div></div><div><div><div>110</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>111</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>
<section><h2><strong>开源地址</strong><a href="#开源地址"><span>#</span></a></h2><p><a href="https://github.com/ldqk/Masuit.Tools" target="_blank">https://github.com/ldqk/Masuit.Tools</a></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/98cc63b2/</id>
      <title type="text">分享一个非常好用的loading效果网站</title>
      <published>2024-08-11T18:31:13.000Z</published>
      <updated>2024-08-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/98cc63b2/"/>
      <summary type="text">本文介绍了一个非常实用的加载效果网站，适合前端开发者寻找和使用各种加载动画。以下是文章的详细内容</summary>
      <content type="html"><![CDATA[<section><h3>先看效果<a href="#先看效果"><span>#</span></a></h3><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/08/640%3Fwx_fmt%3Dgif%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%7Bstr-number%7D" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h3>神仙网站<a href="#神仙网站"><span>#</span></a></h3><p>网址 ：<a href="https://epic-spinners.epicmax.co/?mode=light" target="_blank">https://epic-spinners.epicmax.co/?mode=light</a></p><p>点击想要的效果就会弹出相关代码:egg:</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/08/640%3Fwx_fmt%3Dpng%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%26wx_co%3D1%7Bstr-number%7D" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/a6b86d8c/</id>
      <title type="text">【uniapp】个人中心页面</title>
      <published>2024-08-11T18:31:13.000Z</published>
      <updated>2024-08-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/a6b86d8c/"/>
      <summary type="text">本文档详细介绍了如何使用 UniApp 开发一个个人中心页面。个人中心页面是移动应用中常见的功能模块，通常包含用户的头像、昵称、简介以及各种功能列表。本文将通过三个不同风格的设计示例，展示如何实现这些功能。</summary>
      <content type="html"><![CDATA[<section><h3>先看效果:eyes:<a href="#先看效果eyes"><span>#</span></a></h3><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/08/57881c7a81834b0ca30b00803480e65d" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h3>源码<a href="#源码"><span>#</span></a></h3><section><h4>01：第一个黄色（图一）<a href="#01第一个黄色图一"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>template</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"content"</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"tops"</span><span>&gt;</span></div></div><div><div><div>4</div></div><div><span><span>      </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"gear"</span><span> </span><span>size</span><span>=</span><span>"32"</span><span> </span><span>class</span><span>=</span><span>"setIcon"</span><span> </span><span>@click</span><span>=</span><span>"setFun"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>5</div></div><div><span><span>      </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"infos"</span><span>&gt;</span></div></div><div><div><div>6</div></div><div><span><span>        </span></span><span>&lt;</span><span>image</span></div></div><div><div><div>7</div></div><div><span>          </span><span>src</span><span>=</span><span>"https://img1.baidu.com/it/u=1665929857,2089570148&amp;fm=253&amp;fmt=auto&amp;app=120&amp;f=JPEG?w=500&amp;h=889"</span></div></div><div><div><div>8</div></div><div><span>          </span><span>mode</span><span>=</span><span>"aspectFill"</span><span>&gt;&lt;/</span><span>image</span><span>&gt;</span></div></div><div><div><div>9</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"names"</span><span>&gt;</span></div></div><div><div><div>10</div></div><div><span><span>          </span></span><span>韩信</span></div></div><div><div><div>11</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>12</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"desc"</span><span>&gt;</span></div></div><div><div><div>13</div></div><div><span><span>          </span></span><span>纵情山河万里，肆意九州五岳，爱恨痴狂，抵不过沧海一笑</span></div></div><div><div><div>14</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>15</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"t-list"</span><span>&gt;</span></div></div><div><div><div>16</div></div><div><span><span>          </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"t-item"</span><span>&gt;</span></div></div><div><div><div>17</div></div><div><span><span>            </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"tit"</span><span>&gt;</span></div></div><div><div><div>18</div></div><div><span><span>              </span></span><span>收藏</span></div></div><div><div><div>19</div></div><div><span><span>            </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>20</div></div><div><span><span>            </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"vals"</span><span>&gt;</span></div></div><div><div><div>21</div></div><div><span><span>              </span></span><span>45</span></div></div><div><div><div>22</div></div><div><span><span>            </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>23</div></div><div><span><span>          </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>24</div></div><div><span><span>          </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"t-item"</span><span>&gt;</span></div></div><div><div><div>25</div></div><div><span><span>            </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"tit"</span><span>&gt;</span></div></div><div><div><div>26</div></div><div><span><span>              </span></span><span>点赞</span></div></div><div><div><div>27</div></div><div><span><span>            </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>28</div></div><div><span><span>            </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"vals"</span><span>&gt;</span></div></div><div><div><div>29</div></div><div><span><span>              </span></span><span>266</span></div></div><div><div><div>30</div></div><div><span><span>            </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>31</div></div><div><span><span>          </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>32</div></div><div><span><span>          </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"t-item"</span><span>&gt;</span></div></div><div><div><div>33</div></div><div><span><span>            </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"tit"</span><span>&gt;</span></div></div><div><div><div>34</div></div><div><span><span>              </span></span><span>分享</span></div></div><div><div><div>35</div></div><div><span><span>            </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>36</div></div><div><span><span>            </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"vals"</span><span>&gt;</span></div></div><div><div><div>37</div></div><div><span><span>              </span></span><span>103</span></div></div><div><div><div>38</div></div><div><span><span>            </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>39</div></div><div><span><span>          </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>40</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>41</div></div><div><span><span>      </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>42</div></div><div>
</div></div><div><div><div>43</div></div><div><span><span>    </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>44</div></div><div>
</div></div><div><div><div>45</div></div><div><span><span>    </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"lists"</span><span>&gt;</span></div></div><div><div><div>46</div></div><div><span><span>      </span></span><span>&lt;</span><span>uni-list</span><span>&gt;</span></div></div><div><div><div>47</div></div><div><span><span>        </span></span><span>&lt;</span><span>uni-list-item</span><span> </span><span>:show-extra-icon</span><span>=</span><span>"true"</span><span> </span><span>:extra-icon</span><span>=</span><span>"extraIcon1"</span><span> </span><span>showArrow</span><span> </span><span>title</span><span>=</span><span>"个人信息"</span><span> </span><span>clickable</span></div></div><div><div><div>48</div></div><div><span>          </span><span>@click</span><span>=</span><span>"clickList"</span><span> </span><span>rightText</span><span>=</span><span>"右侧文字"</span><span> /&gt;</span></div></div><div><div><div>49</div></div><div><span><span>        </span></span><span>&lt;</span><span>uni-list-item</span><span> </span><span>:show-extra-icon</span><span>=</span><span>"true"</span><span> </span><span>:extra-icon</span><span>=</span><span>"extraIcon2"</span><span> </span><span>showArrow</span><span> </span><span>title</span><span>=</span><span>"我的购物车"</span><span> </span><span>clickable</span></div></div><div><div><div>50</div></div><div><span>          </span><span>@click</span><span>=</span><span>"clickList"</span><span> </span><span>rightText</span><span>=</span><span>"右侧文字"</span><span> /&gt;</span></div></div><div><div><div>51</div></div><div><span><span>        </span></span><span>&lt;</span><span>uni-list-item</span><span> </span><span>:show-extra-icon</span><span>=</span><span>"true"</span><span> </span><span>:extra-icon</span><span>=</span><span>"extraIcon3"</span><span> </span><span>showArrow</span><span> </span><span>title</span><span>=</span><span>"用户反馈"</span><span> </span><span>clickable</span></div></div><div><div><div>52</div></div><div><span>          </span><span>@click</span><span>=</span><span>"clickList"</span><span> /&gt;</span></div></div><div><div><div>53</div></div><div><span><span>        </span></span><span>&lt;</span><span>uni-list-item</span><span> </span><span>:show-extra-icon</span><span>=</span><span>"true"</span><span> </span><span>:extra-icon</span><span>=</span><span>"extraIcon4"</span><span> </span><span>showArrow</span><span> </span><span>title</span><span>=</span><span>"我的邮件"</span><span> </span><span>clickable</span></div></div><div><div><div>54</div></div><div><span>          </span><span>@click</span><span>=</span><span>"clickList"</span><span> /&gt;</span></div></div><div><div><div>55</div></div><div><span><span>        </span></span><span>&lt;</span><span>uni-list-item</span><span> </span><span>:show-extra-icon</span><span>=</span><span>"true"</span><span> </span><span>:extra-icon</span><span>=</span><span>"extraIcon5"</span><span> </span><span>showArrow</span><span> </span><span>title</span><span>=</span><span>"分享有礼"</span><span> </span><span>clickable</span></div></div><div><div><div>56</div></div><div><span>          </span><span>@click</span><span>=</span><span>"clickList"</span><span> /&gt;</span></div></div><div><div><div>57</div></div><div><span><span>      </span></span><span>&lt;/</span><span>uni-list</span><span>&gt;</span></div></div><div><div><div>58</div></div><div><span><span>    </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>59</div></div><div><span><span>  </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>60</div></div><div><span>&lt;/</span><span>template</span><span>&gt;</span></div></div><div><div><div>61</div></div><div>
</div></div><div><div><div>62</div></div><div><span>&lt;</span><span>script</span><span>&gt;</span></div></div><div><div><div>63</div></div><div><span>  </span><span>export</span><span> </span><span>default</span><span> {</span></div></div><div><div><div>64</div></div><div><span>    </span><span>data</span><span>() {</span></div></div><div><div><div>65</div></div><div><span>      </span><span>return</span><span> {</span></div></div><div><div><div>66</div></div><div><span>        </span><span>extraIcon1</span><span>:</span><span> {</span></div></div><div><div><div>67</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>'#666666'</span><span>,</span></div></div><div><div><div>68</div></div><div><span>          </span><span>size</span><span>:</span><span> </span><span>'22'</span><span>,</span></div></div><div><div><div>69</div></div><div><span>          </span><span>type</span><span>:</span><span> </span><span>'auth'</span></div></div><div><div><div>70</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>71</div></div><div><span>        </span><span>extraIcon2</span><span>:</span><span> {</span></div></div><div><div><div>72</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>'#666666'</span><span>,</span></div></div><div><div><div>73</div></div><div><span>          </span><span>size</span><span>:</span><span> </span><span>'22'</span><span>,</span></div></div><div><div><div>74</div></div><div><span>          </span><span>type</span><span>:</span><span> </span><span>'cart'</span></div></div><div><div><div>75</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>76</div></div><div><span>        </span><span>extraIcon3</span><span>:</span><span> {</span></div></div><div><div><div>77</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>'#666666'</span><span>,</span></div></div><div><div><div>78</div></div><div><span>          </span><span>size</span><span>:</span><span> </span><span>'22'</span><span>,</span></div></div><div><div><div>79</div></div><div><span>          </span><span>type</span><span>:</span><span> </span><span>'chatboxes'</span></div></div><div><div><div>80</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>81</div></div><div><span>        </span><span>extraIcon4</span><span>:</span><span> {</span></div></div><div><div><div>82</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>'#666666'</span><span>,</span></div></div><div><div><div>83</div></div><div><span>          </span><span>size</span><span>:</span><span> </span><span>'22'</span><span>,</span></div></div><div><div><div>84</div></div><div><span>          </span><span>type</span><span>:</span><span> </span><span>'email'</span></div></div><div><div><div>85</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>86</div></div><div><span>        </span><span>extraIcon5</span><span>:</span><span> {</span></div></div><div><div><div>87</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>'#666666'</span><span>,</span></div></div><div><div><div>88</div></div><div><span>          </span><span>size</span><span>:</span><span> </span><span>'22'</span><span>,</span></div></div><div><div><div>89</div></div><div><span>          </span><span>type</span><span>:</span><span> </span><span>'gift'</span></div></div><div><div><div>90</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>91</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>92</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>93</div></div><div><span>    </span><span>methods</span><span>:</span><span> {</span></div></div><div><div><div>94</div></div><div><span>      </span><span>setFun</span><span>() {</span></div></div><div><div><div>95</div></div><div><span><span>        </span></span><span>uni</span><span>.</span><span>showToast</span><span>({</span></div></div><div><div><div>96</div></div><div><span>          </span><span>title</span><span>:</span><span> </span><span>"点击设置"</span><span>,</span></div></div><div><div><div>97</div></div><div><span>          </span><span>icon</span><span>:</span><span> </span><span>"none"</span></div></div><div><div><div>98</div></div><div><span><span>        </span></span><span>})</span></div></div><div><div><div>99</div></div><div><span><span>      </span></span><span>},</span></div></div><div><div><div>100</div></div><div><span>      </span><span>clickList</span><span>() {</span></div></div><div><div><div>101</div></div><div><span><span>        </span></span><span>uni</span><span>.</span><span>showToast</span><span>({</span></div></div><div><div><div>102</div></div><div><span>          </span><span>title</span><span>:</span><span> </span><span>"点击列表"</span><span>,</span></div></div><div><div><div>103</div></div><div><span>          </span><span>icon</span><span>:</span><span> </span><span>"none"</span></div></div><div><div><div>104</div></div><div><span><span>        </span></span><span>})</span></div></div><div><div><div>105</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>106</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>107</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>108</div></div><div><span>&lt;/</span><span>script</span><span>&gt;</span></div></div><div><div><div>109</div></div><div>
</div></div><div><div><div>110</div></div><div><span>&lt;</span><span>style</span><span> </span><span>scoped</span><span>&gt;</span></div></div><div><div><div>111</div></div><div><span>  </span><span>.tops</span><span> {</span></div></div><div><div><div>112</div></div><div><span><span>    </span></span><span>position: </span><span>relative</span><span>;</span></div></div><div><div><div>113</div></div><div><span><span>    </span></span><span>height: </span><span>580</span><span>rpx;</span></div></div><div><div><div>114</div></div><div><span><span>    </span></span><span>background-color: </span><span>aquamarine</span><span>;</span></div></div><div><div><div>115</div></div><div><span><span>    </span></span><span>background: </span><span>url</span><span>(</span><span>"https://img1.baidu.com/it/u=3643237076,897388802&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=800&amp;h=400"</span><span><span>) </span><span>no-repeat</span><span>;</span></span></div></div><div><div><div>116</div></div><div><span><span>    </span></span><span>background-size: </span><span><span>100</span><span>%</span></span><span> </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>117</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>118</div></div><div>
</div></div><div><div><div>119</div></div><div><span>  </span><span>.setIcon</span><span> {</span></div></div><div><div><div>120</div></div><div><span><span>    </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>121</div></div><div><span><span>    </span></span><span>top: </span><span>50</span><span>rpx;</span></div></div><div><div><div>122</div></div><div><span><span>    </span></span><span>right: </span><span>50</span><span>rpx;</span></div></div><div><div><div>123</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>124</div></div><div>
</div></div><div><div><div>125</div></div><div><span>  </span><span>.lists</span><span> {</span></div></div><div><div><div>126</div></div><div><span><span>    </span></span><span>padding: </span><span>20</span><span>rpx;</span></div></div><div><div><div>127</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>128</div></div><div>
</div></div><div><div><div>129</div></div><div><span>  </span><span>.tops</span><span> </span><span>.infos</span><span> {</span></div></div><div><div><div>130</div></div><div><span><span>    </span></span><span>width: </span><span><span>80</span><span>%</span></span><span>;</span></div></div><div><div><div>131</div></div><div><span><span>    </span></span><span>height: </span><span>450</span><span>rpx;</span></div></div><div><div><div>132</div></div><div><span><span>    </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>133</div></div><div><span><span>    </span></span><span>top: </span><span><span>40</span><span>%</span></span><span>;</span></div></div><div><div><div>134</div></div><div><span><span>    </span></span><span>left: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>135</div></div><div><span><span>    </span></span><span>transform: </span><span>translate</span><span>(</span><span><span>-50</span><span>%</span></span><span>, </span><span><span>-25</span><span>%</span></span><span>);</span></div></div><div><div><div>136</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>137</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>138</div></div><div>
</div></div><div><div><div>139</div></div><div><span>  </span><span>.infos</span><span> </span><span>image</span><span> {</span></div></div><div><div><div>140</div></div><div><span><span>    </span></span><span>width: </span><span>120</span><span>rpx;</span></div></div><div><div><div>141</div></div><div><span><span>    </span></span><span>height: </span><span>120</span><span>rpx;</span></div></div><div><div><div>142</div></div><div><span><span>    </span></span><span>border-radius: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>143</div></div><div><span><span>    </span></span><span>border: </span><span>4</span><span><span>rpx </span><span>solid</span><span> </span></span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>144</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>145</div></div><div>
</div></div><div><div><div>146</div></div><div><span>  </span><span>.infos</span><span> </span><span>.names</span><span> {</span></div></div><div><div><div>147</div></div><div><span><span>    </span></span><span>font-size: </span><span>34</span><span>rpx;</span></div></div><div><div><div>148</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>333</span><span>;</span></div></div><div><div><div>149</div></div><div><span><span>    </span></span><span>font-weight: </span><span>700</span><span>;</span></div></div><div><div><div>150</div></div><div><span><span>    </span></span><span>margin: </span><span>20</span><span>rpx </span><span>0</span><span> </span><span>10</span><span>rpx;</span></div></div><div><div><div>151</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>152</div></div><div>
</div></div><div><div><div>153</div></div><div><span>  </span><span>.infos</span><span> </span><span>.desc</span><span> {</span></div></div><div><div><div>154</div></div><div><span><span>    </span></span><span>max-width: </span><span><span>62</span><span>%</span></span><span>;</span></div></div><div><div><div>155</div></div><div><span><span>    </span></span><span>font-size: </span><span>28</span><span>rpx;</span></div></div><div><div><div>156</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>333</span><span>;</span></div></div><div><div><div>157</div></div><div><span><span>    </span></span><span>margin: </span><span>10</span><span><span>rpx </span><span>auto</span><span>;</span></span></div></div><div><div><div>158</div></div><div><span><span>    </span></span><span>overflow: </span><span>hidden</span><span>;</span></div></div><div><div><div>159</div></div><div><span><span>    </span></span><span>text-overflow: </span><span>ellipsis</span><span>;</span></div></div><div><div><div>160</div></div><div><span><span>    </span></span><span>white-space: </span><span>nowrap</span><span>;</span></div></div><div><div><div>161</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>162</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>163</div></div><div>
</div></div><div><div><div>164</div></div><div><span>  </span><span>.infos</span><span> </span><span>.t-list</span><span> {</span></div></div><div><div><div>165</div></div><div><span><span>    </span></span><span>margin-top: </span><span>60</span><span>rpx;</span></div></div><div><div><div>166</div></div><div><span><span>    </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>167</div></div><div><span><span>    </span></span><span>justify-content: </span><span>space-around</span><span>;</span></div></div><div><div><div>168</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>169</div></div><div>
</div></div><div><div><div>170</div></div><div><span>  </span><span>.t-item</span><span> </span><span>.tit</span><span> {</span></div></div><div><div><div>171</div></div><div><span><span>    </span></span><span>font-size: </span><span>32</span><span>rpx;</span></div></div><div><div><div>172</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>333</span><span>;</span></div></div><div><div><div>173</div></div><div><span><span>    </span></span><span>margin-bottom: </span><span>10</span><span>rpx;</span></div></div><div><div><div>174</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>175</div></div><div>
</div></div><div><div><div>176</div></div><div><span>  </span><span>.t-item</span><span> </span><span>.vals</span><span> {</span></div></div><div><div><div>177</div></div><div><span><span>    </span></span><span>font-size: </span><span>36</span><span>rpx;</span></div></div><div><div><div>178</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>333</span><span>;</span></div></div><div><div><div>179</div></div><div><span><span>    </span></span><span>font-weight: </span><span>700</span><span>;</span></div></div><div><div><div>180</div></div><div><span><span>    </span></span><span>margin-bottom: </span><span>10</span><span>rpx;</span></div></div><div><div><div>181</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>182</div></div><div>
</div></div><div><div><div>183</div></div><div><span>  </span><span>/deep/</span><span>.uni-list-item__content-title</span><span>[</span><span>data-v-296a3d7e</span><span>]</span><span> {</span></div></div><div><div><div>184</div></div><div><span><span>    </span></span><span>font-size: </span><span>30</span><span>rpx;</span></div></div><div><div><div>185</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>333</span><span>;</span></div></div><div><div><div>186</div></div><div><span><span>    </span></span><span>overflow: </span><span>hidden</span><span>;</span></div></div><div><div><div>187</div></div><div><span><span>    </span></span><span>font-weight: </span><span>500</span><span>;</span></div></div><div><div><div>188</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>189</div></div><div>
</div></div><div><div><div>190</div></div><div><span>  </span><span>/deep/</span><span>.uni-list-item__container</span><span> {</span></div></div><div><div><div>191</div></div><div><span><span>    </span></span><span>padding: </span><span>30</span><span>rpx;</span></div></div><div><div><div>192</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>193</div></div><div><span>&lt;/</span><span>style</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>第二个蓝色（图二）<a href="#第二个蓝色图二"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>template</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"content"</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"topBox"</span><span>&gt;</span></div></div><div><div><div>4</div></div><div><span><span>      </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"setbox"</span><span>&gt;</span></div></div><div><div><div>5</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"set-left"</span><span>&gt;</span></div></div><div><div><div>6</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"calendar"</span><span> </span><span>size</span><span>=</span><span>"30"</span><span> </span><span>color</span><span>=</span><span>"#fff"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>7</div></div><div><span><span>          </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"txt"</span><span>&gt;签到&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>8</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>9</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"set-right"</span><span>&gt;</span></div></div><div><div><div>10</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"gear"</span><span> </span><span>size</span><span>=</span><span>"30"</span><span> </span><span>color</span><span>=</span><span>"#fff"</span><span> </span><span>@click</span><span>=</span><span>"setFun"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>11</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"chat"</span><span> </span><span>size</span><span>=</span><span>"30"</span><span> </span><span>color</span><span>=</span><span>"#fff"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>12</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span><span>      </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"users"</span><span>&gt;</span></div></div><div><div><div>16</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"u-top"</span><span>&gt;</span></div></div><div><div><div>17</div></div><div><span><span>          </span></span><span>&lt;</span><span>image</span></div></div><div><div><div>18</div></div><div><span>            </span><span>src</span><span>=</span><span>"https://img2.baidu.com/it/u=2953585264,744730101&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=360&amp;h=360"</span></div></div><div><div><div>19</div></div><div><span>            </span><span>mode</span><span>=</span><span>""</span><span>&gt;&lt;/</span><span>image</span><span>&gt;</span></div></div><div><div><div>20</div></div><div><span><span>          </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"tit"</span><span>&gt;</span></div></div><div><div><div>21</div></div><div><span><span>            </span></span><span>登录 / 注册</span></div></div><div><div><div>22</div></div><div><span><span>          </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>23</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>24</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"u-bottom"</span><span>&gt;</span></div></div><div><div><div>25</div></div><div><span><span>          </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"u-item"</span><span>&gt;</span></div></div><div><div><div>26</div></div><div><span><span>            </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"num"</span><span>&gt;12&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>27</div></div><div><span><span>            </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"u-tit"</span><span>&gt;浏览&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>28</div></div><div><span><span>          </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>29</div></div><div><span><span>          </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"u-item"</span><span>&gt;</span></div></div><div><div><div>30</div></div><div><span><span>            </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"num"</span><span>&gt;12&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>31</div></div><div><span><span>            </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"u-tit"</span><span>&gt;浏览&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>32</div></div><div><span><span>          </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>33</div></div><div><span><span>          </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"u-item"</span><span>&gt;</span></div></div><div><div><div>34</div></div><div><span><span>            </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"num"</span><span>&gt;12&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>35</div></div><div><span><span>            </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"u-tit"</span><span>&gt;浏览&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>36</div></div><div><span><span>          </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>37</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>38</div></div><div><span><span>      </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>39</div></div><div><span><span>    </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>40</div></div><div>
</div></div><div><div><div>41</div></div><div><span><span>    </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"bottomBox"</span><span>&gt;</span></div></div><div><div><div>42</div></div><div><span><span>      </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"order-list"</span><span>&gt;</span></div></div><div><div><div>43</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"o-item"</span><span>&gt;</span></div></div><div><div><div>44</div></div><div><span><span>          </span></span><span>&lt;</span><span>image</span><span> </span><span>src</span><span>=</span><span>"../../static/daifuk.png"</span><span> </span><span>mode</span><span>=</span><span>""</span><span>&gt;&lt;/</span><span>image</span><span>&gt;</span></div></div><div><div><div>45</div></div><div><span><span>          </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"tit"</span><span>&gt;待付款&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>46</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>47</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"o-item"</span><span>&gt;</span></div></div><div><div><div>48</div></div><div><span><span>          </span></span><span>&lt;</span><span>image</span><span> </span><span>src</span><span>=</span><span>"../../static/daifa.png"</span><span> </span><span>mode</span><span>=</span><span>""</span><span>&gt;&lt;/</span><span>image</span><span>&gt;</span></div></div><div><div><div>49</div></div><div><span><span>          </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"tit"</span><span>&gt;待发货&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>50</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>51</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"o-item"</span><span>&gt;</span></div></div><div><div><div>52</div></div><div><span><span>          </span></span><span>&lt;</span><span>image</span><span> </span><span>src</span><span>=</span><span>"../../static/yifa.png"</span><span> </span><span>mode</span><span>=</span><span>""</span><span>&gt;&lt;/</span><span>image</span><span>&gt;</span></div></div><div><div><div>53</div></div><div><span><span>          </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"tit"</span><span>&gt;已发货&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>54</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>55</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"o-item"</span><span>&gt;</span></div></div><div><div><div>56</div></div><div><span><span>          </span></span><span>&lt;</span><span>image</span><span> </span><span>src</span><span>=</span><span>"../../static/wancheng.png"</span><span> </span><span>mode</span><span>=</span><span>""</span><span>&gt;&lt;/</span><span>image</span><span>&gt;</span></div></div><div><div><div>57</div></div><div><span><span>          </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"tit"</span><span>&gt;已完成&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>58</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>59</div></div><div><span><span>      </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>60</div></div><div><span><span>    </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>61</div></div><div>
</div></div><div><div><div>62</div></div><div><span><span>    </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"listBox"</span><span>&gt;</span></div></div><div><div><div>63</div></div><div><span><span>      </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"lists"</span><span>&gt;</span></div></div><div><div><div>64</div></div><div><span><span>        </span></span><span>&lt;</span><span>uni-list</span><span>&gt;</span></div></div><div><div><div>65</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-list-item</span><span> </span><span>:show-extra-icon</span><span>=</span><span>"true"</span><span> </span><span>:extra-icon</span><span>=</span><span>"extraIcon1"</span><span> </span><span>showArrow</span><span> </span><span>title</span><span>=</span><span>"个人信息"</span><span> </span><span>clickable</span></div></div><div><div><div>66</div></div><div><span>            </span><span>@click</span><span>=</span><span>"clickList"</span><span> </span><span>rightText</span><span>=</span><span>"右侧文字"</span><span> /&gt;</span></div></div><div><div><div>67</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-list-item</span><span> </span><span>:show-extra-icon</span><span>=</span><span>"true"</span><span> </span><span>:extra-icon</span><span>=</span><span>"extraIcon2"</span><span> </span><span>showArrow</span><span> </span><span>title</span><span>=</span><span>"我的购物车"</span><span> </span><span>clickable</span></div></div><div><div><div>68</div></div><div><span>            </span><span>@click</span><span>=</span><span>"clickList"</span><span> </span><span>rightText</span><span>=</span><span>"右侧文字"</span><span> /&gt;</span></div></div><div><div><div>69</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-list-item</span><span> </span><span>:show-extra-icon</span><span>=</span><span>"true"</span><span> </span><span>:extra-icon</span><span>=</span><span>"extraIcon3"</span><span> </span><span>showArrow</span><span> </span><span>title</span><span>=</span><span>"用户反馈"</span><span> </span><span>clickable</span></div></div><div><div><div>70</div></div><div><span>            </span><span>@click</span><span>=</span><span>"clickList"</span><span> /&gt;</span></div></div><div><div><div>71</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-list-item</span><span> </span><span>:show-extra-icon</span><span>=</span><span>"true"</span><span> </span><span>:extra-icon</span><span>=</span><span>"extraIcon4"</span><span> </span><span>showArrow</span><span> </span><span>title</span><span>=</span><span>"我的邮件"</span><span> </span><span>clickable</span></div></div><div><div><div>72</div></div><div><span>            </span><span>@click</span><span>=</span><span>"clickList"</span><span> /&gt;</span></div></div><div><div><div>73</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-list-item</span><span> </span><span>:show-extra-icon</span><span>=</span><span>"true"</span><span> </span><span>:extra-icon</span><span>=</span><span>"extraIcon5"</span><span> </span><span>showArrow</span><span> </span><span>title</span><span>=</span><span>"分享有礼"</span><span> </span><span>clickable</span></div></div><div><div><div>74</div></div><div><span>            </span><span>@click</span><span>=</span><span>"clickList"</span><span> /&gt;</span></div></div><div><div><div>75</div></div><div><span><span>        </span></span><span>&lt;/</span><span>uni-list</span><span>&gt;</span></div></div><div><div><div>76</div></div><div><span><span>      </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>77</div></div><div><span><span>    </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>78</div></div><div>
</div></div><div><div><div>79</div></div><div><span><span>  </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>80</div></div><div><span>&lt;/</span><span>template</span><span>&gt;</span></div></div><div><div><div>81</div></div><div>
</div></div><div><div><div>82</div></div><div><span>&lt;</span><span>script</span><span>&gt;</span></div></div><div><div><div>83</div></div><div><span>  </span><span>export</span><span> </span><span>default</span><span> {</span></div></div><div><div><div>84</div></div><div><span>    </span><span>data</span><span>() {</span></div></div><div><div><div>85</div></div><div><span>      </span><span>return</span><span> {</span></div></div><div><div><div>86</div></div><div><span>        </span><span>extraIcon1</span><span>:</span><span> {</span></div></div><div><div><div>87</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>'#666666'</span><span>,</span></div></div><div><div><div>88</div></div><div><span>          </span><span>size</span><span>:</span><span> </span><span>'22'</span><span>,</span></div></div><div><div><div>89</div></div><div><span>          </span><span>type</span><span>:</span><span> </span><span>'auth'</span></div></div><div><div><div>90</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>91</div></div><div><span>        </span><span>extraIcon2</span><span>:</span><span> {</span></div></div><div><div><div>92</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>'#666666'</span><span>,</span></div></div><div><div><div>93</div></div><div><span>          </span><span>size</span><span>:</span><span> </span><span>'22'</span><span>,</span></div></div><div><div><div>94</div></div><div><span>          </span><span>type</span><span>:</span><span> </span><span>'cart'</span></div></div><div><div><div>95</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>96</div></div><div><span>        </span><span>extraIcon3</span><span>:</span><span> {</span></div></div><div><div><div>97</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>'#666666'</span><span>,</span></div></div><div><div><div>98</div></div><div><span>          </span><span>size</span><span>:</span><span> </span><span>'22'</span><span>,</span></div></div><div><div><div>99</div></div><div><span>          </span><span>type</span><span>:</span><span> </span><span>'chatboxes'</span></div></div><div><div><div>100</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>101</div></div><div><span>        </span><span>extraIcon4</span><span>:</span><span> {</span></div></div><div><div><div>102</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>'#666666'</span><span>,</span></div></div><div><div><div>103</div></div><div><span>          </span><span>size</span><span>:</span><span> </span><span>'22'</span><span>,</span></div></div><div><div><div>104</div></div><div><span>          </span><span>type</span><span>:</span><span> </span><span>'email'</span></div></div><div><div><div>105</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>106</div></div><div><span>        </span><span>extraIcon5</span><span>:</span><span> {</span></div></div><div><div><div>107</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>'#666666'</span><span>,</span></div></div><div><div><div>108</div></div><div><span>          </span><span>size</span><span>:</span><span> </span><span>'22'</span><span>,</span></div></div><div><div><div>109</div></div><div><span>          </span><span>type</span><span>:</span><span> </span><span>'gift'</span></div></div><div><div><div>110</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>111</div></div><div>
</div></div><div><div><div>112</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>113</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>114</div></div><div><span>    </span><span>methods</span><span>:</span><span> {</span></div></div><div><div><div>115</div></div><div><span>      </span><span>setFun</span><span>() {</span></div></div><div><div><div>116</div></div><div><span><span>        </span></span><span>uni</span><span>.</span><span>showToast</span><span>({</span></div></div><div><div><div>117</div></div><div><span>          </span><span>title</span><span>:</span><span> </span><span>"点击设置"</span><span>,</span></div></div><div><div><div>118</div></div><div><span>          </span><span>icon</span><span>:</span><span> </span><span>"none"</span></div></div><div><div><div>119</div></div><div><span><span>        </span></span><span>})</span></div></div><div><div><div>120</div></div><div><span><span>      </span></span><span>},</span></div></div><div><div><div>121</div></div><div><span>      </span><span>clickList</span><span>() {</span></div></div><div><div><div>122</div></div><div><span><span>        </span></span><span>uni</span><span>.</span><span>showToast</span><span>({</span></div></div><div><div><div>123</div></div><div><span>          </span><span>title</span><span>:</span><span> </span><span>"点击列表"</span><span>,</span></div></div><div><div><div>124</div></div><div><span>          </span><span>icon</span><span>:</span><span> </span><span>"none"</span></div></div><div><div><div>125</div></div><div><span><span>        </span></span><span>})</span></div></div><div><div><div>126</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>127</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>128</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>129</div></div><div><span>&lt;/</span><span>script</span><span>&gt;</span></div></div><div><div><div>130</div></div><div>
</div></div><div><div><div>131</div></div><div><span>&lt;</span><span>style</span><span> </span><span>scoped</span><span>&gt;</span></div></div><div><div><div>132</div></div><div><span>  </span><span>.content</span><span> {</span></div></div><div><div><div>133</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>f5f5f5</span><span>;</span></div></div><div><div><div>134</div></div><div><span><span>    </span></span><span>height: </span><span><span>100</span><span>vh</span></span><span>;</span></div></div><div><div><div>135</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>136</div></div><div>
</div></div><div><div><div>137</div></div><div><span>  </span><span>/* 弧形背景 */</span></div></div><div><div><div>138</div></div><div><span>  </span><span>.topBox</span><span> {</span></div></div><div><div><div>139</div></div><div><span><span>    </span></span><span>width: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>140</div></div><div><span><span>    </span></span><span>position: </span><span>relative</span><span>;</span></div></div><div><div><div>141</div></div><div><span><span>    </span></span><span>z-index: </span><span>1</span><span>;</span></div></div><div><div><div>142</div></div><div><span><span>    </span></span><span>overflow: </span><span>hidden</span><span>;</span></div></div><div><div><div>143</div></div><div><span><span>    </span></span><span>padding: </span><span>60</span><span>rpx </span><span>20</span><span>rpx </span><span>20</span><span>rpx;</span></div></div><div><div><div>144</div></div><div><span><span>    </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>145</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>146</div></div><div>
</div></div><div><div><div>147</div></div><div><span>  </span><span><span>.topBox</span><span>::after</span></span><span> {</span></div></div><div><div><div>148</div></div><div><span><span>    </span></span><span>content: </span><span>""</span><span>;</span></div></div><div><div><div>149</div></div><div><span><span>    </span></span><span>width: </span><span><span>140</span><span>%</span></span><span>;</span></div></div><div><div><div>150</div></div><div><span><span>    </span></span><span>height: </span><span><span>200</span><span>px</span></span><span>;</span></div></div><div><div><div>151</div></div><div><span><span>    </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>152</div></div><div><span><span>    </span></span><span>left: </span><span><span>-20</span><span>%</span></span><span>;</span></div></div><div><div><div>153</div></div><div><span><span>    </span></span><span>top: </span><span>0</span><span>;</span></div></div><div><div><div>154</div></div><div><span><span>    </span></span><span>z-index: </span><span>-1</span><span>;</span></div></div><div><div><div>155</div></div><div><span><span>    </span></span><span>border-radius: </span><span>0</span><span> </span><span>0</span><span> </span><span><span>50</span><span>%</span></span><span> </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>156</div></div><div><span><span>    </span></span><span>background: </span><span>#</span><span>00aaff</span><span>;</span></div></div><div><div><div>157</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>158</div></div><div>
</div></div><div><div><div>159</div></div><div><span>  </span><span>/* 弧形背景 */</span></div></div><div><div><div>160</div></div><div>
</div></div><div><div><div>161</div></div><div><span>  </span><span>.setbox</span><span> {</span></div></div><div><div><div>162</div></div><div><span><span>    </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>163</div></div><div><span><span>    </span></span><span>justify-content: </span><span>space-between</span><span>;</span></div></div><div><div><div>164</div></div><div><span><span>    </span></span><span>align-items: </span><span>center</span><span>;</span></div></div><div><div><div>165</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>166</div></div><div>
</div></div><div><div><div>167</div></div><div><span>  </span><span>.set-left</span><span> {</span></div></div><div><div><div>168</div></div><div><span><span>    </span></span><span>width: </span><span><span>18</span><span>%</span></span><span>;</span></div></div><div><div><div>169</div></div><div><span><span>    </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>170</div></div><div><span><span>    </span></span><span>justify-content: </span><span>space-between</span><span>;</span></div></div><div><div><div>171</div></div><div><span><span>    </span></span><span>align-items: </span><span>center</span><span>;</span></div></div><div><div><div>172</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>173</div></div><div>
</div></div><div><div><div>174</div></div><div><span>  </span><span>.txt</span><span> {</span></div></div><div><div><div>175</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>176</div></div><div><span><span>    </span></span><span>font-size: </span><span>30</span><span>rpx;</span></div></div><div><div><div>177</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>178</div></div><div>
</div></div><div><div><div>179</div></div><div><span>  </span><span>.set-right</span><span> </span><span>.uni-icons</span><span> {</span></div></div><div><div><div>180</div></div><div><span><span>    </span></span><span>margin-right: </span><span>10</span><span>rpx;</span></div></div><div><div><div>181</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>182</div></div><div>
</div></div><div><div><div>183</div></div><div><span>  </span><span>.users</span><span> {</span></div></div><div><div><div>184</div></div><div><span><span>    </span></span><span>margin-top: </span><span>20</span><span>rpx;</span></div></div><div><div><div>185</div></div><div><span><span>    </span></span><span>padding: </span><span>30</span><span>rpx;</span></div></div><div><div><div>186</div></div><div><span><span>    </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>187</div></div><div><span><span>    </span></span><span>height: </span><span>280</span><span>rpx;</span></div></div><div><div><div>188</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>189</div></div><div><span><span>    </span></span><span>box-shadow: </span><span><span>1</span><span>px</span></span><span> </span><span>10</span><span>rpx </span><span>20</span><span>rpx </span><span>#</span><span>ececec</span><span>;</span></div></div><div><div><div>190</div></div><div><span><span>    </span></span><span>border-radius: </span><span>12</span><span>rpx;</span></div></div><div><div><div>191</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>192</div></div><div>
</div></div><div><div><div>193</div></div><div><span>  </span><span>.u-top</span><span> {</span></div></div><div><div><div>194</div></div><div><span><span>    </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>195</div></div><div><span><span>    </span></span><span>justify-content: </span><span>flex-start</span><span>;</span></div></div><div><div><div>196</div></div><div><span><span>    </span></span><span>align-items: </span><span>center</span><span>;</span></div></div><div><div><div>197</div></div><div><span><span>    </span></span><span>margin-bottom: </span><span>30</span><span>rpx;</span></div></div><div><div><div>198</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>199</div></div><div>
</div></div><div><div><div>200</div></div><div><span>  </span><span>.users</span><span> </span><span>.u-top</span><span> </span><span>image</span><span> {</span></div></div><div><div><div>201</div></div><div><span><span>    </span></span><span>width: </span><span>100</span><span>rpx;</span></div></div><div><div><div>202</div></div><div><span><span>    </span></span><span>height: </span><span>100</span><span>rpx;</span></div></div><div><div><div>203</div></div><div><span><span>    </span></span><span>border-radius: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>204</div></div><div><span><span>    </span></span><span>margin-right: </span><span>20</span><span>rpx;</span></div></div><div><div><div>205</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>206</div></div><div>
</div></div><div><div><div>207</div></div><div><span>  </span><span>.u-top</span><span> </span><span>.tit</span><span> {</span></div></div><div><div><div>208</div></div><div><span><span>    </span></span><span>font-size: </span><span>30</span><span>rpx;</span></div></div><div><div><div>209</div></div><div><span><span>    </span></span><span>font-weight: </span><span>700</span><span>;</span></div></div><div><div><div>210</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>333</span><span>;</span></div></div><div><div><div>211</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>212</div></div><div>
</div></div><div><div><div>213</div></div><div><span>  </span><span>.u-bottom</span><span> {</span></div></div><div><div><div>214</div></div><div><span><span>    </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>215</div></div><div><span><span>    </span></span><span>justify-content: </span><span>space-around</span><span>;</span></div></div><div><div><div>216</div></div><div><span><span>    </span></span><span>align-items: </span><span>center</span><span>;</span></div></div><div><div><div>217</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>218</div></div><div>
</div></div><div><div><div>219</div></div><div><span>  </span><span>.u-item</span><span> {</span></div></div><div><div><div>220</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>221</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>222</div></div><div>
</div></div><div><div><div>223</div></div><div><span>  </span><span>.u-item</span><span> </span><span>.u-tit</span><span> {</span></div></div><div><div><div>224</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>757575</span><span>;</span></div></div><div><div><div>225</div></div><div><span><span>    </span></span><span>font-size: </span><span>26</span><span>rpx;</span></div></div><div><div><div>226</div></div><div><span><span>    </span></span><span>margin-top: </span><span>10</span><span>rpx;</span></div></div><div><div><div>227</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>228</div></div><div>
</div></div><div><div><div>229</div></div><div><span>  </span><span>.u-item</span><span> </span><span>.num</span><span> {</span></div></div><div><div><div>230</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>000000</span><span>;</span></div></div><div><div><div>231</div></div><div><span><span>    </span></span><span>font-size: </span><span>33</span><span>rpx;</span></div></div><div><div><div>232</div></div><div><span><span>    </span></span><span>font-weight: </span><span>700</span><span>;</span></div></div><div><div><div>233</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>234</div></div><div>
</div></div><div><div><div>235</div></div><div><span>  </span><span>.bottomBox</span><span> {</span></div></div><div><div><div>236</div></div><div><span><span>    </span></span><span>padding: </span><span>20</span><span>rpx;</span></div></div><div><div><div>237</div></div><div><span><span>    </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>238</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>239</div></div><div>
</div></div><div><div><div>240</div></div><div><span>  </span><span>.order-list</span><span> {</span></div></div><div><div><div>241</div></div><div><span><span>    </span></span><span>height: </span><span>200</span><span>rpx;</span></div></div><div><div><div>242</div></div><div><span><span>    </span></span><span>margin: </span><span>-15</span><span><span>rpx </span><span>auto</span><span> </span></span><span>0</span><span>;</span></div></div><div><div><div>243</div></div><div><span><span>    </span></span><span>padding: </span><span>30</span><span>rpx;</span></div></div><div><div><div>244</div></div><div><span><span>    </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>245</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>246</div></div><div><span><span>    </span></span><span>border-radius: </span><span>12</span><span>rpx;</span></div></div><div><div><div>247</div></div><div><span><span>    </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>248</div></div><div><span><span>    </span></span><span>justify-content: </span><span>space-around</span><span>;</span></div></div><div><div><div>249</div></div><div><span><span>    </span></span><span>align-items: </span><span>center</span><span>;</span></div></div><div><div><div>250</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>251</div></div><div>
</div></div><div><div><div>252</div></div><div><span>  </span><span>.o-item</span><span> {</span></div></div><div><div><div>253</div></div><div><span><span>    </span></span><span>width: </span><span><span>25</span><span>%</span></span><span>;</span></div></div><div><div><div>254</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>255</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>256</div></div><div>
</div></div><div><div><div>257</div></div><div><span>  </span><span>.o-item</span><span> </span><span>image</span><span> {</span></div></div><div><div><div>258</div></div><div><span><span>    </span></span><span>width: </span><span>65</span><span>rpx;</span></div></div><div><div><div>259</div></div><div><span><span>    </span></span><span>height: </span><span>55</span><span>rpx;</span></div></div><div><div><div>260</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>261</div></div><div>
</div></div><div><div><div>262</div></div><div><span>  </span><span>.o-item</span><span> </span><span>.tit</span><span> {</span></div></div><div><div><div>263</div></div><div><span><span>    </span></span><span>font-size: </span><span>28</span><span>rpx;</span></div></div><div><div><div>264</div></div><div><span><span>    </span></span><span>margin-top: </span><span>10</span><span>rpx;</span></div></div><div><div><div>265</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>266</div></div><div>
</div></div><div><div><div>267</div></div><div><span>  </span><span>.listBox</span><span> {</span></div></div><div><div><div>268</div></div><div><span><span>    </span></span><span>height: </span><span>200</span><span>rpx;</span></div></div><div><div><div>269</div></div><div><span><span>    </span></span><span>margin: </span><span>-10</span><span><span>rpx </span><span>auto</span><span> </span></span><span>0</span><span>;</span></div></div><div><div><div>270</div></div><div><span><span>    </span></span><span>padding: </span><span>20</span><span>rpx;</span></div></div><div><div><div>271</div></div><div><span><span>    </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>272</div></div><div><span><span>    </span></span><span>border-radius: </span><span>12</span><span>rpx;</span></div></div><div><div><div>273</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>274</div></div><div><span>&lt;/</span><span>style</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>第三个绿色（图三）<a href="#第三个绿色图三"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>template</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"content"</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"topBox"</span><span>&gt;</span></div></div><div><div><div>4</div></div><div><span><span>      </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"gear"</span><span> </span><span>size</span><span>=</span><span>"32"</span><span> </span><span>class</span><span>=</span><span>"setIcon"</span><span> </span><span>color</span><span>=</span><span>"#fff"</span><span> </span><span>@click</span><span>=</span><span>"setFun"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>5</div></div><div><span><span>      </span></span><span>&lt;</span><span>image</span><span> </span><span>src</span><span>=</span><span>"https://img0.baidu.com/it/u=464193705,1968194224&amp;fm=253&amp;fmt=auto&amp;app=120&amp;f=JPEG?w=801&amp;h=500"</span><span> </span><span>mode</span><span>=</span><span>"aspectFill"</span><span>&gt;&lt;/</span><span>image</span><span>&gt;</span></div></div><div><div><div>6</div></div><div><span><span>      </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"userName"</span><span>&gt;</span></div></div><div><div><div>7</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"name"</span><span>&gt;</span></div></div><div><div><div>8</div></div><div><span><span>          </span></span><span>着逝者为铠</span></div></div><div><div><div>9</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>10</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"desc"</span><span>&gt;</span></div></div><div><div><div>11</div></div><div><span><span>          </span></span><span>以绝望挥剑,着逝者为铠</span></div></div><div><div><div>12</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"listBox"</span><span>&gt;</span></div></div><div><div><div>17</div></div><div><span><span>      </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"lists"</span><span>&gt;</span></div></div><div><div><div>18</div></div><div><span><span>        </span></span><span>&lt;</span><span>uni-list</span><span>&gt;</span></div></div><div><div><div>19</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-list-item</span><span> </span><span>:show-extra-icon</span><span>=</span><span>"true"</span><span> </span><span>:extra-icon</span><span>=</span><span>"extraIcon1"</span><span> </span><span>showArrow</span><span> </span><span>title</span><span>=</span><span>"个人信息"</span><span> </span><span>clickable</span></div></div><div><div><div>20</div></div><div><span>            </span><span>@click</span><span>=</span><span>"clickList"</span><span> </span><span>rightText</span><span>=</span><span>"右侧文字"</span><span> /&gt;</span></div></div><div><div><div>21</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-list-item</span><span> </span><span>:show-extra-icon</span><span>=</span><span>"true"</span><span> </span><span>:extra-icon</span><span>=</span><span>"extraIcon2"</span><span> </span><span>showArrow</span><span> </span><span>title</span><span>=</span><span>"我的购物车"</span><span> </span><span>clickable</span></div></div><div><div><div>22</div></div><div><span>            </span><span>@click</span><span>=</span><span>"clickList"</span><span> </span><span>rightText</span><span>=</span><span>"右侧文字"</span><span> /&gt;</span></div></div><div><div><div>23</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-list-item</span><span> </span><span>:show-extra-icon</span><span>=</span><span>"true"</span><span> </span><span>:extra-icon</span><span>=</span><span>"extraIcon3"</span><span> </span><span>showArrow</span><span> </span><span>title</span><span>=</span><span>"用户反馈"</span><span> </span><span>clickable</span></div></div><div><div><div>24</div></div><div><span>            </span><span>@click</span><span>=</span><span>"clickList"</span><span> /&gt;</span></div></div><div><div><div>25</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-list-item</span><span> </span><span>:show-extra-icon</span><span>=</span><span>"true"</span><span> </span><span>:extra-icon</span><span>=</span><span>"extraIcon4"</span><span> </span><span>showArrow</span><span> </span><span>title</span><span>=</span><span>"我的邮件"</span><span> </span><span>clickable</span></div></div><div><div><div>26</div></div><div><span>            </span><span>@click</span><span>=</span><span>"clickList"</span><span> /&gt;</span></div></div><div><div><div>27</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-list-item</span><span> </span><span>:show-extra-icon</span><span>=</span><span>"true"</span><span> </span><span>:extra-icon</span><span>=</span><span>"extraIcon5"</span><span> </span><span>showArrow</span><span> </span><span>title</span><span>=</span><span>"分享有礼"</span><span> </span><span>clickable</span></div></div><div><div><div>28</div></div><div><span>            </span><span>@click</span><span>=</span><span>"clickList"</span><span> /&gt;</span></div></div><div><div><div>29</div></div><div><span><span>        </span></span><span>&lt;/</span><span>uni-list</span><span>&gt;</span></div></div><div><div><div>30</div></div><div><span><span>      </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>31</div></div><div><span><span>    </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>32</div></div><div><span><span>  </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>33</div></div><div><span>&lt;/</span><span>template</span><span>&gt;</span></div></div><div><div><div>34</div></div><div>
</div></div><div><div><div>35</div></div><div><span>&lt;</span><span>script</span><span>&gt;</span></div></div><div><div><div>36</div></div><div><span>  </span><span>export</span><span> </span><span>default</span><span> {</span></div></div><div><div><div>37</div></div><div><span>    </span><span>data</span><span>() {</span></div></div><div><div><div>38</div></div><div><span>      </span><span>return</span><span> {</span></div></div><div><div><div>39</div></div><div><span>        </span><span>extraIcon1</span><span>:</span><span> {</span></div></div><div><div><div>40</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>'#666666'</span><span>,</span></div></div><div><div><div>41</div></div><div><span>          </span><span>size</span><span>:</span><span> </span><span>'22'</span><span>,</span></div></div><div><div><div>42</div></div><div><span>          </span><span>type</span><span>:</span><span> </span><span>'auth'</span></div></div><div><div><div>43</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>44</div></div><div><span>        </span><span>extraIcon2</span><span>:</span><span> {</span></div></div><div><div><div>45</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>'#666666'</span><span>,</span></div></div><div><div><div>46</div></div><div><span>          </span><span>size</span><span>:</span><span> </span><span>'22'</span><span>,</span></div></div><div><div><div>47</div></div><div><span>          </span><span>type</span><span>:</span><span> </span><span>'cart'</span></div></div><div><div><div>48</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>49</div></div><div><span>        </span><span>extraIcon3</span><span>:</span><span> {</span></div></div><div><div><div>50</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>'#666666'</span><span>,</span></div></div><div><div><div>51</div></div><div><span>          </span><span>size</span><span>:</span><span> </span><span>'22'</span><span>,</span></div></div><div><div><div>52</div></div><div><span>          </span><span>type</span><span>:</span><span> </span><span>'chatboxes'</span></div></div><div><div><div>53</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>54</div></div><div><span>        </span><span>extraIcon4</span><span>:</span><span> {</span></div></div><div><div><div>55</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>'#666666'</span><span>,</span></div></div><div><div><div>56</div></div><div><span>          </span><span>size</span><span>:</span><span> </span><span>'22'</span><span>,</span></div></div><div><div><div>57</div></div><div><span>          </span><span>type</span><span>:</span><span> </span><span>'email'</span></div></div><div><div><div>58</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>59</div></div><div><span>        </span><span>extraIcon5</span><span>:</span><span> {</span></div></div><div><div><div>60</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>'#666666'</span><span>,</span></div></div><div><div><div>61</div></div><div><span>          </span><span>size</span><span>:</span><span> </span><span>'22'</span><span>,</span></div></div><div><div><div>62</div></div><div><span>          </span><span>type</span><span>:</span><span> </span><span>'gift'</span></div></div><div><div><div>63</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>64</div></div><div>
</div></div><div><div><div>65</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>66</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>67</div></div><div><span>    </span><span>methods</span><span>:</span><span> {</span></div></div><div><div><div>68</div></div><div><span>      </span><span>setFun</span><span>() {</span></div></div><div><div><div>69</div></div><div><span><span>        </span></span><span>uni</span><span>.</span><span>showToast</span><span>({</span></div></div><div><div><div>70</div></div><div><span>          </span><span>title</span><span>:</span><span> </span><span>"点击设置"</span><span>,</span></div></div><div><div><div>71</div></div><div><span>          </span><span>icon</span><span>:</span><span> </span><span>"none"</span></div></div><div><div><div>72</div></div><div><span><span>        </span></span><span>})</span></div></div><div><div><div>73</div></div><div><span><span>      </span></span><span>},</span></div></div><div><div><div>74</div></div><div><span>      </span><span>clickList</span><span>() {</span></div></div><div><div><div>75</div></div><div><span><span>        </span></span><span>uni</span><span>.</span><span>showToast</span><span>({</span></div></div><div><div><div>76</div></div><div><span>          </span><span>title</span><span>:</span><span> </span><span>"点击列表"</span><span>,</span></div></div><div><div><div>77</div></div><div><span>          </span><span>icon</span><span>:</span><span> </span><span>"none"</span></div></div><div><div><div>78</div></div><div><span><span>        </span></span><span>})</span></div></div><div><div><div>79</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>80</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>81</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>82</div></div><div><span>&lt;/</span><span>script</span><span>&gt;</span></div></div><div><div><div>83</div></div><div>
</div></div><div><div><div>84</div></div><div><span>&lt;</span><span>style</span><span> </span><span>scoped</span><span>&gt;</span></div></div><div><div><div>85</div></div><div><span>  </span><span>.content</span><span> {</span></div></div><div><div><div>86</div></div><div><span><span>    </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>87</div></div><div><span><span>    </span></span><span>position: </span><span>relative</span><span>;</span></div></div><div><div><div>88</div></div><div><span><span>    </span></span><span>height: </span><span><span>100</span><span>vh</span></span><span>;</span></div></div><div><div><div>89</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>00aa7f</span><span>;</span></div></div><div><div><div>90</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>91</div></div><div>
</div></div><div><div><div>92</div></div><div><span>  </span><span>.topBox</span><span> {</span></div></div><div><div><div>93</div></div><div><span><span>    </span></span><span>height: </span><span>350</span><span>rpx;</span></div></div><div><div><div>94</div></div><div><span><span>    </span></span><span>padding: </span><span>50</span><span>rpx;</span></div></div><div><div><div>95</div></div><div><span><span>    </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>96</div></div><div><span><span>    </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>97</div></div><div><span><span>    </span></span><span>justify-content: </span><span>flex-start</span><span>;</span></div></div><div><div><div>98</div></div><div><span><span>    </span></span><span>align-items: </span><span>center</span><span>;</span></div></div><div><div><div>99</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>100</div></div><div>
</div></div><div><div><div>101</div></div><div><span>  </span><span>.topBox</span><span> </span><span>image</span><span> {</span></div></div><div><div><div>102</div></div><div><span><span>    </span></span><span>width: </span><span>130</span><span>rpx;</span></div></div><div><div><div>103</div></div><div><span><span>    </span></span><span>height: </span><span>130</span><span>rpx;</span></div></div><div><div><div>104</div></div><div><span><span>    </span></span><span>border-radius: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>105</div></div><div><span><span>    </span></span><span>border: </span><span>3</span><span><span>rpx </span><span>solid</span><span> </span></span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>106</div></div><div><span><span>    </span></span><span>margin-right: </span><span>30</span><span>rpx;</span></div></div><div><div><div>107</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>108</div></div><div>
</div></div><div><div><div>109</div></div><div><span>  </span><span>.topBox</span><span> </span><span>.name</span><span> {</span></div></div><div><div><div>110</div></div><div><span><span>    </span></span><span>font-size: </span><span>42</span><span>rpx;</span></div></div><div><div><div>111</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>112</div></div><div><span><span>    </span></span><span>font-weight: </span><span>700</span><span>;</span></div></div><div><div><div>113</div></div><div><span><span>    </span></span><span>margin-bottom: </span><span>23</span><span>rpx;</span></div></div><div><div><div>114</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>115</div></div><div>
</div></div><div><div><div>116</div></div><div><span>  </span><span>.topBox</span><span> </span><span>.desc</span><span> {</span></div></div><div><div><div>117</div></div><div><span><span>    </span></span><span>font-size: </span><span>28</span><span>rpx;</span></div></div><div><div><div>118</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>ececec</span><span>;</span></div></div><div><div><div>119</div></div><div><span><span>    </span></span><span>margin-bottom: </span><span>10</span><span>rpx;</span></div></div><div><div><div>120</div></div><div><span><span>    </span></span><span>text-overflow: </span><span>ellipsis</span><span>;</span></div></div><div><div><div>121</div></div><div><span><span>    </span></span><span>white-space: </span><span>nowrap</span><span>;</span></div></div><div><div><div>122</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>123</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>124</div></div><div>
</div></div><div><div><div>125</div></div><div><span>  </span><span>.listBox</span><span> {</span></div></div><div><div><div>126</div></div><div><span><span>    </span></span><span>height: </span><span>calc</span><span>(</span><span><span>100</span><span>%</span></span><span><span> </span><span>-</span><span> </span></span><span>330</span><span>rpx);</span></div></div><div><div><div>127</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>ffffff</span><span>;</span></div></div><div><div><div>128</div></div><div><span><span>    </span></span><span>border-top-left-radius: </span><span>30</span><span>rpx;</span></div></div><div><div><div>129</div></div><div><span><span>    </span></span><span>border-top-right-radius: </span><span>30</span><span>rpx;</span></div></div><div><div><div>130</div></div><div><span><span>    </span></span><span>margin-top: </span><span>-20</span><span>rpx;</span></div></div><div><div><div>131</div></div><div><span><span>    </span></span><span>padding: </span><span>30</span><span>rpx </span><span>20</span><span>rpx;</span></div></div><div><div><div>132</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>133</div></div><div>
</div></div><div><div><div>134</div></div><div><span>  </span><span>.setIcon</span><span> {</span></div></div><div><div><div>135</div></div><div><span><span>    </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>136</div></div><div><span><span>    </span></span><span>top: </span><span>50</span><span>rpx;</span></div></div><div><div><div>137</div></div><div><span><span>    </span></span><span>right: </span><span>50</span><span>rpx;</span></div></div><div><div><div>138</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>139</div></div><div><span>&lt;/</span><span>style</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><blockquote><p>最后，页面中用到了一些本地图片和uniapp的组件，为了更好的一键复制使用，我把整体源码-包含上期的登录页面源码和个人中心页面放在了gitee上，如有需要的话，下面附上此项目gitee地址：<a href="https://gitee.com/xt-123/uniapp-pages" target="_blank">https://gitee.com/xt-123/uniapp-pages</a></p></blockquote></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/f2b42afb/</id>
      <title type="text">PC端登录页源码(一键复制)</title>
      <published>2024-08-11T18:31:13.000Z</published>
      <updated>2024-08-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/f2b42afb/"/>
      <summary type="text">登录页面是每一个项目不可缺少的页面，是一个应用的门面，首次进入看见的可能就是登录界面，做了这么久的前端，发现登录界面其实都大同小异，有时候没必要从头写，我写了几个自认为比较好看的uniapp登录界面记录一下，下次用到的话，可以直接复制过来，修改下就行了.只有静态页面，并未做逻辑上的东西，这样便于在此基础上做调整。</summary>
      <content type="html"><![CDATA[<section><h3>先看效果 :eye:<a href="#先看效果-eye"><span>#</span></a></h3><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/08/1499be202c9c43f7b3729502c31411f6" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/08/89753498cef341ceb3cbec1e6d4e3f13" alt="图片" /><figcaption>图片</figcaption></figure><p></p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/08/5a1f6cf1302d4d2b8f8522728ba5da26" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section>
<section><h3>页面源码:eagle:<a href="#页面源码eagle"><span>#</span></a></h3><section><h4>紫色登录界面（图一）：<a href="#紫色登录界面图一"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;!</span><span>DOCTYPE</span><span> </span><span>html</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span>&lt;</span><span>html</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>&lt;</span><span>head</span><span>&gt;</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>&lt;</span><span>meta</span><span> </span><span>charset</span><span>=</span><span>"utf-8"</span><span>&gt;</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>&lt;</span><span>title</span><span>&gt;登录1&lt;/</span><span>title</span><span>&gt;</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>&lt;</span><span>style</span><span>&gt;</span></div></div><div><div><div>7</div></div><div><span>      </span><span>*</span><span> {</span></div></div><div><div><div>8</div></div><div><span><span>        </span></span><span>margin: </span><span>0</span><span>;</span></div></div><div><div><div>9</div></div><div><span><span>        </span></span><span>padding: </span><span>0</span><span>;</span></div></div><div><div><div>10</div></div><div><span><span>        </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>      </span><span>/* 动态背景 */</span></div></div><div><div><div>14</div></div><div><span>      </span><span>@keyframes</span><span><span> </span><span>move</span><span> {</span></span></div></div><div><div><div>15</div></div><div><span><span>        </span></span><span>100% {</span></div></div><div><div><div>16</div></div><div><span><span>          </span></span><span>transform: </span><span>translate3d</span><span>(</span><span>0</span><span>, </span><span>0</span><span>, </span><span><span>1</span><span>px</span></span><span>) </span><span>rotate</span><span>(</span><span><span>360</span><span>deg</span></span><span>);</span></div></div><div><div><div>17</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>18</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>19</div></div><div>
</div></div><div><div><div>20</div></div><div><span>      </span><span>.background</span><span> {</span></div></div><div><div><div>21</div></div><div><span><span>        </span></span><span>position: </span><span>fixed</span><span>;</span></div></div><div><div><div>22</div></div><div><span><span>        </span></span><span>width: </span><span><span>100</span><span>vw</span></span><span>;</span></div></div><div><div><div>23</div></div><div><span><span>        </span></span><span>height: </span><span><span>100</span><span>vh</span></span><span>;</span></div></div><div><div><div>24</div></div><div><span><span>        </span></span><span>top: </span><span>0</span><span>;</span></div></div><div><div><div>25</div></div><div><span><span>        </span></span><span>left: </span><span>0</span><span>;</span></div></div><div><div><div>26</div></div><div><span><span>        </span></span><span>background: </span><span>#</span><span>3E1E68</span><span>;</span></div></div><div><div><div>27</div></div><div><span><span>        </span></span><span>overflow: </span><span>hidden</span><span>;</span></div></div><div><div><div>28</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>29</div></div><div>
</div></div><div><div><div>30</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span> {</span></div></div><div><div><div>31</div></div><div><span><span>        </span></span><span>width: </span><span><span>20</span><span>vmin</span></span><span>;</span></div></div><div><div><div>32</div></div><div><span><span>        </span></span><span>height: </span><span><span>20</span><span>vmin</span></span><span>;</span></div></div><div><div><div>33</div></div><div><span><span>        </span></span><span>border-radius: </span><span><span>20</span><span>vmin</span></span><span>;</span></div></div><div><div><div>34</div></div><div><span><span>        </span></span><span>backface-visibility: </span><span>hidden</span><span>;</span></div></div><div><div><div>35</div></div><div><span><span>        </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>36</div></div><div><span><span>        </span></span><span>animation: </span><span>move</span><span>;</span></div></div><div><div><div>37</div></div><div><span><span>        </span></span><span>animation-duration: </span><span>45</span><span>;</span></div></div><div><div><div>38</div></div><div><span><span>        </span></span><span>animation-timing-function: </span><span>linear</span><span>;</span></div></div><div><div><div>39</div></div><div><span><span>        </span></span><span>animation-iteration-count: </span><span>infinite</span><span>;</span></div></div><div><div><div>40</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>41</div></div><div>
</div></div><div><div><div>42</div></div><div>
</div></div><div><div><div>43</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>0</span><span>)</span><span> {</span></div></div><div><div><div>44</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>FFACAC</span><span>;</span></div></div><div><div><div>45</div></div><div><span><span>        </span></span><span>top: </span><span><span>90</span><span>%</span></span><span>;</span></div></div><div><div><div>46</div></div><div><span><span>        </span></span><span>left: </span><span><span>47</span><span>%</span></span><span>;</span></div></div><div><div><div>47</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>8</span><span>s</span></span><span>;</span></div></div><div><div><div>48</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-17</span><span>s</span></span><span>;</span></div></div><div><div><div>49</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>2</span><span>vw</span></span><span> </span><span><span>17</span><span>vh</span></span><span>;</span></div></div><div><div><div>50</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>-40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.494502440636581</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>51</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>52</div></div><div>
</div></div><div><div><div>53</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>1</span><span>)</span><span> {</span></div></div><div><div><div>54</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>FFACAC</span><span>;</span></div></div><div><div><div>55</div></div><div><span><span>        </span></span><span>top: </span><span><span>31</span><span>%</span></span><span>;</span></div></div><div><div><div>56</div></div><div><span><span>        </span></span><span>left: </span><span><span>5</span><span>%</span></span><span>;</span></div></div><div><div><div>57</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>40</span><span>s</span></span><span>;</span></div></div><div><div><div>58</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-14</span><span>s</span></span><span>;</span></div></div><div><div><div>59</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>-5</span><span>vw</span></span><span> </span><span><span>-14</span><span>vh</span></span><span>;</span></div></div><div><div><div>60</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>-40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.192195104974926</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>61</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>62</div></div><div>
</div></div><div><div><div>63</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>2</span><span>)</span><span> {</span></div></div><div><div><div>64</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>FFACAC</span><span>;</span></div></div><div><div><div>65</div></div><div><span><span>        </span></span><span>top: </span><span><span>18</span><span>%</span></span><span>;</span></div></div><div><div><div>66</div></div><div><span><span>        </span></span><span>left: </span><span><span>62</span><span>%</span></span><span>;</span></div></div><div><div><div>67</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>20</span><span>s</span></span><span>;</span></div></div><div><div><div>68</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-5</span><span>s</span></span><span>;</span></div></div><div><div><div>69</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>-18</span><span>vw</span></span><span> </span><span><span>-12</span><span>vh</span></span><span>;</span></div></div><div><div><div>70</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.72205756381233</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>71</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>72</div></div><div>
</div></div><div><div><div>73</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>3</span><span>)</span><span> {</span></div></div><div><div><div>74</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>FFACAC</span><span>;</span></div></div><div><div><div>75</div></div><div><span><span>        </span></span><span>top: </span><span><span>71</span><span>%</span></span><span>;</span></div></div><div><div><div>76</div></div><div><span><span>        </span></span><span>left: </span><span><span>45</span><span>%</span></span><span>;</span></div></div><div><div><div>77</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>30</span><span>s</span></span><span>;</span></div></div><div><div><div>78</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-2</span><span>s</span></span><span>;</span></div></div><div><div><div>79</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>-4</span><span>vw</span></span><span> </span><span><span>-20</span><span>vh</span></span><span>;</span></div></div><div><div><div>80</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>-40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.303503038071778</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>81</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>82</div></div><div>
</div></div><div><div><div>83</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>4</span><span>)</span><span> {</span></div></div><div><div><div>84</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>E45A84</span><span>;</span></div></div><div><div><div>85</div></div><div><span><span>        </span></span><span>top: </span><span><span>90</span><span>%</span></span><span>;</span></div></div><div><div><div>86</div></div><div><span><span>        </span></span><span>left: </span><span><span>38</span><span>%</span></span><span>;</span></div></div><div><div><div>87</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>15</span><span>s</span></span><span>;</span></div></div><div><div><div>88</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-48</span><span>s</span></span><span>;</span></div></div><div><div><div>89</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>7</span><span>vw</span></span><span> </span><span><span>-9</span><span>vh</span></span><span>;</span></div></div><div><div><div>90</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>-40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.882238754040052</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>91</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>92</div></div><div>
</div></div><div><div><div>93</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>5</span><span>)</span><span> {</span></div></div><div><div><div>94</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>583C87</span><span>;</span></div></div><div><div><div>95</div></div><div><span><span>        </span></span><span>top: </span><span><span>34</span><span>%</span></span><span>;</span></div></div><div><div><div>96</div></div><div><span><span>        </span></span><span>left: </span><span><span>32</span><span>%</span></span><span>;</span></div></div><div><div><div>97</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>30</span><span>s</span></span><span>;</span></div></div><div><div><div>98</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-36</span><span>s</span></span><span>;</span></div></div><div><div><div>99</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>-6</span><span>vw</span></span><span> </span><span><span>-15</span><span>vh</span></span><span>;</span></div></div><div><div><div>100</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.183333217256063</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>101</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>102</div></div><div>
</div></div><div><div><div>103</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>6</span><span>)</span><span> {</span></div></div><div><div><div>104</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>583C87</span><span>;</span></div></div><div><div><div>105</div></div><div><span><span>        </span></span><span>top: </span><span><span>25</span><span>%</span></span><span>;</span></div></div><div><div><div>106</div></div><div><span><span>        </span></span><span>left: </span><span><span>41</span><span>%</span></span><span>;</span></div></div><div><div><div>107</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>21</span><span>s</span></span><span>;</span></div></div><div><div><div>108</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-47</span><span>s</span></span><span>;</span></div></div><div><div><div>109</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>-10</span><span>vw</span></span><span> </span><span><span>-5</span><span>vh</span></span><span>;</span></div></div><div><div><div>110</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.345257098222438</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>111</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>112</div></div><div>
</div></div><div><div><div>113</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>7</span><span>)</span><span> {</span></div></div><div><div><div>114</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>E45A84</span><span>;</span></div></div><div><div><div>115</div></div><div><span><span>        </span></span><span>top: </span><span><span>16</span><span>%</span></span><span>;</span></div></div><div><div><div>116</div></div><div><span><span>        </span></span><span>left: </span><span><span>39</span><span>%</span></span><span>;</span></div></div><div><div><div>117</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>30</span><span>s</span></span><span>;</span></div></div><div><div><div>118</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-33</span><span>s</span></span><span>;</span></div></div><div><div><div>119</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>-15</span><span>vw</span></span><span> </span><span><span>3</span><span>vh</span></span><span>;</span></div></div><div><div><div>120</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>-40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.693872337330205</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>121</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>122</div></div><div>
</div></div><div><div><div>123</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>8</span><span>)</span><span> {</span></div></div><div><div><div>124</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>583C87</span><span>;</span></div></div><div><div><div>125</div></div><div><span><span>        </span></span><span>top: </span><span><span>42</span><span>%</span></span><span>;</span></div></div><div><div><div>126</div></div><div><span><span>        </span></span><span>left: </span><span><span>55</span><span>%</span></span><span>;</span></div></div><div><div><div>127</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>46</span><span>s</span></span><span>;</span></div></div><div><div><div>128</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-50</span><span>s</span></span><span>;</span></div></div><div><div><div>129</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>-6</span><span>vw</span></span><span> </span><span><span>25</span><span>vh</span></span><span>;</span></div></div><div><div><div>130</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.588315610213253</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>131</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>132</div></div><div>
</div></div><div><div><div>133</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>9</span><span>)</span><span> {</span></div></div><div><div><div>134</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>E45A84</span><span>;</span></div></div><div><div><div>135</div></div><div><span><span>        </span></span><span>top: </span><span><span>78</span><span>%</span></span><span>;</span></div></div><div><div><div>136</div></div><div><span><span>        </span></span><span>left: </span><span><span>25</span><span>%</span></span><span>;</span></div></div><div><div><div>137</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>44</span><span>s</span></span><span>;</span></div></div><div><div><div>138</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-21</span><span>s</span></span><span>;</span></div></div><div><div><div>139</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>-4</span><span>vw</span></span><span> </span><span><span>-12</span><span>vh</span></span><span>;</span></div></div><div><div><div>140</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>-40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.82170170819547</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>141</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>142</div></div><div>
</div></div><div><div><div>143</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>10</span><span>)</span><span> {</span></div></div><div><div><div>144</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>E45A84</span><span>;</span></div></div><div><div><div>145</div></div><div><span><span>        </span></span><span>top: </span><span><span>73</span><span>%</span></span><span>;</span></div></div><div><div><div>146</div></div><div><span><span>        </span></span><span>left: </span><span><span>77</span><span>%</span></span><span>;</span></div></div><div><div><div>147</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>41</span><span>s</span></span><span>;</span></div></div><div><div><div>148</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-40</span><span>s</span></span><span>;</span></div></div><div><div><div>149</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>21</span><span>vw</span></span><span> </span><span><span>-11</span><span>vh</span></span><span>;</span></div></div><div><div><div>150</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>-40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.838449416658446</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>151</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>152</div></div><div>
</div></div><div><div><div>153</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>11</span><span>)</span><span> {</span></div></div><div><div><div>154</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>E45A84</span><span>;</span></div></div><div><div><div>155</div></div><div><span><span>        </span></span><span>top: </span><span><span>48</span><span>%</span></span><span>;</span></div></div><div><div><div>156</div></div><div><span><span>        </span></span><span>left: </span><span><span>81</span><span>%</span></span><span>;</span></div></div><div><div><div>157</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>33</span><span>s</span></span><span>;</span></div></div><div><div><div>158</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-42</span><span>s</span></span><span>;</span></div></div><div><div><div>159</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>6</span><span>vw</span></span><span> </span><span><span>19</span><span>vh</span></span><span>;</span></div></div><div><div><div>160</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.848850560573668</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>161</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>162</div></div><div>
</div></div><div><div><div>163</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>12</span><span>)</span><span> {</span></div></div><div><div><div>164</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>E45A84</span><span>;</span></div></div><div><div><div>165</div></div><div><span><span>        </span></span><span>top: </span><span><span>77</span><span>%</span></span><span>;</span></div></div><div><div><div>166</div></div><div><span><span>        </span></span><span>left: </span><span><span>7</span><span>%</span></span><span>;</span></div></div><div><div><div>167</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>25</span><span>s</span></span><span>;</span></div></div><div><div><div>168</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-1</span><span>s</span></span><span>;</span></div></div><div><div><div>169</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>15</span><span>vw</span></span><span> </span><span><span>24</span><span>vh</span></span><span>;</span></div></div><div><div><div>170</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>-40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.800039290361969</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>171</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>172</div></div><div>
</div></div><div><div><div>173</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>13</span><span>)</span><span> {</span></div></div><div><div><div>174</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>E45A84</span><span>;</span></div></div><div><div><div>175</div></div><div><span><span>        </span></span><span>top: </span><span><span>77</span><span>%</span></span><span>;</span></div></div><div><div><div>176</div></div><div><span><span>        </span></span><span>left: </span><span><span>38</span><span>%</span></span><span>;</span></div></div><div><div><div>177</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>51</span><span>s</span></span><span>;</span></div></div><div><div><div>178</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-40</span><span>s</span></span><span>;</span></div></div><div><div><div>179</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>-1</span><span>vw</span></span><span> </span><span><span>-13</span><span>vh</span></span><span>;</span></div></div><div><div><div>180</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>-40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.876822672246133</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>181</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>182</div></div><div>
</div></div><div><div><div>183</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>14</span><span>)</span><span> {</span></div></div><div><div><div>184</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>583C87</span><span>;</span></div></div><div><div><div>185</div></div><div><span><span>        </span></span><span>top: </span><span><span>58</span><span>%</span></span><span>;</span></div></div><div><div><div>186</div></div><div><span><span>        </span></span><span>left: </span><span><span>98</span><span>%</span></span><span>;</span></div></div><div><div><div>187</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>7</span><span>s</span></span><span>;</span></div></div><div><div><div>188</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-1</span><span>s</span></span><span>;</span></div></div><div><div><div>189</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>-19</span><span>vw</span></span><span> </span><span><span>-20</span><span>vh</span></span><span>;</span></div></div><div><div><div>190</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>-40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.622075629639948</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>191</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>192</div></div><div>
</div></div><div><div><div>193</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>15</span><span>)</span><span> {</span></div></div><div><div><div>194</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>583C87</span><span>;</span></div></div><div><div><div>195</div></div><div><span><span>        </span></span><span>top: </span><span><span>79</span><span>%</span></span><span>;</span></div></div><div><div><div>196</div></div><div><span><span>        </span></span><span>left: </span><span><span>31</span><span>%</span></span><span>;</span></div></div><div><div><div>197</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>39</span><span>s</span></span><span>;</span></div></div><div><div><div>198</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-46</span><span>s</span></span><span>;</span></div></div><div><div><div>199</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>14</span><span>vw</span></span><span> </span><span><span>21</span><span>vh</span></span><span>;</span></div></div><div><div><div>200</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.022352355698978</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>201</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>202</div></div><div>
</div></div><div><div><div>203</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>16</span><span>)</span><span> {</span></div></div><div><div><div>204</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>E45A84</span><span>;</span></div></div><div><div><div>205</div></div><div><span><span>        </span></span><span>top: </span><span><span>41</span><span>%</span></span><span>;</span></div></div><div><div><div>206</div></div><div><span><span>        </span></span><span>left: </span><span><span>74</span><span>%</span></span><span>;</span></div></div><div><div><div>207</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>37</span><span>s</span></span><span>;</span></div></div><div><div><div>208</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-4</span><span>s</span></span><span>;</span></div></div><div><div><div>209</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>-19</span><span>vw</span></span><span> </span><span><span>3</span><span>vh</span></span><span>;</span></div></div><div><div><div>210</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.049960684696969</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>211</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>212</div></div><div>
</div></div><div><div><div>213</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>17</span><span>)</span><span> {</span></div></div><div><div><div>214</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>583C87</span><span>;</span></div></div><div><div><div>215</div></div><div><span><span>        </span></span><span>top: </span><span><span>56</span><span>%</span></span><span>;</span></div></div><div><div><div>216</div></div><div><span><span>        </span></span><span>left: </span><span><span>34</span><span>%</span></span><span>;</span></div></div><div><div><div>217</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>26</span><span>s</span></span><span>;</span></div></div><div><div><div>218</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-35</span><span>s</span></span><span>;</span></div></div><div><div><div>219</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>-16</span><span>vw</span></span><span> </span><span><span>-7</span><span>vh</span></span><span>;</span></div></div><div><div><div>220</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>-40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.11253385954465</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>221</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>222</div></div><div>
</div></div><div><div><div>223</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>18</span><span>)</span><span> {</span></div></div><div><div><div>224</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>583C87</span><span>;</span></div></div><div><div><div>225</div></div><div><span><span>        </span></span><span>top: </span><span><span>84</span><span>%</span></span><span>;</span></div></div><div><div><div>226</div></div><div><span><span>        </span></span><span>left: </span><span><span>2</span><span>%</span></span><span>;</span></div></div><div><div><div>227</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>14</span><span>s</span></span><span>;</span></div></div><div><div><div>228</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-39</span><span>s</span></span><span>;</span></div></div><div><div><div>229</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>-10</span><span>vw</span></span><span> </span><span><span>-6</span><span>vh</span></span><span>;</span></div></div><div><div><div>230</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.903761483531039</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>231</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>232</div></div><div>
</div></div><div><div><div>233</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>19</span><span>)</span><span> {</span></div></div><div><div><div>234</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>E45A84</span><span>;</span></div></div><div><div><div>235</div></div><div><span><span>        </span></span><span>top: </span><span><span>61</span><span>%</span></span><span>;</span></div></div><div><div><div>236</div></div><div><span><span>        </span></span><span>left: </span><span><span>39</span><span>%</span></span><span>;</span></div></div><div><div><div>237</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>21</span><span>s</span></span><span>;</span></div></div><div><div><div>238</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-36</span><span>s</span></span><span>;</span></div></div><div><div><div>239</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>14</span><span>vw</span></span><span> </span><span><span>9</span><span>vh</span></span><span>;</span></div></div><div><div><div>240</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.448311817969409</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>241</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>242</div></div><div>
</div></div><div><div><div>243</div></div><div><span>      </span><span>.background</span><span> </span><span>span</span><span>:nth-child</span><span>(</span><span>20</span><span>)</span><span> {</span></div></div><div><div><div>244</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>E45A84</span><span>;</span></div></div><div><div><div>245</div></div><div><span><span>        </span></span><span>top: </span><span><span>33</span><span>%</span></span><span>;</span></div></div><div><div><div>246</div></div><div><span><span>        </span></span><span>left: </span><span><span>5</span><span>%</span></span><span>;</span></div></div><div><div><div>247</div></div><div><span><span>        </span></span><span>animation-duration: </span><span><span>8</span><span>s</span></span><span>;</span></div></div><div><div><div>248</div></div><div><span><span>        </span></span><span>animation-delay: </span><span><span>-7</span><span>s</span></span><span>;</span></div></div><div><div><div>249</div></div><div><span><span>        </span></span><span>transform-origin: </span><span><span>4</span><span>vw</span></span><span> </span><span><span>2</span><span>vh</span></span><span>;</span></div></div><div><div><div>250</div></div><div><span><span>        </span></span><span>box-shadow: </span><span><span>40</span><span>vmin</span></span><span> </span><span>0</span><span> </span><span><span>5.013421190075091</span><span>vmin</span></span><span> </span><span>currentColor</span><span>;</span></div></div><div><div><div>251</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>252</div></div><div>
</div></div><div><div><div>253</div></div><div><span>      </span><span>/* 动态背景 */</span></div></div><div><div><div>254</div></div><div>
</div></div><div><div><div>255</div></div><div><span>      </span><span>body</span><span> {</span></div></div><div><div><div>256</div></div><div><span><span>        </span></span><span>height: </span><span><span>100</span><span>vh</span></span><span>;</span></div></div><div><div><div>257</div></div><div><span><span>        </span></span><span>background-color: </span><span>aquamarine</span><span>;</span></div></div><div><div><div>258</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>259</div></div><div>
</div></div><div><div><div>260</div></div><div><span>      </span><span>.Box</span><span> {</span></div></div><div><div><div>261</div></div><div><span><span>        </span></span><span>position: </span><span>fixed</span><span>;</span></div></div><div><div><div>262</div></div><div><span><span>        </span></span><span>top: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>263</div></div><div><span><span>        </span></span><span>left: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>264</div></div><div><span><span>        </span></span><span>transform: </span><span>translate</span><span>(</span><span><span>-50</span><span>%</span></span><span>, </span><span><span>-50</span><span>%</span></span><span>);</span></div></div><div><div><div>265</div></div><div><span><span>        </span></span><span>width: </span><span><span>320</span><span>px</span></span><span>;</span></div></div><div><div><div>266</div></div><div><span><span>        </span></span><span>background-color: </span><span>rgba</span><span>(</span><span>0</span><span>, </span><span>0</span><span>, </span><span>0</span><span>, </span><span>0.24</span><span>);</span></div></div><div><div><div>267</div></div><div><span><span>        </span></span><span>border-radius: </span><span><span>6</span><span>px</span></span><span>;</span></div></div><div><div><div>268</div></div><div><span><span>        </span></span><span>padding: </span><span><span>20</span><span>px</span></span><span> </span><span><span>32</span><span>px</span></span><span>;</span></div></div><div><div><div>269</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>270</div></div><div>
</div></div><div><div><div>271</div></div><div><span>      </span><span>h3</span><span> {</span></div></div><div><div><div>272</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>22</span><span>px</span></span><span>;</span></div></div><div><div><div>273</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>274</div></div><div><span><span>        </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>275</div></div><div><span><span>        </span></span><span>margin-bottom: </span><span><span>40</span><span>px</span></span><span>;</span></div></div><div><div><div>276</div></div><div><span><span>        </span></span><span>font-weight: </span><span>500</span><span>;</span></div></div><div><div><div>277</div></div><div><span><span>        </span></span><span>letter-spacing: </span><span><span>5</span><span>px</span></span><span>;</span></div></div><div><div><div>278</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>279</div></div><div>
</div></div><div><div><div>280</div></div><div><span>      </span><span>input</span><span> {</span></div></div><div><div><div>281</div></div><div><span><span>        </span></span><span>width: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>282</div></div><div><span><span>        </span></span><span>height: </span><span><span>35</span><span>px</span></span><span>;</span></div></div><div><div><div>283</div></div><div><span><span>        </span></span><span>border: </span><span><span>1</span><span>px</span></span><span><span> </span><span>solid</span><span> </span></span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>284</div></div><div><span><span>        </span></span><span>background-color: </span><span>transparent</span><span>;</span></div></div><div><div><div>285</div></div><div><span><span>        </span></span><span>padding-left: </span><span><span>10</span><span>px</span></span><span>;</span></div></div><div><div><div>286</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>12</span><span>px</span></span><span>;</span></div></div><div><div><div>287</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>288</div></div><div><span><span>        </span></span><span>margin-bottom: </span><span><span>20</span><span>px</span></span><span>;</span></div></div><div><div><div>289</div></div><div><span><span>        </span></span><span>outline: </span><span>none</span><span>;</span></div></div><div><div><div>290</div></div><div><span><span>        </span></span><span>border-radius: </span><span><span>5</span><span>px</span></span><span>;</span></div></div><div><div><div>291</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>292</div></div><div>
</div></div><div><div><div>293</div></div><div><span>      </span><span>input</span><span>::placeholder</span><span> {</span></div></div><div><div><div>294</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>295</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>296</div></div><div>
</div></div><div><div><div>297</div></div><div><span>      </span><span>.yzmBox</span><span> {</span></div></div><div><div><div>298</div></div><div><span><span>        </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>299</div></div><div><span><span>        </span></span><span>justify-content: </span><span>flex-start</span><span>;</span></div></div><div><div><div>300</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>301</div></div><div>
</div></div><div><div><div>302</div></div><div><span>      </span><span>.yzmBox</span><span> </span><span>input</span><span> {</span></div></div><div><div><div>303</div></div><div><span><span>        </span></span><span>width: </span><span><span>70</span><span>%</span></span><span>;</span></div></div><div><div><div>304</div></div><div><span><span>        </span></span><span>border-top-right-radius: </span><span>0</span><span>;</span></div></div><div><div><div>305</div></div><div><span><span>        </span></span><span>border-bottom-right-radius: </span><span>0</span><span>;</span></div></div><div><div><div>306</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>307</div></div><div>
</div></div><div><div><div>308</div></div><div><span>      </span><span>.yzmBox</span><span> </span><span>.btn</span><span> {</span></div></div><div><div><div>309</div></div><div><span><span>        </span></span><span>cursor: </span><span>pointer</span><span>;</span></div></div><div><div><div>310</div></div><div><span><span>        </span></span><span>width: </span><span><span>29</span><span>%</span></span><span>;</span></div></div><div><div><div>311</div></div><div><span><span>        </span></span><span>background-color: </span><span>#</span><span>aa55ff</span><span>;</span></div></div><div><div><div>312</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>d8d8d8</span><span>;</span></div></div><div><div><div>313</div></div><div><span><span>        </span></span><span>height: </span><span><span>35</span><span>px</span></span><span>;</span></div></div><div><div><div>314</div></div><div><span><span>        </span></span><span>outline: </span><span>none</span><span>;</span></div></div><div><div><div>315</div></div><div><span><span>        </span></span><span>border: </span><span><span>1</span><span>px</span></span><span><span> </span><span>solid</span><span> </span></span><span>#</span><span>aa55ff</span><span>;</span></div></div><div><div><div>316</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>12</span><span>px</span></span><span>;</span></div></div><div><div><div>317</div></div><div><span><span>        </span></span><span>border-radius: </span><span><span>6</span><span>px</span></span><span>;</span></div></div><div><div><div>318</div></div><div><span><span>        </span></span><span>margin-left: </span><span><span>1</span><span>%</span></span><span>;</span></div></div><div><div><div>319</div></div><div><span><span>        </span></span><span>border-top-left-radius: </span><span>0</span><span>;</span></div></div><div><div><div>320</div></div><div><span><span>        </span></span><span>border-bottom-left-radius: </span><span>0</span><span>;</span></div></div><div><div><div>321</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>322</div></div><div>
</div></div><div><div><div>323</div></div><div><span>      </span><span>.forgetPwd</span><span> {</span></div></div><div><div><div>324</div></div><div><span><span>        </span></span><span>text-align: </span><span>end</span><span>;</span></div></div><div><div><div>325</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>12</span><span>px</span></span><span>;</span></div></div><div><div><div>326</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>ffffff</span><span>;</span></div></div><div><div><div>327</div></div><div><span><span>        </span></span><span>padding-right: </span><span><span>5</span><span>px</span></span><span>;</span></div></div><div><div><div>328</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>329</div></div><div>
</div></div><div><div><div>330</div></div><div><span>      </span><span>.loginBtn</span><span> {</span></div></div><div><div><div>331</div></div><div><span><span>        </span></span><span>width: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>332</div></div><div><span><span>        </span></span><span>line-height: </span><span><span>36</span><span>px</span></span><span>;</span></div></div><div><div><div>333</div></div><div><span><span>        </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>334</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>15</span><span>px</span></span><span>;</span></div></div><div><div><div>335</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>336</div></div><div><span><span>        </span></span><span>border-radius: </span><span><span>6</span><span>px</span></span><span>;</span></div></div><div><div><div>337</div></div><div><span><span>        </span></span><span>background: </span><span>linear-gradient</span><span><span>(to </span><span>right</span><span>, </span></span><span>#</span><span>aa55ff</span><span>, </span><span>#</span><span>E45A84</span><span>);</span></div></div><div><div><div>338</div></div><div><span><span>        </span></span><span>outline: </span><span>none</span><span>;</span></div></div><div><div><div>339</div></div><div><span><span>        </span></span><span>border: </span><span>none</span><span>;</span></div></div><div><div><div>340</div></div><div><span><span>        </span></span><span>margin-top: </span><span><span>30</span><span>px</span></span><span>;</span></div></div><div><div><div>341</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>342</div></div><div>
</div></div><div><div><div>343</div></div><div><span>      </span><span>.no</span><span> {</span></div></div><div><div><div>344</div></div><div><span><span>        </span></span><span>margin-top: </span><span><span>30</span><span>px</span></span><span>;</span></div></div><div><div><div>345</div></div><div><span><span>        </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>346</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>12</span><span>px</span></span><span>;</span></div></div><div><div><div>347</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>ffffff</span><span>;</span></div></div><div><div><div>348</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>349</div></div><div><span><span>    </span></span><span>&lt;/</span><span>style</span><span>&gt;</span></div></div><div><div><div>350</div></div><div><span><span>  </span></span><span>&lt;/</span><span>head</span><span>&gt;</span></div></div><div><div><div>351</div></div><div><span><span>  </span></span><span>&lt;</span><span>body</span><span>&gt;</span></div></div><div><div><div>352</div></div><div><span>    </span><span>&lt;!-- 背景 --&gt;</span></div></div><div><div><div>353</div></div><div><span><span>    </span></span><span>&lt;</span><span>div</span><span> </span><span>class</span><span>=</span><span>"background"</span><span>&gt;</span></div></div><div><div><div>354</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>355</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>356</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>357</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>358</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>359</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>360</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>361</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>362</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>363</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>364</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>365</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>366</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>367</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>368</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>369</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>370</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>371</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>372</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>373</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>374</div></div><div><span><span>      </span></span><span>&lt;</span><span>span</span><span>&gt;&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>375</div></div><div><span><span>    </span></span><span>&lt;/</span><span>div</span><span>&gt;</span></div></div><div><div><div>376</div></div><div>
</div></div><div><div><div>377</div></div><div><span><span>    </span></span><span>&lt;</span><span>div</span><span> </span><span>class</span><span>=</span><span>"Box"</span><span>&gt;</span></div></div><div><div><div>378</div></div><div><span><span>      </span></span><span>&lt;</span><span>h3</span><span>&gt;某某管理系统&lt;/</span><span>h3</span><span>&gt;</span></div></div><div><div><div>379</div></div><div><span><span>      </span></span><span>&lt;</span><span>form</span><span> </span><span>action</span><span>=</span><span>""</span><span>&gt;</span></div></div><div><div><div>380</div></div><div><span><span>        </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"text"</span><span> </span><span>placeholder</span><span>=</span><span>"请输入账号"</span><span> </span><span>required</span><span>&gt;</span></div></div><div><div><div>381</div></div><div><span><span>        </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"password"</span><span> </span><span>placeholder</span><span>=</span><span>"请输入密码"</span><span> </span><span>required</span><span>&gt;</span></div></div><div><div><div>382</div></div><div><span><span>        </span></span><span>&lt;</span><span>div</span><span> </span><span>class</span><span>=</span><span>"yzmBox"</span><span>&gt;</span></div></div><div><div><div>383</div></div><div><span><span>          </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"text"</span><span> </span><span>placeholder</span><span>=</span><span>"请输入验证码"</span><span>&gt;</span></div></div><div><div><div>384</div></div><div><span><span>          </span></span><span>&lt;</span><span>button</span><span> </span><span>class</span><span>=</span><span>"btn"</span><span>&gt;发送&lt;/</span><span>button</span><span>&gt;</span></div></div><div><div><div>385</div></div><div><span><span>        </span></span><span>&lt;/</span><span>div</span><span>&gt;</span></div></div><div><div><div>386</div></div><div><span><span>        </span></span><span>&lt;</span><span>p</span><span> </span><span>class</span><span>=</span><span>"forgetPwd"</span><span>&gt;忘记密码&lt;/</span><span>p</span><span>&gt;</span></div></div><div><div><div>387</div></div><div><span><span>        </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"submit"</span><span> </span><span>class</span><span>=</span><span>"loginBtn"</span><span> </span><span>value</span><span>=</span><span>"登录"</span><span>&gt;&lt;/</span><span>button</span><span>&gt;</span></div></div><div><div><div>388</div></div><div><span><span>        </span></span><span>&lt;</span><span>p</span><span> </span><span>class</span><span>=</span><span>"no"</span><span>&gt;没有账号？立即注册&lt;/</span><span>p</span><span>&gt;</span></div></div><div><div><div>389</div></div><div><span><span>      </span></span><span>&lt;/</span><span>form</span><span>&gt;</span></div></div><div><div><div>390</div></div><div><span><span>    </span></span><span>&lt;/</span><span>div</span><span>&gt;</span></div></div><div><div><div>391</div></div><div><span><span>  </span></span><span>&lt;/</span><span>body</span><span>&gt;</span></div></div><div><div><div>392</div></div><div><span>&lt;/</span><span>html</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>蓝色登录界面（图二）：<a href="#蓝色登录界面图二"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;!</span><span>DOCTYPE</span><span> </span><span>html</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span>&lt;</span><span>html</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>&lt;</span><span>head</span><span>&gt;</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>&lt;</span><span>meta</span><span> </span><span>charset</span><span>=</span><span>"utf-8"</span><span>&gt;</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>&lt;</span><span>title</span><span>&gt;登录2&lt;/</span><span>title</span><span>&gt;</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>&lt;</span><span>style</span><span>&gt;</span></div></div><div><div><div>7</div></div><div><span>      </span><span>*</span><span> {</span></div></div><div><div><div>8</div></div><div><span><span>        </span></span><span>margin: </span><span>0</span><span>;</span></div></div><div><div><div>9</div></div><div><span><span>        </span></span><span>padding: </span><span>0</span><span>;</span></div></div><div><div><div>10</div></div><div><span><span>        </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>      </span><span>body</span><span> {</span></div></div><div><div><div>14</div></div><div><span><span>        </span></span><span>height: </span><span><span>100</span><span>vh</span></span><span>;</span></div></div><div><div><div>15</div></div><div><span><span>        </span></span><span>background: </span><span>linear-gradient</span><span><span>(to </span><span>right</span><span>, </span></span><span>#</span><span>6af4ff</span><span>, </span><span>#</span><span>ffffff</span><span>);</span></div></div><div><div><div>16</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>      </span><span>.Box</span><span> {</span></div></div><div><div><div>19</div></div><div><span><span>        </span></span><span>position: </span><span>fixed</span><span>;</span></div></div><div><div><div>20</div></div><div><span><span>        </span></span><span>top: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>21</div></div><div><span><span>        </span></span><span>left: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>22</div></div><div><span><span>        </span></span><span>transform: </span><span>translate</span><span>(</span><span><span>-50</span><span>%</span></span><span>, </span><span><span>-50</span><span>%</span></span><span>);</span></div></div><div><div><div>23</div></div><div><span><span>        </span></span><span>width: </span><span><span>550</span><span>px</span></span><span>;</span></div></div><div><div><div>24</div></div><div><span><span>        </span></span><span>height: </span><span><span>330</span><span>px</span></span><span>;</span></div></div><div><div><div>25</div></div><div><span><span>        </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>26</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>27</div></div><div>
</div></div><div><div><div>28</div></div><div>
</div></div><div><div><div>29</div></div><div><span>      </span><span>form</span><span> {</span></div></div><div><div><div>30</div></div><div><span><span>        </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>31</div></div><div><span><span>        </span></span><span>top: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>32</div></div><div><span><span>        </span></span><span>left: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>33</div></div><div><span><span>        </span></span><span>transform: </span><span>translate</span><span>(</span><span><span>-50</span><span>%</span></span><span>, </span><span><span>-60</span><span>%</span></span><span>);</span></div></div><div><div><div>34</div></div><div><span><span>        </span></span><span>width: </span><span><span>80</span><span>%</span></span><span>;</span></div></div><div><div><div>35</div></div><div><span><span>        </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>36</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>37</div></div><div>
</div></div><div><div><div>38</div></div><div><span>      </span><span>h3</span><span> {</span></div></div><div><div><div>39</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>24</span><span>px</span></span><span>;</span></div></div><div><div><div>40</div></div><div><span><span>        </span></span><span>margin-bottom: </span><span><span>20</span><span>px</span></span><span>;</span></div></div><div><div><div>41</div></div><div><span><span>        </span></span><span>letter-spacing: </span><span><span>5</span><span>px</span></span><span>;</span></div></div><div><div><div>42</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>43</div></div><div>
</div></div><div><div><div>44</div></div><div><span>      </span><span>input</span><span> {</span></div></div><div><div><div>45</div></div><div><span><span>        </span></span><span>width: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>46</div></div><div><span><span>        </span></span><span>height: </span><span><span>38</span><span>px</span></span><span>;</span></div></div><div><div><div>47</div></div><div><span><span>        </span></span><span>border: </span><span><span>1</span><span>px</span></span><span><span> </span><span>solid</span><span> </span></span><span>#</span><span>000000</span><span>;</span></div></div><div><div><div>48</div></div><div><span><span>        </span></span><span>background-color: </span><span>transparent</span><span>;</span></div></div><div><div><div>49</div></div><div><span><span>        </span></span><span>padding-left: </span><span><span>10</span><span>px</span></span><span>;</span></div></div><div><div><div>50</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>12</span><span>px</span></span><span>;</span></div></div><div><div><div>51</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>000000</span><span>;</span></div></div><div><div><div>52</div></div><div><span><span>        </span></span><span>margin-bottom: </span><span><span>15</span><span>px</span></span><span>;</span></div></div><div><div><div>53</div></div><div><span><span>        </span></span><span>outline: </span><span>none</span><span>;</span></div></div><div><div><div>54</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>55</div></div><div>
</div></div><div><div><div>56</div></div><div><span>      </span><span>.desc</span><span> {</span></div></div><div><div><div>57</div></div><div><span><span>        </span></span><span>margin: </span><span><span>0</span><span>px</span></span><span> </span><span><span>20</span><span>px</span></span><span> </span><span><span>30</span><span>px</span></span><span>;</span></div></div><div><div><div>58</div></div><div><span><span>        </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>59</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>12</span><span>px</span></span><span>;</span></div></div><div><div><div>60</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>828282</span><span>;</span></div></div><div><div><div>61</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>62</div></div><div>
</div></div><div><div><div>63</div></div><div><span>      </span><span>.loginBtn</span><span> {</span></div></div><div><div><div>64</div></div><div><span><span>        </span></span><span>width: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>65</div></div><div><span><span>        </span></span><span>line-height: </span><span><span>36</span><span>px</span></span><span>;</span></div></div><div><div><div>66</div></div><div><span><span>        </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>67</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>15</span><span>px</span></span><span>;</span></div></div><div><div><div>68</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>69</div></div><div><span><span>        </span></span><span>background: </span><span>rgb</span><span>(</span><span>57</span><span>, </span><span>99</span><span>, </span><span>134</span><span>);</span></div></div><div><div><div>70</div></div><div><span><span>        </span></span><span>outline: </span><span>none</span><span>;</span></div></div><div><div><div>71</div></div><div><span><span>        </span></span><span>border: </span><span>none</span><span>;</span></div></div><div><div><div>72</div></div><div><span><span>        </span></span><span>margin-top: </span><span><span>10</span><span>px</span></span><span>;</span></div></div><div><div><div>73</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>74</div></div><div>
</div></div><div><div><div>75</div></div><div><span>      </span><span>.no</span><span> {</span></div></div><div><div><div>76</div></div><div><span><span>        </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>77</div></div><div><span><span>        </span></span><span>justify-content: </span><span>space-between</span><span>;</span></div></div><div><div><div>78</div></div><div><span><span>        </span></span><span>cursor: </span><span>pointer</span><span>;</span></div></div><div><div><div>79</div></div><div><span><span>        </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>80</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>12</span><span>px</span></span><span>;</span></div></div><div><div><div>81</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>828282</span><span>;</span></div></div><div><div><div>82</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>83</div></div><div><span><span>    </span></span><span>&lt;/</span><span>style</span><span>&gt;</span></div></div><div><div><div>84</div></div><div><span><span>  </span></span><span>&lt;/</span><span>head</span><span>&gt;</span></div></div><div><div><div>85</div></div><div><span><span>  </span></span><span>&lt;</span><span>body</span><span>&gt;</span></div></div><div><div><div>86</div></div><div><span><span>    </span></span><span>&lt;</span><span>div</span><span> </span><span>class</span><span>=</span><span>"Box"</span><span>&gt;</span></div></div><div><div><div>87</div></div><div><span><span>      </span></span><span>&lt;</span><span>form</span><span> </span><span>action</span><span>=</span><span>""</span><span>&gt;</span></div></div><div><div><div>88</div></div><div><span><span>        </span></span><span>&lt;</span><span>h3</span><span>&gt;欢迎登录&lt;/</span><span>h3</span><span>&gt;</span></div></div><div><div><div>89</div></div><div><span><span>        </span></span><span>&lt;</span><span>p</span><span> </span><span>class</span><span>=</span><span>"desc"</span><span>&gt;WELCOME LOGIN&lt;/</span><span>p</span><span>&gt;</span></div></div><div><div><div>90</div></div><div><span><span>        </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"text"</span><span> </span><span>placeholder</span><span>=</span><span>"请输入账号"</span><span> </span><span>required</span><span>&gt;</span></div></div><div><div><div>91</div></div><div><span><span>        </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"password"</span><span> </span><span>placeholder</span><span>=</span><span>"请输入密码"</span><span> </span><span>required</span><span>&gt;</span></div></div><div><div><div>92</div></div><div><span><span>        </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"submit"</span><span> </span><span>class</span><span>=</span><span>"loginBtn"</span><span> </span><span>value</span><span>=</span><span>"登录"</span><span>&gt;&lt;/</span><span>button</span><span>&gt;</span></div></div><div><div><div>93</div></div><div><span><span>        </span></span><span>&lt;</span><span>p</span><span> </span><span>class</span><span>=</span><span>"no"</span><span>&gt;</span></div></div><div><div><div>94</div></div><div><span><span>          </span></span><span>&lt;</span><span>span</span><span>&gt;忘记密码&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>95</div></div><div><span><span>          </span></span><span>&lt;</span><span>span</span><span>&gt;没有账号？立即注册&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>96</div></div><div><span><span>        </span></span><span>&lt;/</span><span>p</span><span>&gt;</span></div></div><div><div><div>97</div></div><div><span><span>      </span></span><span>&lt;/</span><span>form</span><span>&gt;</span></div></div><div><div><div>98</div></div><div><span><span>    </span></span><span>&lt;/</span><span>div</span><span>&gt;</span></div></div><div><div><div>99</div></div><div><span><span>  </span></span><span>&lt;/</span><span>body</span><span>&gt;</span></div></div><div><div><div>100</div></div><div><span>&lt;/</span><span>html</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>青色登录界面（图三）：<a href="#青色登录界面图三"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;!</span><span>DOCTYPE</span><span> </span><span>html</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span>&lt;</span><span>html</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>&lt;</span><span>head</span><span>&gt;</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>&lt;</span><span>meta</span><span> </span><span>charset</span><span>=</span><span>"utf-8"</span><span>&gt;</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>&lt;</span><span>title</span><span>&gt;登录3&lt;/</span><span>title</span><span>&gt;</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>&lt;</span><span>style</span><span>&gt;</span></div></div><div><div><div>7</div></div><div><span>      </span><span>*</span><span> {</span></div></div><div><div><div>8</div></div><div><span><span>        </span></span><span>margin: </span><span>0</span><span>;</span></div></div><div><div><div>9</div></div><div><span><span>        </span></span><span>padding: </span><span>0</span><span>;</span></div></div><div><div><div>10</div></div><div><span><span>        </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>      </span><span>body</span><span> {</span></div></div><div><div><div>14</div></div><div><span><span>        </span></span><span>height: </span><span><span>100</span><span>vh</span></span><span>;</span></div></div><div><div><div>15</div></div><div><span><span>        </span></span><span>background-color: </span><span>aquamarine</span><span>;</span></div></div><div><div><div>16</div></div><div><span><span>        </span></span><span>background: </span><span>url</span><span>(</span><span>"https://images.pexels.com/photos/936722/pexels-photo-936722.jpeg?auto=compress&amp;cs=tinysrgb&amp;w=1260&amp;h=750&amp;dpr=1"</span><span><span>) </span><span>no-repeat</span><span>;</span></span></div></div><div><div><div>17</div></div><div><span><span>        </span></span><span>background-size: </span><span>cover</span><span>;</span></div></div><div><div><div>18</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>19</div></div><div>
</div></div><div><div><div>20</div></div><div><span>      </span><span>.Box</span><span> {</span></div></div><div><div><div>21</div></div><div><span><span>        </span></span><span>position: </span><span>fixed</span><span>;</span></div></div><div><div><div>22</div></div><div><span><span>        </span></span><span>top: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>23</div></div><div><span><span>        </span></span><span>left: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>24</div></div><div><span><span>        </span></span><span>transform: </span><span>translate</span><span>(</span><span><span>-50</span><span>%</span></span><span>, </span><span><span>-50</span><span>%</span></span><span>);</span></div></div><div><div><div>25</div></div><div><span><span>        </span></span><span>width: </span><span><span>550</span><span>px</span></span><span>;</span></div></div><div><div><div>26</div></div><div><span><span>        </span></span><span>height: </span><span><span>330</span><span>px</span></span><span>;</span></div></div><div><div><div>27</div></div><div><span><span>        </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>28</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>29</div></div><div>
</div></div><div><div><div>30</div></div><div><span>      </span><span>.left</span><span> {</span></div></div><div><div><div>31</div></div><div><span><span>        </span></span><span>position: </span><span>relative</span><span>;</span></div></div><div><div><div>32</div></div><div><span><span>        </span></span><span>width: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>33</div></div><div><span><span>        </span></span><span>height: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>34</div></div><div><span><span>        </span></span><span>background-color: </span><span>rgba</span><span>(</span><span>57</span><span>, </span><span>99</span><span>, </span><span>134</span><span>, </span><span>0.75</span><span>);</span></div></div><div><div><div>35</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>36</div></div><div>
</div></div><div><div><div>37</div></div><div><span>      </span><span>.right</span><span> {</span></div></div><div><div><div>38</div></div><div><span><span>        </span></span><span>position: </span><span>relative</span><span>;</span></div></div><div><div><div>39</div></div><div><span><span>        </span></span><span>width: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>40</div></div><div><span><span>        </span></span><span>height: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>41</div></div><div><span><span>        </span></span><span>background-color: </span><span>rgba</span><span>(</span><span>255</span><span>, </span><span>255</span><span>, </span><span>255</span><span>, </span><span>1</span><span>);</span></div></div><div><div><div>42</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>43</div></div><div>
</div></div><div><div><div>44</div></div><div><span>      </span><span>.centerBox</span><span> {</span></div></div><div><div><div>45</div></div><div><span><span>        </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>46</div></div><div><span><span>        </span></span><span>top: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>47</div></div><div><span><span>        </span></span><span>left: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>48</div></div><div><span><span>        </span></span><span>transform: </span><span>translate</span><span>(</span><span><span>-50</span><span>%</span></span><span>, </span><span><span>-50</span><span>%</span></span><span>);</span></div></div><div><div><div>49</div></div><div><span><span>        </span></span><span>width: </span><span><span>80</span><span>%</span></span><span>;</span></div></div><div><div><div>50</div></div><div><span><span>        </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>51</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>52</div></div><div>
</div></div><div><div><div>53</div></div><div><span>      </span><span>.left</span><span> </span><span>img</span><span> {</span></div></div><div><div><div>54</div></div><div><span><span>        </span></span><span>width: </span><span><span>50</span><span>px</span></span><span>;</span></div></div><div><div><div>55</div></div><div><span><span>        </span></span><span>height: </span><span><span>50</span><span>px</span></span><span>;</span></div></div><div><div><div>56</div></div><div><span><span>        </span></span><span>margin-bottom: </span><span><span>5</span><span>px</span></span><span>;</span></div></div><div><div><div>57</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>58</div></div><div>
</div></div><div><div><div>59</div></div><div><span>      </span><span>.left</span><span> </span><span>p</span><span> {</span></div></div><div><div><div>60</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>14</span><span>px</span></span><span>;</span></div></div><div><div><div>61</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>62</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>63</div></div><div>
</div></div><div><div><div>64</div></div><div><span>      </span><span>.left</span><span> </span><span>h4</span><span> {</span></div></div><div><div><div>65</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>18</span><span>px</span></span><span>;</span></div></div><div><div><div>66</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>67</div></div><div><span><span>        </span></span><span>margin-bottom: </span><span><span>10</span><span>px</span></span><span>;</span></div></div><div><div><div>68</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>69</div></div><div>
</div></div><div><div><div>70</div></div><div><span>      </span><span>.right</span><span> </span><span>form</span><span> {</span></div></div><div><div><div>71</div></div><div><span><span>        </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>72</div></div><div><span><span>        </span></span><span>top: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>73</div></div><div><span><span>        </span></span><span>left: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>74</div></div><div><span><span>        </span></span><span>transform: </span><span>translate</span><span>(</span><span><span>-50</span><span>%</span></span><span>, </span><span><span>-50</span><span>%</span></span><span>);</span></div></div><div><div><div>75</div></div><div><span><span>        </span></span><span>width: </span><span><span>80</span><span>%</span></span><span>;</span></div></div><div><div><div>76</div></div><div><span><span>        </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>77</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>78</div></div><div>
</div></div><div><div><div>79</div></div><div><span>      </span><span>h3</span><span> {</span></div></div><div><div><div>80</div></div><div><span><span>        </span></span><span>margin-bottom: </span><span><span>20</span><span>px</span></span><span>;</span></div></div><div><div><div>81</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>82</div></div><div>
</div></div><div><div><div>83</div></div><div><span>      </span><span>input</span><span> {</span></div></div><div><div><div>84</div></div><div><span><span>        </span></span><span>width: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>85</div></div><div><span><span>        </span></span><span>height: </span><span><span>30</span><span>px</span></span><span>;</span></div></div><div><div><div>86</div></div><div><span><span>        </span></span><span>border: </span><span><span>1</span><span>px</span></span><span><span> </span><span>solid</span><span> </span></span><span>#</span><span>767676</span><span>;</span></div></div><div><div><div>87</div></div><div><span><span>        </span></span><span>background-color: </span><span>transparent</span><span>;</span></div></div><div><div><div>88</div></div><div><span><span>        </span></span><span>padding-left: </span><span><span>10</span><span>px</span></span><span>;</span></div></div><div><div><div>89</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>12</span><span>px</span></span><span>;</span></div></div><div><div><div>90</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>000000</span><span>;</span></div></div><div><div><div>91</div></div><div><span><span>        </span></span><span>margin-bottom: </span><span><span>15</span><span>px</span></span><span>;</span></div></div><div><div><div>92</div></div><div><span><span>        </span></span><span>outline: </span><span>none</span><span>;</span></div></div><div><div><div>93</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>94</div></div><div>
</div></div><div><div><div>95</div></div><div><span>      </span><span>.loginBtn</span><span> {</span></div></div><div><div><div>96</div></div><div><span><span>        </span></span><span>width: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>97</div></div><div><span><span>        </span></span><span>height: </span><span><span>35</span><span>px</span></span><span>;</span></div></div><div><div><div>98</div></div><div><span><span>        </span></span><span>line-height: </span><span><span>32</span><span>px</span></span><span>;</span></div></div><div><div><div>99</div></div><div><span><span>        </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>100</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>15</span><span>px</span></span><span>;</span></div></div><div><div><div>101</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>102</div></div><div><span><span>        </span></span><span>border-radius: </span><span><span>6</span><span>px</span></span><span>;</span></div></div><div><div><div>103</div></div><div><span><span>        </span></span><span>background: </span><span>rgb</span><span>(</span><span>57</span><span>, </span><span>99</span><span>, </span><span>134</span><span>);</span></div></div><div><div><div>104</div></div><div><span><span>        </span></span><span>outline: </span><span>none</span><span>;</span></div></div><div><div><div>105</div></div><div><span><span>        </span></span><span>border: </span><span>none</span><span>;</span></div></div><div><div><div>106</div></div><div><span><span>        </span></span><span>margin-top: </span><span><span>10</span><span>px</span></span><span>;</span></div></div><div><div><div>107</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>108</div></div><div>
</div></div><div><div><div>109</div></div><div><span>      </span><span>.no</span><span> {</span></div></div><div><div><div>110</div></div><div><span><span>        </span></span><span>cursor: </span><span>pointer</span><span>;</span></div></div><div><div><div>111</div></div><div><span><span>        </span></span><span>margin-top: </span><span><span>30</span><span>px</span></span><span>;</span></div></div><div><div><div>112</div></div><div><span><span>        </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>113</div></div><div><span><span>        </span></span><span>font-size: </span><span><span>12</span><span>px</span></span><span>;</span></div></div><div><div><div>114</div></div><div><span><span>        </span></span><span>color: </span><span>#</span><span>828282</span><span>;</span></div></div><div><div><div>115</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>116</div></div><div><span><span>    </span></span><span>&lt;/</span><span>style</span><span>&gt;</span></div></div><div><div><div>117</div></div><div><span><span>  </span></span><span>&lt;/</span><span>head</span><span>&gt;</span></div></div><div><div><div>118</div></div><div><span><span>  </span></span><span>&lt;</span><span>body</span><span>&gt;</span></div></div><div><div><div>119</div></div><div><span><span>    </span></span><span>&lt;</span><span>div</span><span> </span><span>class</span><span>=</span><span>"Box"</span><span>&gt;</span></div></div><div><div><div>120</div></div><div><span><span>      </span></span><span>&lt;</span><span>div</span><span> </span><span>class</span><span>=</span><span>"left"</span><span>&gt;</span></div></div><div><div><div>121</div></div><div><span><span>        </span></span><span>&lt;</span><span>div</span><span> </span><span>class</span><span>=</span><span>"centerBox"</span><span>&gt;</span></div></div><div><div><div>122</div></div><div><span><span>          </span></span><span>&lt;</span><span>img</span><span> </span><span>src</span><span>=</span><span>"https://img0.baidu.com/it/u=2804005887,994501744&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=200&amp;h=200"</span></div></div><div><div><div>123</div></div><div><span>            </span><span>alt</span><span>=</span><span>""</span><span>&gt;</span></div></div><div><div><div>124</div></div><div><span><span>          </span></span><span>&lt;</span><span>h4</span><span>&gt;某某后台管理系统&lt;/</span><span>h4</span><span>&gt;</span></div></div><div><div><div>125</div></div><div><span><span>          </span></span><span>&lt;</span><span>p</span><span>&gt;This is a description&lt;/</span><span>p</span><span>&gt;</span></div></div><div><div><div>126</div></div><div><span><span>        </span></span><span>&lt;/</span><span>div</span><span>&gt;</span></div></div><div><div><div>127</div></div><div><span><span>      </span></span><span>&lt;/</span><span>div</span><span>&gt;</span></div></div><div><div><div>128</div></div><div><span><span>      </span></span><span>&lt;</span><span>div</span><span> </span><span>class</span><span>=</span><span>"right"</span><span>&gt;</span></div></div><div><div><div>129</div></div><div><span><span>        </span></span><span>&lt;</span><span>form</span><span> </span><span>action</span><span>=</span><span>""</span><span>&gt;</span></div></div><div><div><div>130</div></div><div><span><span>          </span></span><span>&lt;</span><span>h3</span><span>&gt;欢迎登录&lt;/</span><span>h3</span><span>&gt;</span></div></div><div><div><div>131</div></div><div><span><span>          </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"text"</span><span> </span><span>placeholder</span><span>=</span><span>"请输入账号"</span><span> </span><span>required</span><span>&gt;</span></div></div><div><div><div>132</div></div><div><span><span>          </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"password"</span><span> </span><span>placeholder</span><span>=</span><span>"请输入密码"</span><span> </span><span>required</span><span>&gt;</span></div></div><div><div><div>133</div></div><div><span><span>          </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"submit"</span><span> </span><span>class</span><span>=</span><span>"loginBtn"</span><span> </span><span>value</span><span>=</span><span>"登录"</span><span>&gt;&lt;/</span><span>button</span><span>&gt;</span></div></div><div><div><div>134</div></div><div><span><span>          </span></span><span>&lt;</span><span>p</span><span> </span><span>class</span><span>=</span><span>"no"</span><span>&gt;没有账号？立即注册&lt;/</span><span>p</span><span>&gt;</span></div></div><div><div><div>135</div></div><div><span><span>        </span></span><span>&lt;/</span><span>form</span><span>&gt;</span></div></div><div><div><div>136</div></div><div>
</div></div><div><div><div>137</div></div><div><span><span>      </span></span><span>&lt;/</span><span>div</span><span>&gt;</span></div></div><div><div><div>138</div></div><div><span><span>    </span></span><span>&lt;/</span><span>div</span><span>&gt;</span></div></div><div><div><div>139</div></div><div><span><span>  </span></span><span>&lt;/</span><span>body</span><span>&gt;</span></div></div><div><div><div>140</div></div><div><span>&lt;/</span><span>html</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/fc344f65/</id>
      <title type="text">【uniapp】小程序滚动tab</title>
      <published>2024-08-11T18:31:13.000Z</published>
      <updated>2024-08-11T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/fc344f65/"/>
      <summary type="text">本文档详细介绍了如何使用 UniApp 实现一个滚动的 Tab 栏。滚动 Tab 栏在小程序中非常常见，适用于需要展示多个选项卡且每个选项卡内容较多的情况。本文将通过两个不同的实现方式（文字版和图片版）来展示如何实现这一功能。</summary>
      <content type="html"><![CDATA[<section><h3>文字版<a href="#文字版"><span>#</span></a></h3><section><h4>效果图<a href="#效果图"><span>#</span></a></h4><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/08/640%3Fwx_fmt%3Dgif%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%7Bstr-number%7D" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section><section><h4>源码<a href="#源码"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>template</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"content"</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"scrollBox"</span><span>&gt;</span></div></div><div><div><div>4</div></div><div><span><span>      </span></span><span>&lt;</span><span>scroll-view</span><span> </span><span>class</span><span>=</span><span>"scroll"</span><span> </span><span>scroll-x</span><span>=</span><span>'true'</span><span> </span><span>scroll-with-animation</span><span> </span><span>:scroll-left</span><span>=</span><span>'scrollLeft'</span><span>&gt;</span></div></div><div><div><div>5</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"tabBox"</span><span> </span><span>v-for</span><span>=</span><span>"(item,index) in tabsList"</span><span> </span><span>:key</span><span>=</span><span>"index"</span></div></div><div><div><div>6</div></div><div><span>          </span><span>:class</span><span>=</span><span>"[{ active: currentIndex === index }, 'scroll-item']"</span><span> </span><span>@click</span><span>=</span><span>"changeTab(index)"</span><span>&gt;</span></div></div><div><div><div>7</div></div><div><span><span>          </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"nanum"</span><span> </span><span>:class</span><span>=</span><span>"currentIndex === index?'active':''"</span><span>&gt;</span></div></div><div><div><div>8</div></div><div><span><span>            </span></span><span>{{index+1}}</span></div></div><div><div><div>9</div></div><div><span><span>          </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>10</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>&lt;/</span><span>scroll-view</span><span>&gt;</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>13</div></div><div><span><span>  </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>14</div></div><div><span>&lt;/</span><span>template</span><span>&gt;</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span>&lt;</span><span>script</span><span>&gt;</span></div></div><div><div><div>17</div></div><div><span>  </span><span>export</span><span> </span><span>default</span><span> {</span></div></div><div><div><div>18</div></div><div><span>    </span><span>data</span><span>() {</span></div></div><div><div><div>19</div></div><div><span>      </span><span>return</span><span> {</span></div></div><div><div><div>20</div></div><div><span>        </span><span>scrollWidth</span><span>:</span><span> </span><span>0</span><span>,</span></div></div><div><div><div>21</div></div><div><span>        </span><span>tabsList</span><span>:</span><span> [{</span></div></div><div><div><div>22</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>1</span><span>,</span></div></div><div><div><div>23</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'tab1'</span><span>,</span></div></div><div><div><div>24</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>25</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>26</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>2</span><span>,</span></div></div><div><div><div>27</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'tab2'</span><span>,</span></div></div><div><div><div>28</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>29</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>30</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>3</span><span>,</span></div></div><div><div><div>31</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'tab3'</span><span>,</span></div></div><div><div><div>32</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>33</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>34</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>4</span><span>,</span></div></div><div><div><div>35</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'tab4'</span><span>,</span></div></div><div><div><div>36</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>37</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>38</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>5</span><span>,</span></div></div><div><div><div>39</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'tab5'</span><span>,</span></div></div><div><div><div>40</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>41</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>42</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>6</span><span>,</span></div></div><div><div><div>43</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'tab6'</span><span>,</span></div></div><div><div><div>44</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>45</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>46</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>7</span><span>,</span></div></div><div><div><div>47</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'tab7'</span><span>,</span></div></div><div><div><div>48</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>49</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>50</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>8</span><span>,</span></div></div><div><div><div>51</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'tab8'</span><span>,</span></div></div><div><div><div>52</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>53</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>54</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>9</span><span>,</span></div></div><div><div><div>55</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'tab9'</span><span>,</span></div></div><div><div><div>56</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>57</div></div><div><span><span>        </span></span><span>],</span></div></div><div><div><div>58</div></div><div><span>        </span><span>currentIndex</span><span>:</span><span> </span><span>0</span><span>,</span></div></div><div><div><div>59</div></div><div><span>        </span><span>scrollLeft</span><span>:</span><span> </span><span>0</span><span>,</span></div></div><div><div><div>60</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>61</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>62</div></div><div><span>    </span><span>onLoad</span><span>() {</span></div></div><div><div><div>63</div></div><div><span>      </span><span>// 获取元素宽度</span></div></div><div><div><div>64</div></div><div><span>      </span><span>const</span><span> </span><span>query</span><span> </span><span>=</span><span><span> </span><span>uni</span><span>.</span></span><span>createSelectorQuery</span><span>().</span><span>select</span><span>(</span><span>'.scroll'</span><span>);</span></div></div><div><div><div>65</div></div><div><span><span>      </span></span><span>query</span><span>.</span><span>boundingClientRect</span><span><span>(</span><span>res</span><span> </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>66</div></div><div><span>        </span><span>this</span><span>.</span><span>scrollWidth</span><span> </span><span>=</span><span><span> </span><span>res</span><span>.</span></span><span>width</span><span>;</span></div></div><div><div><div>67</div></div><div><span><span>      </span></span><span>}).</span><span>exec</span><span>()</span></div></div><div><div><div>68</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>69</div></div><div>
</div></div><div><div><div>70</div></div><div><span>    </span><span>methods</span><span>:</span><span> {</span></div></div><div><div><div>71</div></div><div><span>      </span><span>// 切换Tab</span></div></div><div><div><div>72</div></div><div><span>      </span><span>changeTab</span><span><span>(</span><span>index</span><span>) {</span></span></div></div><div><div><div>73</div></div><div><span><span>        </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>index</span><span>, </span><span>"文字tab"</span><span>);</span></div></div><div><div><div>74</div></div><div><span>        </span><span>this</span><span>.</span><span>currentIndex</span><span> </span><span>=</span><span> </span><span>index</span><span>;</span></div></div><div><div><div>75</div></div><div><span>        </span><span>this</span><span>.</span><span>moveTo</span><span>(</span><span>index</span><span>)</span></div></div><div><div><div>76</div></div><div><span><span>      </span></span><span>},</span></div></div><div><div><div>77</div></div><div><span>      </span><span>// 当前点击的元素移动到屏幕中间</span></div></div><div><div><div>78</div></div><div><span>      </span><span>moveTo</span><span><span>(</span><span>index</span><span>) {</span></span></div></div><div><div><div>79</div></div><div><span>        </span><span>const</span><span> </span><span>query</span><span> </span><span>=</span><span><span> </span><span>uni</span><span>.</span></span><span>createSelectorQuery</span><span>().</span><span>in</span><span>(</span><span>this</span><span>)</span></div></div><div><div><div>80</div></div><div><span><span>        </span></span><span>query</span><span>.</span><span>selectAll</span><span>(</span><span>'.scroll-item'</span><span>).</span><span>boundingClientRect</span><span><span>(</span><span>rect</span><span> </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>81</div></div><div><span>          </span><span>const</span><span> </span><span>windowWidth</span><span> </span><span>=</span><span> </span><span>this</span><span>.</span><span>scrollWidth</span><span>; </span><span>// 获取到的屏幕宽度</span></div></div><div><div><div>82</div></div><div><span>          </span><span>let</span><span> </span><span>width</span><span> </span><span>=</span><span> </span><span>0</span></div></div><div><div><div>83</div></div><div><span>          </span><span>// 计算当前点击的标签项距离左侧的距离</span></div></div><div><div><div>84</div></div><div><span>          </span><span>for</span><span> (</span><span>let</span><span> </span><span>i</span><span> </span><span>=</span><span> </span><span>0</span><span>; </span><span>i</span><span> </span><span>&lt;</span><span> </span><span>index</span><span>; </span><span>i</span><span>++</span><span>) {</span></div></div><div><div><div>85</div></div><div><span>            </span><span>width</span><span> </span><span>+=</span><span> </span><span>rect</span><span>[</span><span>i</span><span>].</span><span>width</span></div></div><div><div><div>86</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>87</div></div><div><span>          </span><span>// 当大于屏幕一半的宽度则滚动，否则就设置左侧位置为0</span></div></div><div><div><div>88</div></div><div><span>          </span><span>if</span><span> (</span><span>width</span><span> </span><span>&gt;</span><span> </span><span>windowWidth</span><span> </span><span>/</span><span> </span><span>2</span><span>) {</span></div></div><div><div><div>89</div></div><div><span>            </span><span>this</span><span>.</span><span>scrollLeft</span><span> </span><span>=</span><span> </span><span>width</span><span> </span><span>+</span><span> </span><span>rect</span><span>[</span><span>index</span><span>].</span><span>width</span><span> </span><span>/</span><span> </span><span>2</span><span> </span><span>-</span><span> </span><span>windowWidth</span><span> </span><span>/</span><span> </span><span>2</span></div></div><div><div><div>90</div></div><div><span><span>          </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>91</div></div><div><span>            </span><span>this</span><span>.</span><span>scrollLeft</span><span> </span><span>=</span><span> </span><span>0</span></div></div><div><div><div>92</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>93</div></div><div><span><span>        </span></span><span>}).</span><span>exec</span><span>()</span></div></div><div><div><div>94</div></div><div><span><span>      </span></span><span>},</span></div></div><div><div><div>95</div></div><div>
</div></div><div><div><div>96</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>97</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>98</div></div><div><span>&lt;/</span><span>script</span><span>&gt;</span></div></div><div><div><div>99</div></div><div>
</div></div><div><div><div>100</div></div><div><span>&lt;</span><span>style</span><span> </span><span>scoped</span><span>&gt;</span></div></div><div><div><div>101</div></div><div><span>  </span><span>.scrollBox</span><span> </span><span>.tabBox</span><span> {</span></div></div><div><div><div>102</div></div><div><span><span>    </span></span><span>width: </span><span>150</span><span>rpx;</span></div></div><div><div><div>103</div></div><div><span><span>    </span></span><span>height: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>104</div></div><div><span><span>    </span></span><span>margin-right: </span><span>10</span><span>rpx;</span></div></div><div><div><div>105</div></div><div><span><span>    </span></span><span>padding: </span><span>4</span><span>rpx;</span></div></div><div><div><div>106</div></div><div><span><span>    </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>107</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>108</div></div><div><span><span>    </span></span><span>margin-top: </span><span>40</span><span>rpx;</span></div></div><div><div><div>109</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>110</div></div><div>
</div></div><div><div><div>111</div></div><div><span>  </span><span>.scrollBox</span><span> </span><span>.tabBox</span><span> </span><span>.nanum</span><span> {</span></div></div><div><div><div>112</div></div><div><span><span>    </span></span><span>width: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>113</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>114</div></div><div><span><span>    </span></span><span>font-size: </span><span>24</span><span>rpx;</span></div></div><div><div><div>115</div></div><div><span><span>    </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>116</div></div><div><span><span>    </span></span><span>bottom: </span><span>0</span><span>;</span></div></div><div><div><div>117</div></div><div><span><span>    </span></span><span>left: </span><span>0</span><span>;</span></div></div><div><div><div>118</div></div><div><span><span>    </span></span><span>height: </span><span>60</span><span>rpx;</span></div></div><div><div><div>119</div></div><div><span><span>    </span></span><span>line-height: </span><span>60</span><span>rpx;</span></div></div><div><div><div>120</div></div><div><span><span>    </span></span><span>background: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>121</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>122</div></div><div>
</div></div><div><div><div>123</div></div><div><span>  </span><span>.scroll</span><span> {</span></div></div><div><div><div>124</div></div><div><span><span>    </span></span><span>width: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>125</div></div><div><span><span>    </span></span><span>white-space: </span><span>nowrap</span><span>;</span></div></div><div><div><div>126</div></div><div><span><span>    </span></span><span>height: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>127</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>eee</span><span>;</span></div></div><div><div><div>128</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>129</div></div><div>
</div></div><div><div><div>130</div></div><div><span>  </span><span>.scroll</span><span> </span><span>view</span><span> {</span></div></div><div><div><div>131</div></div><div><span><span>    </span></span><span>display: </span><span>inline-block</span><span>;</span></div></div><div><div><div>132</div></div><div><span><span>    </span></span><span>font-size: </span><span>30</span><span>rpx;</span></div></div><div><div><div>133</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>000</span><span>;</span></div></div><div><div><div>134</div></div><div><span><span>    </span></span><span>position: </span><span>relative</span><span>;</span></div></div><div><div><div>135</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>136</div></div><div>
</div></div><div><div><div>137</div></div><div><span>  </span><span>.scroll</span><span> </span><span>view</span><span>.active</span><span> {</span></div></div><div><div><div>138</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>000000</span><span> </span><span>!important</span><span>;</span></div></div><div><div><div>139</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>fff</span><span> </span><span>!important</span><span>;</span></div></div><div><div><div>140</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>141</div></div><div><span>&lt;/</span><span>style</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><hr /></section></section>
<section><h3>图片版<a href="#图片版"><span>#</span></a></h3><section><h4>效果图<a href="#效果图-1"><span>#</span></a></h4><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/08/640%3Fwx_fmt%3Dgif%26from%3Dappmsg%26tp%3Dwebp%26wxfrom%3D5%26wx_lazy%3D1%7Bstr-number%7D" alt="图片" /><figcaption>图片</figcaption></figure><p></p></section><section><h4>源码<a href="#源码-1"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>template</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"content"</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"scrollBox"</span><span>&gt;</span></div></div><div><div><div>4</div></div><div><span><span>      </span></span><span>&lt;</span><span>scroll-view</span><span> </span><span>class</span><span>=</span><span>"scroll"</span><span> </span><span>scroll-x</span><span>=</span><span>'true'</span><span> </span><span>scroll-with-animation</span><span> </span><span>:scroll-left</span><span>=</span><span>'scrollLeft'</span><span>&gt;</span></div></div><div><div><div>5</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"imagbx"</span><span> </span><span>v-for</span><span>=</span><span>"(item,index) in tabsList"</span><span> </span><span>:key</span><span>=</span><span>"index"</span></div></div><div><div><div>6</div></div><div><span>          </span><span>:class</span><span>=</span><span>"[{ active: currentIndex === index }, 'scroll-item']"</span><span> </span><span>@click</span><span>=</span><span>"changeTab(index)"</span><span>&gt;</span></div></div><div><div><div>7</div></div><div><span><span>          </span></span><span>&lt;</span><span>image</span><span> </span><span>:src</span><span>=</span><span>"item.img"</span><span> </span><span>mode</span><span>=</span><span>"widthFix"</span><span>&gt;&lt;/</span><span>image</span><span>&gt;</span></div></div><div><div><div>8</div></div><div><span><span>          </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"nanum"</span><span> </span><span>:class</span><span>=</span><span>"currentIndex === index?'active':''"</span><span>&gt;</span></div></div><div><div><div>9</div></div><div><span><span>            </span></span><span>{{index+1}}</span></div></div><div><div><div>10</div></div><div><span><span>          </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>11</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>&lt;/</span><span>scroll-view</span><span>&gt;</span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>14</div></div><div><span><span>  </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>15</div></div><div><span>&lt;/</span><span>template</span><span>&gt;</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>&lt;</span><span>script</span><span>&gt;</span></div></div><div><div><div>18</div></div><div><span>  </span><span>export</span><span> </span><span>default</span><span> {</span></div></div><div><div><div>19</div></div><div><span>    </span><span>data</span><span>() {</span></div></div><div><div><div>20</div></div><div><span>      </span><span>return</span><span> {</span></div></div><div><div><div>21</div></div><div><span>        </span><span>scrollWidth</span><span>:</span><span> </span><span>0</span><span>,</span></div></div><div><div><div>22</div></div><div><span>        </span><span>tabsList</span><span>:</span><span> [{</span></div></div><div><div><div>23</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>1</span><span>,</span></div></div><div><div><div>24</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'img1'</span><span>,</span></div></div><div><div><div>25</div></div><div><span>            </span><span>img</span><span>:</span><span> </span><span>'https://img.pconline.com.cn/images/product/1144409/201812/10/15444358345118610_800.png'</span></div></div><div><div><div>26</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>27</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>28</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>2</span><span>,</span></div></div><div><div><div>29</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'img2'</span><span>,</span></div></div><div><div><div>30</div></div><div><span>            </span><span>img</span><span>:</span><span> </span><span>'https://img.pconline.com.cn/images/product/1144409/201812/10/15444358345118610_800.png'</span></div></div><div><div><div>31</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>32</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>33</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>3</span><span>,</span></div></div><div><div><div>34</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'img3'</span><span>,</span></div></div><div><div><div>35</div></div><div><span>            </span><span>img</span><span>:</span><span> </span><span>'https://img.pconline.com.cn/images/product/1144409/201812/10/15444358345118610_800.png'</span></div></div><div><div><div>36</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>37</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>38</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>4</span><span>,</span></div></div><div><div><div>39</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'img4'</span><span>,</span></div></div><div><div><div>40</div></div><div><span>            </span><span>img</span><span>:</span><span> </span><span>'https://img.pconline.com.cn/images/product/1144409/201812/10/15444358345118610_800.png'</span></div></div><div><div><div>41</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>42</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>43</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>5</span><span>,</span></div></div><div><div><div>44</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'img5'</span><span>,</span></div></div><div><div><div>45</div></div><div><span>            </span><span>img</span><span>:</span><span> </span><span>'https://img.pconline.com.cn/images/product/1144409/201812/10/15444358345118610_800.png'</span></div></div><div><div><div>46</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>47</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>48</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>6</span><span>,</span></div></div><div><div><div>49</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'img6'</span><span>,</span></div></div><div><div><div>50</div></div><div><span>            </span><span>img</span><span>:</span><span> </span><span>'https://img.pconline.com.cn/images/product/1144409/201812/10/15444358345118610_800.png'</span></div></div><div><div><div>51</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>52</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>53</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>7</span><span>,</span></div></div><div><div><div>54</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'img7'</span><span>,</span></div></div><div><div><div>55</div></div><div><span>            </span><span>img</span><span>:</span><span> </span><span>'https://img.pconline.com.cn/images/product/1144409/201812/10/15444358345118610_800.png'</span></div></div><div><div><div>56</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>57</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>58</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>8</span><span>,</span></div></div><div><div><div>59</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'img8'</span><span>,</span></div></div><div><div><div>60</div></div><div><span>            </span><span>img</span><span>:</span><span> </span><span>'https://img.pconline.com.cn/images/product/1144409/201812/10/15444358345118610_800.png'</span></div></div><div><div><div>61</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>62</div></div><div><span><span>          </span></span><span>{</span></div></div><div><div><div>63</div></div><div><span>            </span><span>id</span><span>:</span><span> </span><span>9</span><span>,</span></div></div><div><div><div>64</div></div><div><span>            </span><span>name</span><span>:</span><span> </span><span>'img9'</span><span>,</span></div></div><div><div><div>65</div></div><div><span>            </span><span>img</span><span>:</span><span> </span><span>'https://img.pconline.com.cn/images/product/1144409/201812/10/15444358345118610_800.png'</span></div></div><div><div><div>66</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>67</div></div><div><span><span>        </span></span><span>],</span></div></div><div><div><div>68</div></div><div><span>        </span><span>currentIndex</span><span>:</span><span> </span><span>0</span><span>,</span></div></div><div><div><div>69</div></div><div><span>        </span><span>scrollLeft</span><span>:</span><span> </span><span>0</span><span>,</span></div></div><div><div><div>70</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>71</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>72</div></div><div><span>    </span><span>onLoad</span><span>() {</span></div></div><div><div><div>73</div></div><div><span>      </span><span>// 获取元素宽度</span></div></div><div><div><div>74</div></div><div><span>      </span><span>const</span><span> </span><span>query</span><span> </span><span>=</span><span><span> </span><span>uni</span><span>.</span></span><span>createSelectorQuery</span><span>().</span><span>select</span><span>(</span><span>'.scroll'</span><span>);</span></div></div><div><div><div>75</div></div><div><span><span>      </span></span><span>query</span><span>.</span><span>boundingClientRect</span><span><span>(</span><span>res</span><span> </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>76</div></div><div><span>        </span><span>this</span><span>.</span><span>scrollWidth</span><span> </span><span>=</span><span><span> </span><span>res</span><span>.</span></span><span>width</span><span>;</span></div></div><div><div><div>77</div></div><div><span><span>      </span></span><span>}).</span><span>exec</span><span>()</span></div></div><div><div><div>78</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>79</div></div><div>
</div></div><div><div><div>80</div></div><div><span>    </span><span>methods</span><span>:</span><span> {</span></div></div><div><div><div>81</div></div><div><span>      </span><span>// 点击切换Tab</span></div></div><div><div><div>82</div></div><div><span>      </span><span>changeTab</span><span><span>(</span><span>index</span><span>) {</span></span></div></div><div><div><div>83</div></div><div><span><span>        </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>index</span><span>, </span><span>"图片tab"</span><span>);</span></div></div><div><div><div>84</div></div><div><span>        </span><span>this</span><span>.</span><span>currentIndex</span><span> </span><span>=</span><span> </span><span>index</span><span>;</span></div></div><div><div><div>85</div></div><div><span>        </span><span>this</span><span>.</span><span>moveTo</span><span>(</span><span>index</span><span>)</span></div></div><div><div><div>86</div></div><div><span><span>      </span></span><span>},</span></div></div><div><div><div>87</div></div><div><span>      </span><span>// 点击元素移动到中间</span></div></div><div><div><div>88</div></div><div><span>      </span><span>moveTo</span><span><span>(</span><span>index</span><span>) {</span></span></div></div><div><div><div>89</div></div><div><span>        </span><span>const</span><span> </span><span>query</span><span> </span><span>=</span><span><span> </span><span>uni</span><span>.</span></span><span>createSelectorQuery</span><span>().</span><span>in</span><span>(</span><span>this</span><span>)</span></div></div><div><div><div>90</div></div><div><span><span>        </span></span><span>query</span><span>.</span><span>selectAll</span><span>(</span><span>`.scroll-item`</span><span>).</span><span>boundingClientRect</span><span><span>(</span><span>rect</span><span> </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>91</div></div><div><span>          </span><span>const</span><span> </span><span>windowWidth</span><span> </span><span>=</span><span> </span><span>this</span><span>.</span><span>scrollWidth</span><span>; </span><span>// 屏幕宽度</span></div></div><div><div><div>92</div></div><div><span>          </span><span>let</span><span> </span><span>width</span><span> </span><span>=</span><span> </span><span>0</span></div></div><div><div><div>93</div></div><div><span>          </span><span>// 计算当前点击的标签项距离左侧的距离</span></div></div><div><div><div>94</div></div><div><span>          </span><span>for</span><span> (</span><span>let</span><span> </span><span>i</span><span> </span><span>=</span><span> </span><span>0</span><span>; </span><span>i</span><span> </span><span>&lt;</span><span> </span><span>index</span><span>; </span><span>i</span><span>++</span><span>) {</span></div></div><div><div><div>95</div></div><div><span>            </span><span>width</span><span> </span><span>+=</span><span> </span><span>rect</span><span>[</span><span>i</span><span>].</span><span>width</span></div></div><div><div><div>96</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>97</div></div><div><span>          </span><span>// 当大于屏幕一半的宽度则滚动，否则就设置左侧位置为0</span></div></div><div><div><div>98</div></div><div><span>          </span><span>if</span><span> (</span><span>width</span><span> </span><span>&gt;</span><span> </span><span>windowWidth</span><span> </span><span>/</span><span> </span><span>2</span><span>) {</span></div></div><div><div><div>99</div></div><div><span>            </span><span>this</span><span>.</span><span>scrollLeft</span><span> </span><span>=</span><span> </span><span>width</span><span> </span><span>+</span><span> </span><span>rect</span><span>[</span><span>index</span><span>].</span><span>width</span><span> </span><span>/</span><span> </span><span>2</span><span> </span><span>-</span><span> </span><span>windowWidth</span><span> </span><span>/</span><span> </span><span>2</span></div></div><div><div><div>100</div></div><div><span><span>          </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>101</div></div><div><span>            </span><span>this</span><span>.</span><span>scrollLeft</span><span> </span><span>=</span><span> </span><span>0</span></div></div><div><div><div>102</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>103</div></div><div><span><span>        </span></span><span>}).</span><span>exec</span><span>()</span></div></div><div><div><div>104</div></div><div><span><span>      </span></span><span>},</span></div></div><div><div><div>105</div></div><div>
</div></div><div><div><div>106</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>107</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>108</div></div><div><span>&lt;/</span><span>script</span><span>&gt;</span></div></div><div><div><div>109</div></div><div>
</div></div><div><div><div>110</div></div><div><span>&lt;</span><span>style</span><span> </span><span>scoped</span><span>&gt;</span></div></div><div><div><div>111</div></div><div><span>  </span><span>.scrollBox</span><span> </span><span>.imagbx</span><span> {</span></div></div><div><div><div>112</div></div><div><span><span>    </span></span><span>width: </span><span>150</span><span>rpx;</span></div></div><div><div><div>113</div></div><div><span><span>    </span></span><span>height: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>114</div></div><div><span><span>    </span></span><span>margin-right: </span><span>10</span><span>rpx;</span></div></div><div><div><div>115</div></div><div><span><span>    </span></span><span>padding: </span><span>4</span><span>rpx;</span></div></div><div><div><div>116</div></div><div><span><span>    </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>117</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>118</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>119</div></div><div>
</div></div><div><div><div>120</div></div><div><span>  </span><span>.scrollBox</span><span> </span><span>.imagbx</span><span> </span><span>image</span><span> {</span></div></div><div><div><div>121</div></div><div><span><span>    </span></span><span>height: </span><span>160</span><span>rpx;</span></div></div><div><div><div>122</div></div><div><span><span>    </span></span><span>width: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>123</div></div><div><span><span>    </span></span><span>margin-bottom: </span><span>44</span><span>rpx;</span></div></div><div><div><div>124</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>125</div></div><div>
</div></div><div><div><div>126</div></div><div><span>  </span><span>.scrollBox</span><span> </span><span>.imagbx</span><span> </span><span>.nanum</span><span> {</span></div></div><div><div><div>127</div></div><div><span><span>    </span></span><span>width: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>128</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>129</div></div><div><span><span>    </span></span><span>font-size: </span><span>24</span><span>rpx;</span></div></div><div><div><div>130</div></div><div><span><span>    </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>131</div></div><div><span><span>    </span></span><span>bottom: </span><span>0</span><span>;</span></div></div><div><div><div>132</div></div><div><span><span>    </span></span><span>left: </span><span>0</span><span>;</span></div></div><div><div><div>133</div></div><div><span><span>    </span></span><span>height: </span><span>40</span><span>rpx;</span></div></div><div><div><div>134</div></div><div><span><span>    </span></span><span>background: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>135</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>136</div></div><div>
</div></div><div><div><div>137</div></div><div><span>  </span><span>.scroll</span><span> {</span></div></div><div><div><div>138</div></div><div><span><span>    </span></span><span>width: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>139</div></div><div><span><span>    </span></span><span>white-space: </span><span>nowrap</span><span>;</span></div></div><div><div><div>140</div></div><div><span><span>    </span></span><span>height: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>141</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>eee</span><span>;</span></div></div><div><div><div>142</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>143</div></div><div>
</div></div><div><div><div>144</div></div><div><span>  </span><span>.scroll</span><span> </span><span>view</span><span> {</span></div></div><div><div><div>145</div></div><div><span><span>    </span></span><span>display: </span><span>inline-block</span><span>;</span></div></div><div><div><div>146</div></div><div><span><span>    </span></span><span>font-size: </span><span>30</span><span>upx;</span></div></div><div><div><div>147</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>000</span><span>;</span></div></div><div><div><div>148</div></div><div><span><span>    </span></span><span>position: </span><span>relative</span><span>;</span></div></div><div><div><div>149</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>150</div></div><div>
</div></div><div><div><div>151</div></div><div><span>  </span><span>.scroll</span><span> </span><span>view</span><span>.active</span><span> {</span></div></div><div><div><div>152</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>000000</span><span> </span><span>!important</span><span>;</span></div></div><div><div><div>153</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>fff</span><span> </span><span>!important</span><span>;</span></div></div><div><div><div>154</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>155</div></div><div><span>&lt;/</span><span>style</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/5f2de2cf/</id>
      <title type="text">【MACCMS】docker环境中安装服务</title>
      <published>2024-08-01T08:31:13.000Z</published>
      <updated>2024-08-01T08:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/5f2de2cf/"/>
      <summary type="text">本文详细介绍了如何在Docker环境中安装和配置MACCMS视频管理系统。首先，文章指导读者准备Docker环境，包括安装Docker以及创建所需的网络。接着，依次介绍了如何安装和配置MySQL、Nginx和PHP容器，确保这些服务能够正常运行并相互协作。随后，文章提供了MACCMS项目文件的下载和部署步骤，包括文件的解压、权限设置等。此外，还详细描述了Nginx的配置方法，以支持MACCMS的正常访问。最后，文章给出了如何配置视频分类的具体SQL语句，帮助用户快速完成系统的初始化设置。通过本文的指导，读者可以顺利地在Docker环境中搭建一个功能完整的MACCMS视频管理平台。</summary>
      <content type="html"><![CDATA[<section><h2>环境准备<a href="#环境准备"><span>#</span></a></h2><ul>
<li>Docker
<ul>
<li>Mysql</li>
<li>Nginx</li>
<li>Php</li>
</ul>
</li>
<li><a href="https://github.com/magicblack/maccms10/releases" target="_blank">maccmsV10 项目文件</a></li>
<li><a href="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/07/6e7b7cb7ecc2cabf146b694492444590.zip" target="_blank">模板文件</a></li>
<li><a href="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/08/830bdd46a759797d47a71490dba2d6c5.zip" target="_blank">萌芽采集插件</a></li>
<li><a href="https://www.dkewl.com/" target="_blank">集模板/插件于一身的网站</a></li>
<li><a href="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/08/b8b949ab6f2d0ecf68206a3542a6cfda.rar" target="_blank">移动端模板</a></li>
<li><a href="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/08/255ffd96a9b9f336d9dd5e7f660351f3.zip" target="_blank">pc端模板</a></li>
<li>安装waf防火墙（可选）</li>
</ul></section>
<section><h2>安装<a href="#安装"><span>#</span></a></h2><ol>
<li>
<p>安装好docker后，运行如下命令创建bridge网络：<code>docker network create maccmsnet</code></p>
<ul>
<li>查询到新创建的bridge maccmsnet</li>
</ul>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/07/ad6969e884e85b8babfff9b5cb135e6f.png" alt="image-20240731091413134" /><figcaption>image-20240731091413134</figcaption></figure><p></p>
<ul>
<li>查看网桥下的容器ip信息： <code>docker network inspect maccmsnet</code></li>
</ul>
</li>
</ol><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/07/554c29c1a5f55bbf6f97dee12519f5bf.png" alt="image-20240731091525753" /><figcaption>image-20240731091525753</figcaption></figure><p></p><ol>
<li>
<p>运行容器连接到<code>maccmsnet</code>网络</p>
<ul>
<li>
<p>Mysql 安装</p>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 下载MySQL镜像</span></div></div><div><div><div>2</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>pull</span><span> </span><span>mysql:5.7.41</span></div></div><div><div><div>3</div></div><div><span># 初始化目录，后续MySQL的文件都会放在这里</span></div></div><div><div><div>4</div></div><div><span>$</span><span> </span><span>mkdir</span><span> </span><span>-p</span><span> </span><span>/opt/docker/mysql</span></div></div><div><div><div>5</div></div><div><span>$</span><span> </span><span>cd</span><span> </span><span>/opt/docker/mysql</span></div></div><div><div><div>6</div></div><div><span># 运行空的MySQL容器，注意MySQL密码需要自己设置一下MYSQL_ROOT_PASSWORD</span></div></div><div><div><div>7</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>run</span><span> </span><span>--name</span><span> </span><span>mysql</span><span> </span><span>-e</span><span> </span><span>MYSQL_ROOT_PASSWORD=</span><span>123456</span><span> </span><span>-d</span><span> </span><span>mysql:5.7.41</span></div></div><div><div><div>8</div></div><div><span># 将容器内的文件拷贝出来，防止运行容器后文件被覆盖的问题</span></div></div><div><div><div>9</div></div><div><span>$</span><span> </span><span>mkdir</span><span> </span><span>-p</span><span> </span><span>/opt/docker/mysql/conf</span></div></div><div><div><div>10</div></div><div><span># 2-创建配置文件</span></div></div><div><div><div>11</div></div><div><span>$</span><span> </span><span>vi</span><span> </span><span>conf/my.config</span></div></div><div><div><div>12</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>cp</span><span> </span><span>mysql:/var/lib/mysql</span><span> </span><span>/opt/docker/mysql/</span></div></div><div><div><div>13</div></div><div><span>$</span><span> </span><span>mv</span><span> </span><span>mysql</span><span> </span><span>data</span></div></div><div><div><div>14</div></div><div><span># 删除后重新启动一个容器</span></div></div><div><div><div>15</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>rm</span><span> </span><span>-f</span><span> </span><span>mysql</span></div></div><div><div><div>16</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>run</span><span> </span><span>--name</span><span> </span><span>mysql</span><span>    </span><span>-e</span><span> </span><span>TZ=Asia/Shanghai</span><span>    </span><span>-p</span><span> </span><span>33006:3306</span><span>    </span><span>--restart</span><span> </span><span>always</span><span>    </span><span>-v</span><span> </span><span>/opt/docker/mysql/data:/var/lib/mysql</span><span>    </span><span>-v</span><span> </span><span>/opt/docker/mysql/logs:/var/log/mysql</span><span>    </span><span>-v</span><span> </span><span>/opt/docker/mysql/conf/my.config:/etc/mysql/my.config</span><span>    </span><span>-e</span><span> </span><span>MYSQL_ROOT_PASSWORD=</span><span>123456</span><span> </span><span>--network</span><span> </span><span>maccmsnet</span><span> </span><span>--network-alias</span><span> </span><span>mysql</span><span>   </span><span>-d</span><span> </span><span>mysql:5.7.41</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># my.config</span></div></div><div><div><div>2</div></div><div><span>[mysql]</span></div></div><div><div><div>3</div></div><div><span>#设置mysql客户端默认字符集</span></div></div><div><div><div>4</div></div><div><span>default-character-set</span><span>=</span><span>UTF8MB4</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>[mysqld]</span></div></div><div><div><div>7</div></div><div><span>#设置3306端口</span></div></div><div><div><div>8</div></div><div><span>port</span><span>=</span><span>3306</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>#允许最大连接数</span></div></div><div><div><div>11</div></div><div><span>max_connections</span><span>=</span><span>200</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>#允许连接失败的次数</span></div></div><div><div><div>14</div></div><div><span>max_connect_errors</span><span>=</span><span>10</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span>#默认使用“mysql_native_password”插件认证</span></div></div><div><div><div>17</div></div><div><span>default_authentication_plugin</span><span>=</span><span>mysql_native_password</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>#服务端使用的字符集默认为8比特编码的latin1字符集</span></div></div><div><div><div>20</div></div><div><span>character-set-server</span><span>=</span><span>UTF8MB4</span></div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span>#开启查询缓存</span></div></div><div><div><div>23</div></div><div><span>explicit_defaults_for_timestamp</span><span>=</span><span>true</span></div></div><div><div><div>24</div></div><div>
</div></div><div><div><div>25</div></div><div><span>#创建新表时将使用的默认存储引擎</span></div></div><div><div><div>26</div></div><div><span>default-storage-engine</span><span>=</span><span>INNODB</span></div></div><div><div><div>27</div></div><div>
</div></div><div><div><div>28</div></div><div><span>#等待超时时间秒</span></div></div><div><div><div>29</div></div><div><span>wait_timeout</span><span>=</span><span>60</span></div></div><div><div><div>30</div></div><div>
</div></div><div><div><div>31</div></div><div><span>#交互式连接超时时间秒</span></div></div><div><div><div>32</div></div><div><span>interactive-timeout</span><span>=</span><span>600</span></div></div><div><div><div>33</div></div><div><span>secure_file_priv</span><span>=</span><span>/var/lib/mysql</span></div></div><div><div><div>34</div></div><div>
</div></div><div><div><div>35</div></div><div><span>[client]</span></div></div><div><div><div>36</div></div><div><span>default-character-set</span><span>=</span><span>UTF8MB4</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>#登入容器内</span></div></div><div><div><div>2</div></div><div><span>docker</span><span> </span><span>exec</span><span> </span><span>-it</span><span> </span><span>&lt;container_id_or_name&gt;</span><span> </span><span>bash</span></div></div><div><div><div>3</div></div><div><span># 登录mysql</span></div></div><div><div><div>4</div></div><div><span>mysql</span><span> </span><span>-u</span><span> </span><span>root</span><span> </span><span>-p</span></div></div><div><div><div>5</div></div><div><span># 修改密码</span></div></div><div><div><div>6</div></div><div><span>ALTER</span><span> </span><span>USER</span><span> </span><span>'root'@'localhost'</span><span> </span><span>IDENTIFIED</span><span> </span><span>BY</span><span> </span><span>'new_password'</span><span>;</span></div></div><div><div><div>7</div></div><div><span># 刷新权限</span></div></div><div><div><div>8</div></div><div><span>FLUSH</span><span> </span><span>PRIVILEGES</span><span>;</span></div></div><div><div><div>9</div></div><div><span># 退出</span></div></div><div><div><div>10</div></div><div><span>exit</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<blockquote><ul>
<li>—name   容器名称</li>
<li>-e             配置时间区域</li>
<li>-p             主机端口和容器端口映射</li>
<li>—restart   自动重启</li>
<li>-v               配置文件/数据文件映射主机</li>
<li>—network 网络配置</li>
<li>—network-alias    网络别名</li>
</ul></blockquote>
</li>
<li>
<p>Nginx 安装</p>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 下载Nginx镜像</span></div></div><div><div><div>2</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>pull</span><span> </span><span>nginx:1.22.0</span></div></div><div><div><div>3</div></div><div><span># 初始化目录</span></div></div><div><div><div>4</div></div><div><span>$</span><span> </span><span>mkdir</span><span> </span><span>-p</span><span> </span><span>/opt/docker/nginx/ssl</span></div></div><div><div><div>5</div></div><div><span>$</span><span> </span><span>cd</span><span> </span><span>/opt/docker/nginx</span></div></div><div><div><div>6</div></div><div><span># 裸启动</span></div></div><div><div><div>7</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>--name</span><span> </span><span>nginx</span><span> </span><span>nginx:1.22.0</span></div></div><div><div><div>8</div></div><div><span># 拷贝文件</span></div></div><div><div><div>9</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>cp</span><span> </span><span>nginx:/etc/nginx</span><span> </span><span>/opt/docker/nginx</span></div></div><div><div><div>10</div></div><div><span>$</span><span> </span><span>mv</span><span> </span><span>nginx</span><span> </span><span>conf</span></div></div><div><div><div>11</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>cp</span><span> </span><span>nginx:/usr/share/nginx</span><span> </span><span>/opt/docker/nginx</span></div></div><div><div><div>12</div></div><div><span>$</span><span> </span><span>mv</span><span> </span><span>nginx</span><span> </span><span>webs</span></div></div><div><div><div>13</div></div><div><span># 删除裸启的容器</span></div></div><div><div><div>14</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>rm</span><span> </span><span>-f</span><span> </span><span>nginx</span></div></div><div><div><div>15</div></div><div><span># 正式启动容器</span></div></div><div><div><div>16</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>run</span><span> </span><span>--name</span><span> </span><span>nginx</span><span>    </span><span>-e</span><span> </span><span>TZ=Asia/Shanghai</span><span>    </span><span>-p</span><span> </span><span>8080:8080</span><span>    </span><span>--restart</span><span> </span><span>always</span><span>    </span><span>-v</span><span> </span><span>/opt/docker/nginx/conf/:/etc/nginx</span><span>    </span><span>-v</span><span> </span><span>/opt/docker/nginx/webs/:/usr/share/nginx</span><span>    </span><span>-v</span><span> </span><span>/opt/docker/nginx/logs/:/var/log/nginx</span><span>    </span><span>-v</span><span> </span><span>/opt/docker/nginx/ssl/:/ssl</span><span> </span><span>--network</span><span> </span><span>maccmsnet</span><span> </span><span>--network-alias</span><span> </span><span>nginx</span><span>   </span><span>-d</span><span> </span><span>nginx:1.22.0</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
</li>
<li>
<p>PHP 安装</p>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 下载php镜像</span></div></div><div><div><div>2</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>pull</span><span> </span><span>php:7.2-fpm</span></div></div><div><div><div>3</div></div><div><span># 初始化目录</span></div></div><div><div><div>4</div></div><div><span>$</span><span> </span><span>mkdir</span><span> </span><span>-p</span><span> </span><span>/opt/docker/php</span></div></div><div><div><div>5</div></div><div><span># 裸启容器</span></div></div><div><div><div>6</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>--name</span><span> </span><span>php</span><span> </span><span>php:7.2-fpm</span></div></div><div><div><div>7</div></div><div><span># 拷贝配置文件</span></div></div><div><div><div>8</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>cp</span><span> </span><span>php:/usr/local/etc/php</span><span> </span><span>/opt/docker/php/</span></div></div><div><div><div>9</div></div><div><span>$</span><span> </span><span>mv</span><span> </span><span>/opt/docker/php/php/</span><span> </span><span>/opt/docker/php/conf</span></div></div><div><div><div>10</div></div><div><span># 删除裸启的容器</span></div></div><div><div><div>11</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>rm</span><span> </span><span>-f</span><span> </span><span>php</span></div></div><div><div><div>12</div></div><div><span># 正式启动容器</span></div></div><div><div><div>13</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>--name</span><span> </span><span>php</span><span>    </span><span>-e</span><span> </span><span>TZ=Asia/Shanghai</span><span>    </span><span>--restart</span><span> </span><span>always</span><span>    </span><span>-p</span><span> </span><span>9000:9000</span><span>    </span><span>-v</span><span> </span><span>/opt/docker/nginx/webs:/var/www/html</span><span>    </span><span>-v</span><span> </span><span>/opt/docker/php/conf:/usr/local/etc/php</span><span> </span><span>--network</span><span> </span><span>maccmsnet</span><span> </span><span>--network-alias</span><span> </span><span>php</span><span>   </span><span>php:7.2-fpm</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span># 进入容器</span></div></div><div><div><div>16</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>exec</span><span> </span><span>-it</span><span> </span><span>php</span><span> </span><span>/bin/bash</span></div></div><div><div><div>17</div></div><div><span># 首次进入容器，先更新一下源，防止接下来下载时找不到依赖</span></div></div><div><div><div>18</div></div><div><span>$</span><span> </span><span>apt</span><span> </span><span>update</span></div></div><div><div><div>19</div></div><div><span># 这里可能会报错，提示没有更新的包，网络状态是404, 这时需要将源替换为旧版支持源</span></div></div><div><div><div>20</div></div><div><span># 备份原有源  -- 如有错误执行  start</span></div></div><div><div><div>21</div></div><div><span>$</span><span> </span><span>cp</span><span> </span><span>/etc/apt/sources.list</span><span> </span><span>/etc/apt/sources.list.bak</span></div></div><div><div><div>22</div></div><div>
</div></div><div><div><div>23</div></div><div><span># 备份原有源</span></div></div><div><div><div>24</div></div><div><span>$</span><span> </span><span>cp</span><span> </span><span>/etc/apt/sources.list</span><span> </span><span>/etc/apt/sources.list.bak</span></div></div><div><div><div>25</div></div><div>
</div></div><div><div><div>26</div></div><div><span>$</span><span> </span><span># 替换为 Debian 旧版支持源</span></div></div><div><div><div>27</div></div><div><span>$</span><span> </span><span>sed</span><span> </span><span>-i</span><span> </span><span>'s|deb.debian.org|archive.debian.org|g'</span><span> </span><span>/etc/apt/sources.list</span></div></div><div><div><div>28</div></div><div><span>$</span><span> </span><span>sed</span><span> </span><span>-i</span><span> </span><span>'s|security.debian.org|archive.debian.org|g'</span><span> </span><span>/etc/apt/sources.list</span></div></div><div><div><div>29</div></div><div><span># 重新更新</span></div></div><div><div><div>30</div></div><div><span>$</span><span> </span><span>apt</span><span> </span><span>update</span></div></div><div><div><div>31</div></div><div><span># -- 如有错误执行 end</span></div></div><div><div><div>32</div></div><div><span># PHP镜像的制作者已经将扩展都继承到镜像中了，这里执行命令解压扩展包</span></div></div><div><div><div>33</div></div><div><span>$</span><span> </span><span>docker-php-source</span><span> </span><span>extract</span></div></div><div><div><div>34</div></div><div><span># 首先安装zip扩展，先将ZIP需要的依赖库安装一下</span></div></div><div><div><div>35</div></div><div><span>$</span><span> </span><span>apt</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>--no-install-recommends</span><span> </span><span>zlib1g-dev</span><span> &amp;&amp; </span><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>--no-install-recommends</span><span> </span><span>libzip-dev</span></div></div><div><div><div>36</div></div><div><span># 安装zip扩展，这个扩展不安装无法安装程序</span></div></div><div><div><div>37</div></div><div><span>$</span><span> </span><span>docker-php-ext-install</span><span> </span><span>zip</span></div></div><div><div><div>38</div></div><div><span># 接下来安装GD扩展，先将GD需要的依赖库安装一下</span></div></div><div><div><div>39</div></div><div><span>$</span><span> </span><span>apt</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>libwebp-dev</span><span> </span><span>libjpeg-dev</span><span> </span><span>libpng-dev</span><span> </span><span>libfreetype6-dev</span></div></div><div><div><div>40</div></div><div><span># 移动到GD源码目录</span></div></div><div><div><div>41</div></div><div><span>$</span><span> </span><span>cd</span><span> </span><span>/usr/src/php/ext/gd</span></div></div><div><div><div>42</div></div><div><span># 编译GD源码</span></div></div><div><div><div>43</div></div><div><span>$</span><span> </span><span>docker-php-ext-configure</span><span> </span><span>gd</span><span> </span><span>--with-webp-dir=/usr/include/webp</span><span> </span><span>--with-jpeg-dir=/usr/include</span><span> </span><span>--with-png-dir=/usr/include</span><span> </span><span>--with-freetype-dir=/usr/include/freetype2</span></div></div><div><div><div>44</div></div><div><span># 安装GD扩展，这个扩展不安装图形验证码无法加载</span></div></div><div><div><div>45</div></div><div><span>$</span><span> </span><span>docker-php-ext-install</span><span> </span><span>gd</span></div></div><div><div><div>46</div></div><div><span># 最后安装pdo_mysql扩展，这个扩展直接安装即可，不安装该扩展将无法访问数据库</span></div></div><div><div><div>47</div></div><div><span>$</span><span> </span><span>docker-php-ext-install</span><span> </span><span>pdo_mysql</span></div></div><div><div><div>48</div></div><div><span># 安装redis依赖</span></div></div><div><div><div>49</div></div><div><span>$</span><span> </span><span>apt-get</span><span> </span><span>update</span><span> &amp;&amp; </span><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>libhiredis-dev</span></div></div><div><div><div>50</div></div><div><span># 安装 redis 扩展（自动匹配 PHP 7.2）,里面选项默认no即可</span></div></div><div><div><div>51</div></div><div><span>$</span><span> </span><span>pecl</span><span> </span><span>install</span><span> </span><span>redis-5.1.1</span></div></div><div><div><div>52</div></div><div><span># 启用扩展</span></div></div><div><div><div>53</div></div><div><span>$</span><span> </span><span>docker-php-ext-enable</span><span> </span><span>redis</span></div></div><div><div><div>54</div></div><div><span># 到此为止需要的扩展都已经安装完毕，进行一下善后工作即可</span></div></div><div><div><div>55</div></div><div><span># 收起解压好的扩展文件</span></div></div><div><div><div>56</div></div><div><span>$</span><span> </span><span>docker-php-source</span><span> </span><span>delete</span></div></div><div><div><div>57</div></div><div><span># 退出容器，并重启PHP容器</span></div></div><div><div><div>58</div></div><div><span>$</span><span> </span><span>exit</span></div></div><div><div><div>59</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>restart</span><span> </span><span>php</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
</li>
</ul>
</li>
<li>
<p>上传maccmsV10 项目文件</p>
</li>
</ol><blockquote><p>下载地址： <a href="https://github.com/magicblack/maccms10/releases" target="_blank">https://github.com/magicblack/maccms10/releases</a></p></blockquote><blockquote><p>下载完成后解压文件，并做一些处理</p></blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 作者提供的压缩文件为.zip格式，如果你的服务器没有安装对应的依赖需要安装一下</span></div></div><div><div><div>2</div></div><div><span>$</span><span> </span><span>apt</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>unzip</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 移动到目标目录（/opt/docker/nginx/webs），并解压文件到该目录</span></div></div><div><div><div>5</div></div><div><span>$</span><span> </span><span>cd</span><span> </span><span>/opt/docker/nginx/webs</span></div></div><div><div><div>6</div></div><div><span>$</span><span> </span><span>unzip</span><span> </span><span>maccms10.zip</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span># 解压后会有111开头的文件夹，不用理会直接删除就行</span></div></div><div><div><div>9</div></div><div><span>$</span><span> </span><span>rm</span><span> </span><span>-rf</span><span> </span><span>111</span><span>*</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span># PHP需要放开文件权限，这里权限直接给到777</span></div></div><div><div><div>12</div></div><div><span>$</span><span> </span><span>chmod</span><span> </span><span>-R</span><span> </span><span>777</span><span> </span><span>maccms</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span># 最终看到的目录结构应该是这个效果（maccms10.zip也可以删掉，没用了）</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>
<p>配置Nginx</p>
<blockquote><p>程序文件准备好了，而且放在了<code>/opt/docker/nginx/webs</code>目录，nginx和php都可以访问到，接下来修改一下Nginx的配置文件</p></blockquote>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 移动到Nginx配置文件目录下</span></div></div><div><div><div>2</div></div><div><span>$</span><span> </span><span>cd</span><span> </span><span>/opt/docker/nginx/conf/conf.d</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 我个人习惯每个项目都单独写个配置文件，这里创建maccms.conf，将配置写道该文件中，如下图所示</span></div></div><div><div><div>5</div></div><div><span>$</span><span> </span><span>vim</span><span> </span><span>maccms.conf</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 由于我们没有配置域名访问(那样比较麻烦)，为了不影响我们效果把Nginx自带的配置文件先关闭</span></div></div><div><div><div>8</div></div><div><span>$</span><span> </span><span>mv</span><span> </span><span>default.conf</span><span> </span><span>default.conf.bak</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 最终的目录结构是这样的</span></div></div><div><div><div>11</div></div><div><span>$</span><span> </span><span>ll</span></div></div><div><div><div>12</div></div><div><span>total</span><span> </span><span>16</span></div></div><div><div><div>13</div></div><div><span>drwxr-xr-x</span><span> </span><span>2</span><span> </span><span>root</span><span> </span><span>root</span><span> </span><span>4096</span><span> </span><span>Jul</span><span>  </span><span>9</span><span> </span><span>10:36</span><span> </span><span>./</span></div></div><div><div><div>14</div></div><div><span>drwxr-xr-x</span><span> </span><span>3</span><span> </span><span>root</span><span> </span><span>root</span><span> </span><span>4096</span><span> </span><span>Oct</span><span>  </span><span>5</span><span>  </span><span>2022</span><span> </span><span>../</span></div></div><div><div><div>15</div></div><div><span>-rw-r--r--</span><span> </span><span>1</span><span> </span><span>root</span><span> </span><span>root</span><span> </span><span>1093</span><span> </span><span>Jul</span><span>  </span><span>9</span><span> </span><span>09:56</span><span> </span><span>default.conf.bak</span></div></div><div><div><div>16</div></div><div><span>-rw-r--r--</span><span> </span><span>1</span><span> </span><span>root</span><span> </span><span>root</span><span>  </span><span>746</span><span> </span><span>Jul</span><span>  </span><span>9</span><span> </span><span>10:36</span><span> </span><span>maccms.conf</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># maccms.conf</span></div></div><div><div><div>2</div></div><div><span>server</span><span> </span><span>{</span></div></div><div><div><div>3</div></div><div><span>    </span><span>listen</span><span>       </span><span>80</span><span>;</span></div></div><div><div><div>4</div></div><div><span>    </span><span>server_name</span><span>  </span><span>127.0.0.1</span><span>;</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>    </span><span>location</span><span> </span><span>~</span><span> </span><span>.php</span><span>$ </span><span>{</span></div></div><div><div><div>7</div></div><div><span>        </span><span>fastcgi_pass</span><span>    </span><span>php:9000</span><span>;</span></div></div><div><div><div>8</div></div><div><span>        </span><span>fastcgi_index</span><span>   </span><span>index.php</span><span>;</span></div></div><div><div><div>9</div></div><div><span>        </span><span>fastcgi_split_path_info</span><span>   </span><span>^</span><span>(</span><span>.</span><span>+.php</span><span>)(</span><span>/.+</span><span>)$;</span></div></div><div><div><div>10</div></div><div><span>        </span><span>fastcgi_param</span><span>   </span><span>SCRIPT_FILENAME</span><span>  </span><span>/var/www/html/maccms/</span><span>$fastcgi_script_name</span><span>;</span></div></div><div><div><div>11</div></div><div><span>        </span><span>include</span><span>         </span><span>fastcgi_params</span><span>;</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>    </span><span>location</span><span> </span><span>/</span><span> </span><span>{</span></div></div><div><div><div>15</div></div><div><span>        </span><span>if</span><span> (!</span><span>-e</span><span> </span><span>$request_filename</span><span>) {</span></div></div><div><div><div>16</div></div><div><span>            </span><span>rewrite</span><span> </span><span>^/index.php</span><span>(</span><span>.</span><span>*</span><span>)$ </span><span>/index.php?s=</span><span><span>$1</span><span> </span></span><span>last</span><span>;</span></div></div><div><div><div>17</div></div><div><span>            </span><span>rewrite</span><span> </span><span>^/admin.php</span><span>(</span><span>.</span><span>*</span><span>)$ </span><span>/admin.php?s=</span><span><span>$1</span><span> </span></span><span>last</span><span>;</span></div></div><div><div><div>18</div></div><div><span>            </span><span>rewrite</span><span> </span><span>^/api.php</span><span>(</span><span>.</span><span>*</span><span>)$ </span><span>/api.php?s=</span><span><span>$1</span><span> </span></span><span>last</span><span>;</span></div></div><div><div><div>19</div></div><div><span>            </span><span>rewrite</span><span> </span><span>^</span><span>(</span><span>.</span><span>*</span><span>)$ </span><span>/index.php?s=</span><span><span>$1</span><span> </span></span><span>last</span><span>;</span></div></div><div><div><div>20</div></div><div><span>            </span><span>break</span><span>;</span></div></div><div><div><div>21</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>22</div></div><div><span>        </span><span>root</span><span>   </span><span>/usr/share/nginx</span><span>;</span></div></div><div><div><div>23</div></div><div><span>        </span><span>index</span><span>  </span><span>index.html</span><span> </span><span>index.htm</span><span> </span><span>index.php</span><span>;</span></div></div><div><div><div>24</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>25</div></div><div>
</div></div><div><div><div>26</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
</li>
<li>
<p>根据向导安装，安装完成后修改<code>admin.php</code>文件名，同时修改nginx配置</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 移动到Maccms程序目录</span></div></div><div><div><div>2</div></div><div><span>$</span><span> </span><span>cd</span><span> </span><span>/opt/docker/nginx/webs/maccms</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 给admin.php重命名为yyds.php</span></div></div><div><div><div>5</div></div><div><span>$</span><span> </span><span>mv</span><span> </span><span>admin.php</span><span> </span><span>yyds.php</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 编辑Nginx配置文件，将配置文件中的admin.php修改为刚刚设置的yyds.php</span></div></div><div><div><div>8</div></div><div><span># 一共有两处需要修改，两处都在同一行，我文字说明一下这里就不截图了</span></div></div><div><div><div>9</div></div><div><span>$</span><span> </span><span>vim</span><span> </span><span>/opt/docker/nginx/conf/conf.d/maccms.conf</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span># 重启Nginx容器使配置生效</span></div></div><div><div><div>12</div></div><div><span>$</span><span> </span><span>docker</span><span> </span><span>restart</span><span> </span><span>nginx</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>配置视频分类</p>
<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>truncate</span><span> </span><span>table</span><span> </span><span>`mac_type`</span><span>;</span></div></div><div><div><div>2</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'1'</span><span>, </span><span>'电影'</span><span>, </span><span>'dianying'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'0'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'电影,电影大全,电影天堂,最新电影,好看的电影,电影排行榜'</span><span>, </span><span>'为您提供更新电影、好看的电影排行榜及电影迅雷下载，免费在线观看伦理电影、动作片、喜剧片、爱情片、搞笑片等全新电影。'</span><span>, </span><span>'电影'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\\u559c\\u5267,\\u7231\\u60c5,\\u6050\\u6016,\\u52a8\\u4f5c,\\u79d1\\u5e7b,\\u5267\\u60c5,\\u6218\\u4e89,\\u8b66\\u532a,\\u72af\\u7f6a,\\u52a8\\u753b,\\u5947\\u5e7b,\\u6b66\\u4fa0,\\u5192\\u9669,\\u67aa\\u6218,\\u6050\\u6016,\\u60ac\\u7591,\\u60ca\\u609a,\\u7ecf\\u5178,\\u9752\\u6625,\\u6587\\u827a,\\u5fae\\u7535\\u5f71,\\u53e4\\u88c5,\\u5386\\u53f2,\\u8fd0\\u52a8,\\u519c\\u6751,\\u513f\\u7ae5,\\u7f51\\u7edc\\u7535\\u5f71\",\"area\":\"\\u5927\\u9646,\\u9999\\u6e2f,\\u53f0\\u6e7e,\\u7f8e\\u56fd,\\u6cd5\\u56fd,\\u82f1\\u56fd,\\u65e5\\u672c,\\u97e9\\u56fd,\\u5fb7\\u56fd,\\u6cf0\\u56fd,\\u5370\\u5ea6,\\u610f\\u5927\\u5229,\\u897f\\u73ed\\u7259,\\u52a0\\u62ff\\u5927,\\u5176\\u4ed6\",\"lang\":\"\\u56fd\\u8bed,\\u82f1\\u8bed,\\u7ca4\\u8bed,\\u95fd\\u5357\\u8bed,\\u97e9\\u8bed,\\u65e5\\u8bed,\\u6cd5\\u8bed,\\u5fb7\\u8bed,\\u5176\\u5b83\",\"year\":\"2018,2017,2016,2015,2014,2013,2012,2011,2010\",\"star\":\"\\u738b\\u5b9d\\u5f3a,\\u9ec4\\u6e24,\\u5468\\u8fc5,\\u5468\\u51ac\\u96e8,\\u8303\\u51b0\\u51b0,\\u9648\\u5b66\\u51ac,\\u9648\\u4f1f\\u9706,\\u90ed\\u91c7\\u6d01,\\u9093\\u8d85,\\u6210\\u9f99,\\u845b\\u4f18,\\u6797\\u6b63\\u82f1,\\u5f20\\u5bb6\\u8f89,\\u6881\\u671d\\u4f1f,\\u5f90\\u5ce5,\\u90d1\\u607a,\\u5434\\u5f66\\u7956,\\u5218\\u5fb7\\u534e,\\u5468\\u661f\\u9a70,\\u6797\\u9752\\u971e,\\u5468\\u6da6\\u53d1,\\u674e\\u8fde\\u6770,\\u7504\\u5b50\\u4e39,\\u53e4\\u5929\\u4e50,\\u6d2a\\u91d1\\u5b9d,\\u59da\\u6668,\\u502a\\u59ae,\\u9ec4\\u6653\\u660e,\\u5f6d\\u4e8e\\u664f,\\u6c64\\u552f,\\u9648\\u5c0f\\u6625\",\"director\":\"\\u51af\\u5c0f\\u521a,\\u5f20\\u827a\\u8c0b,\\u5434\\u5b87\\u68ee,\\u9648\\u51ef\\u6b4c,\\u5f90\\u514b,\\u738b\\u5bb6\\u536b,\\u59dc\\u6587,\\u5468\\u661f\\u9a70,\\u674e\\u5b89\",\"state\":\"\\u6b63\\u7247,\\u9884\\u544a\\u7247,\\u82b1\\u7d6e\",\"version\":\"\\u9ad8\\u6e05\\u7248,\\u5267\\u573a\\u7248,\\u62a2\\u5148\\u7248,OVA,TV,\\u5f71\\u9662\\u7248\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>3</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'2'</span><span>, </span><span>'连续剧'</span><span>, </span><span>'lianxuju'</span><span>, </span><span>'2'</span><span>, </span><span>'1'</span><span>, </span><span>'0'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'电视剧,最新电视剧,好看的电视剧,热播电视剧,电视剧在线观看'</span><span>, </span><span>'为您提供2018新电视剧排行榜，韩国电视剧、泰国电视剧、香港TVB全新电视剧排行榜、好看的电视剧等热播电视剧排行榜，并提供免费高清电视剧下载及在线观看。'</span><span>, </span><span>'电视剧'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\\u53e4\\u88c5,\\u6218\\u4e89,\\u9752\\u6625\\u5076\\u50cf,\\u559c\\u5267,\\u5bb6\\u5ead,\\u72af\\u7f6a,\\u52a8\\u4f5c,\\u5947\\u5e7b,\\u5267\\u60c5,\\u5386\\u53f2,\\u7ecf\\u5178,\\u4e61\\u6751,\\u60c5\\u666f,\\u5546\\u6218,\\u7f51\\u5267,\\u5176\\u4ed6\",\"area\":\"\\u5185\\u5730,\\u97e9\\u56fd,\\u9999\\u6e2f,\\u53f0\\u6e7e,\\u65e5\\u672c,\\u7f8e\\u56fd,\\u6cf0\\u56fd,\\u82f1\\u56fd,\\u65b0\\u52a0\\u5761,\\u5176\\u4ed6\",\"lang\":\"\\u56fd\\u8bed,\\u82f1\\u8bed,\\u7ca4\\u8bed,\\u95fd\\u5357\\u8bed,\\u97e9\\u8bed,\\u65e5\\u8bed,\\u5176\\u5b83\",\"year\":\"2018,2017,2016,2015,2014,2013,2012,2011,2010,2009,2008,2006,2005,2004\",\"star\":\"\\u738b\\u5b9d\\u5f3a,\\u80e1\\u6b4c,\\u970d\\u5efa\\u534e,\\u8d75\\u4e3d\\u9896,\\u5218\\u6d9b,\\u5218\\u8bd7\\u8bd7,\\u9648\\u4f1f\\u9706,\\u5434\\u5947\\u9686,\\u9646\\u6bc5,\\u5510\\u5ae3,\\u5173\\u6653\\u5f64,\\u5b59\\u4fea,\\u674e\\u6613\\u5cf0,\\u5f20\\u7ff0,\\u674e\\u6668,\\u8303\\u51b0\\u51b0,\\u6797\\u5fc3\\u5982,\\u6587\\u7ae0,\\u9a6c\\u4f0a\\u740d,\\u4f5f\\u5927\\u4e3a,\\u5b59\\u7ea2\\u96f7,\\u9648\\u5efa\\u658c,\\u674e\\u5c0f\\u7490\",\"director\":\"\\u5f20\\u7eaa\\u4e2d,\\u674e\\u5c11\\u7ea2,\\u5218\\u6c5f,\\u5b54\\u7b19,\\u5f20\\u9ece,\\u5eb7\\u6d2a\\u96f7,\\u9ad8\\u5e0c\\u5e0c,\\u80e1\\u73ab,\\u8d75\\u5b9d\\u521a,\\u90d1\\u6653\\u9f99\",\"state\":\"\\u6b63\\u7247,\\u9884\\u544a\\u7247,\\u82b1\\u7d6e\",\"version\":\"\\u9ad8\\u6e05\\u7248,\\u5267\\u573a\\u7248,\\u62a2\\u5148\\u7248,OVA,TV,\\u5f71\\u9662\\u7248\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>4</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'3'</span><span>, </span><span>'综艺'</span><span>, </span><span>'zongyi'</span><span>, </span><span>'3'</span><span>, </span><span>'1'</span><span>, </span><span>'0'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'综艺,综艺节目,最新综艺节目,综艺节目排行榜'</span><span>, </span><span>'为您提供新综艺节目、好看的综艺节目排行榜，免费高清在线观看选秀、情感、访谈、搞笑、真人秀、脱口秀等热门综艺节目。'</span><span>, </span><span>'综艺'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\\u9009\\u79c0,\\u60c5\\u611f,\\u8bbf\\u8c08,\\u64ad\\u62a5,\\u65c5\\u6e38,\\u97f3\\u4e50,\\u7f8e\\u98df,\\u7eaa\\u5b9e,\\u66f2\\u827a,\\u751f\\u6d3b,\\u6e38\\u620f\\u4e92\\u52a8,\\u8d22\\u7ecf,\\u6c42\\u804c\",\"area\":\"\\u5185\\u5730,\\u6e2f\\u53f0,\\u65e5\\u97e9,\\u6b27\\u7f8e\",\"lang\":\"\\u56fd\\u8bed,\\u82f1\\u8bed,\\u7ca4\\u8bed,\\u95fd\\u5357\\u8bed,\\u97e9\\u8bed,\\u65e5\\u8bed,\\u5176\\u5b83\",\"year\":\"2018,2017,2016,2015,2014,2013,2012,2011,2010,2009,2008,2007,2006,2005,2004\",\"star\":\"\\u4f55\\u7085,\\u6c6a\\u6db5,\\u8c22\\u5a1c,\\u5468\\u7acb\\u6ce2,\\u9648\\u9c81\\u8c6b,\\u5b5f\\u975e,\\u674e\\u9759,\\u6731\\u519b,\\u6731\\u4e39,\\u534e\\u5c11,\\u90ed\\u5fb7\\u7eb2,\\u6768\\u6f9c\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>5</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'4'</span><span>, </span><span>'动漫'</span><span>, </span><span>'dongman'</span><span>, </span><span>'4'</span><span>, </span><span>'1'</span><span>, </span><span>'0'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'动漫,动漫大全,最新动漫,好看的动漫,日本动漫,动漫排行榜'</span><span>, </span><span>'为您提供新动漫、好看的动漫排行榜，免费高清在线观看热血动漫、卡通动漫、新番动漫、百合动漫、搞笑动漫、国产动漫、动漫电影等热门动漫。'</span><span>, </span><span>'动画片'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\\u60c5\\u611f,\\u79d1\\u5e7b,\\u70ed\\u8840,\\u63a8\\u7406,\\u641e\\u7b11,\\u5192\\u9669,\\u841d\\u8389,\\u6821\\u56ed,\\u52a8\\u4f5c,\\u673a\\u6218,\\u8fd0\\u52a8,\\u6218\\u4e89,\\u5c11\\u5e74,\\u5c11\\u5973,\\u793e\\u4f1a,\\u539f\\u521b,\\u4eb2\\u5b50,\\u76ca\\u667a,\\u52b1\\u5fd7,\\u5176\\u4ed6\",\"area\":\"\\u56fd\\u4ea7,\\u65e5\\u672c,\\u6b27\\u7f8e,\\u5176\\u4ed6\",\"lang\":\"\\u56fd\\u8bed,\\u82f1\\u8bed,\\u7ca4\\u8bed,\\u95fd\\u5357\\u8bed,\\u97e9\\u8bed,\\u65e5\\u8bed,\\u5176\\u5b83\",\"year\":\"2018,2017,2016,2015,2014,2013,2012,2011,2010,2009,2008,2007,2006,2005,2004\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"TV\\u7248,\\u7535\\u5f71\\u7248,OVA\\u7248,\\u771f\\u4eba\\u7248\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>6</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'5'</span><span>, </span><span>'资讯'</span><span>, </span><span>'zixun'</span><span>, </span><span>'5'</span><span>, </span><span>'2'</span><span>, </span><span>'0'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>''</span><span>, </span><span>''</span><span>, </span><span>'最新影视资讯,电影资讯,娱乐资讯'</span><span>, </span><span>'本站提供最新电影,电视剧,综艺,动漫的资讯信息,一览无遗'</span><span>, </span><span>'最新资讯-推荐资讯'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>7</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'7'</span><span>, </span><span>'喜剧片'</span><span>, </span><span>'xijupian'</span><span>, </span><span>'2'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的喜剧片,最新喜剧片,经典喜剧片,国语喜剧片电影'</span><span>, </span><span>'2021最新喜剧片，好看的喜剧片大全和排行榜推荐，免费喜剧片在线观看和视频在线播放是由本网站整理和收录，欢迎喜剧片爱好者来到这里在线观看喜剧片'</span><span>, </span><span>'好看的喜剧片-最新喜剧片-经典喜剧片-最新喜剧片推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>8</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'6'</span><span>, </span><span>'动作片'</span><span>, </span><span>'dongzuopian'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的动作片,最新动作片,经典动作片,国语动作片电影'</span><span>, </span><span>'2021最新动作片，好看的动作片大全和排行榜推荐，免费动作片在线观看和视频在线播放是由本网站整理和收录，欢迎动作片爱好者来到这里在线观看动作片'</span><span>, </span><span>'好看的动作片-最新动作片-经典动作片-最新动作片推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>9</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'8'</span><span>, </span><span>'爱情片'</span><span>, </span><span>'aiqingpian'</span><span>, </span><span>'3'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的爱情片,最新爱情片,经典爱情片,国语爱情片电影'</span><span>, </span><span>'2021最新爱情片，好看的爱情片大全和排行榜推荐，免费爱情片在线观看和视频在线播放是由本网站整理和收录，欢迎爱情片爱好者来到这里在线观看爱情片'</span><span>, </span><span>'好看的爱情片-最新爱情片-经典爱情片-最新爱情片推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>10</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'9'</span><span>, </span><span>'科幻片'</span><span>, </span><span>'kehuanpian'</span><span>, </span><span>'4'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的科幻片,最新科幻片,经典科幻片,国语科幻片电影'</span><span>, </span><span>'2021最新科幻片，好看的科幻片大全和排行榜推荐，免费科幻片在线观看和视频在线播放是由本网站整理和收录，欢迎科幻片爱好者来到这里在线观看科幻片'</span><span>, </span><span>'好看的科幻片-最新科幻片-经典科幻片-最新科幻片推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>11</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'10'</span><span>, </span><span>'恐怖片'</span><span>, </span><span>'kongbupian'</span><span>, </span><span>'5'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的恐怖片,最新恐怖片,经典恐怖片,国语恐怖片电影'</span><span>, </span><span>'2021最新恐怖片，好看的恐怖片大全和排行榜推荐，免费恐怖片在线观看和视频在线播放是由本网站整理和收录，欢迎恐怖片爱好者来到这里在线观看恐怖片'</span><span>, </span><span>'好看的恐怖片-最新恐怖片-经典恐怖片-最新恐怖片推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>12</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'11'</span><span>, </span><span>'剧情片'</span><span>, </span><span>'juqingpian'</span><span>, </span><span>'6'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的剧情片,最新剧情片,经典剧情片,国语剧情片电影'</span><span>, </span><span>'2021最新剧情片，好看的剧情片大全和排行榜推荐，免费剧情片在线观看和视频在线播放是由本网站整理和收录，欢迎剧情片爱好者来到这里在线观看剧情片'</span><span>, </span><span>'好看的剧情片-最新剧情片-经典剧情片-最新剧情片推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>13</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'12'</span><span>, </span><span>'战争片'</span><span>, </span><span>'zhanzhengpian'</span><span>, </span><span>'7'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的战争片,最新战争片,经典战争片,国语战争片电影'</span><span>, </span><span>'2021最新战争片，好看的战争片大全和排行榜推荐，免费战争片在线观看和视频在线播放是由本网站整理和收录，欢迎战争片爱好者来到这里在线观看战争片'</span><span>, </span><span>'好看的战争片-最新战争片-经典战争片-最新战争片推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>14</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'13'</span><span>, </span><span>'国产剧'</span><span>, </span><span>'guochanju'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'2'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的国产剧,最新国产剧,经典国产剧,国语国产剧电影'</span><span>, </span><span>'2021最新国产剧，好看的国产剧大全和排行榜推荐，免费国产剧在线观看和视频在线播放是由本网站整理和收录，欢迎国产剧爱好者来到这里在线观看国产剧'</span><span>, </span><span>'好看的国产剧-最新国产剧-经典国产剧-最新国产剧推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>15</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'14'</span><span>, </span><span>'港台剧'</span><span>, </span><span>'gangtaiju'</span><span>, </span><span>'2'</span><span>, </span><span>'1'</span><span>, </span><span>'2'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的港台剧,最新港台剧,经典港台剧,国语港台剧电影'</span><span>, </span><span>'2021最新港台剧，好看的港台剧大全和排行榜推荐，免费港台剧在线观看和视频在线播放是由本网站整理和收录，欢迎港台剧爱好者来到这里在线观看港台剧'</span><span>, </span><span>'好看的港台剧-最新港台剧-经典港台剧-最新港台剧推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>16</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'15'</span><span>, </span><span>'日韩剧'</span><span>, </span><span>'rihanju'</span><span>, </span><span>'3'</span><span>, </span><span>'1'</span><span>, </span><span>'2'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的日韩剧,最新日韩剧,经典日韩剧,国语日韩剧电影'</span><span>, </span><span>'2021最新日韩剧，好看的日韩剧大全和排行榜推荐，免费日韩剧在线观看和视频在线播放是由本网站整理和收录，欢迎日韩剧爱好者来到这里在线观看日韩剧'</span><span>, </span><span>'好看的日韩剧-最新日韩剧-经典日韩剧-最新日韩剧推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>17</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'16'</span><span>, </span><span>'欧美剧'</span><span>, </span><span>'oumeiju'</span><span>, </span><span>'4'</span><span>, </span><span>'1'</span><span>, </span><span>'2'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的欧美剧,最新欧美剧,经典欧美剧,国语欧美剧电影'</span><span>, </span><span>'2021最新欧美剧，好看的欧美剧大全和排行榜推荐，免费欧美剧在线观看和视频在线播放是由本网站整理和收录，欢迎欧美剧爱好者来到这里在线观看欧美剧'</span><span>, </span><span>'好看的欧美剧-最新欧美剧-经典欧美剧-最新欧美剧推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>18</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'17'</span><span>, </span><span>'公告'</span><span>, </span><span>'gonggao'</span><span>, </span><span>'1'</span><span>, </span><span>'2'</span><span>, </span><span>'5'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>''</span><span>, </span><span>''</span><span>, </span><span>'最新公告-最新公告推荐'</span><span>, </span><span>'2021最新公告，公布本站最新发展动态'</span><span>, </span><span>'最新公告-最新公告推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>19</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'18'</span><span>, </span><span>'头条'</span><span>, </span><span>'toutiao'</span><span>, </span><span>'2'</span><span>, </span><span>'2'</span><span>, </span><span>'5'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>''</span><span>, </span><span>''</span><span>, </span><span>''</span><span>, </span><span>''</span><span>, </span><span>''</span><span>, </span><span>''</span><span>, </span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>20</div></div><div>
</div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'19'</span><span>, </span><span>'冒险片'</span><span>, </span><span>'maoxianpian'</span><span>, </span><span>'8'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的冒险片'</span><span>, </span><span>''</span><span>, </span><span>''</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>23</div></div><div>
</div></div><div><div><div>24</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'20'</span><span>, </span><span>'动画片'</span><span>, </span><span>'maoxianpian'</span><span>, </span><span>'9'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的动画片'</span><span>, </span><span>''</span><span>, </span><span>''</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>25</div></div><div>
</div></div><div><div><div>26</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'21'</span><span>, </span><span>'其他'</span><span>, </span><span>'qita'</span><span>, </span><span>'10'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的动画片'</span><span>, </span><span>''</span><span>, </span><span>''</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>27</div></div><div>
</div></div><div><div><div>28</div></div><div>
</div></div><div><div><div>29</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'22'</span><span>, </span><span>'其他'</span><span>, </span><span>'qita'</span><span>, </span><span>'5'</span><span>, </span><span>'1'</span><span>, </span><span>'2'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的国产剧,最新国产剧,经典国产剧,国语国产剧电影'</span><span>, </span><span>'2021最新国产剧，好看的国产剧大全和排行榜推荐，免费国产剧在线观看和视频在线播放是由本网站整理和收录，欢迎国产剧爱好者来到这里在线观看国产剧'</span><span>, </span><span>'好看的国产剧-最新国产剧-经典国产剧-最新国产剧推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>30</div></div><div>
</div></div><div><div><div>31</div></div><div>
</div></div><div><div><div>32</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'23'</span><span>, </span><span>'国产综艺'</span><span>, </span><span>'guochanzongyi'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'3'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的国产剧,最新国产剧,经典国产剧,国语国产剧电影'</span><span>, </span><span>'2021最新国产剧，好看的国产剧大全和排行榜推荐，免费国产剧在线观看和视频在线播放是由本网站整理和收录，欢迎国产剧爱好者来到这里在线观看国产剧'</span><span>, </span><span>'好看的国产剧-最新国产剧-经典国产剧-最新国产剧推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>33</div></div><div>
</div></div><div><div><div>34</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'24'</span><span>, </span><span>'日韩综艺'</span><span>, </span><span>'rihanzongyi'</span><span>, </span><span>'2'</span><span>, </span><span>'1'</span><span>, </span><span>'3'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的国产剧,最新国产剧,经典国产剧,国语国产剧电影'</span><span>, </span><span>'2021最新国产剧，好看的国产剧大全和排行榜推荐，免费国产剧在线观看和视频在线播放是由本网站整理和收录，欢迎国产剧爱好者来到这里在线观看国产剧'</span><span>, </span><span>'好看的国产剧-最新国产剧-经典国产剧-最新国产剧推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>35</div></div><div>
</div></div><div><div><div>36</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'25'</span><span>, </span><span>'欧美综艺'</span><span>, </span><span>'oumeizongyi'</span><span>, </span><span>'3'</span><span>, </span><span>'1'</span><span>, </span><span>'3'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的国产剧,最新国产剧,经典国产剧,国语国产剧电影'</span><span>, </span><span>'2021最新国产剧，好看的国产剧大全和排行榜推荐，免费国产剧在线观看和视频在线播放是由本网站整理和收录，欢迎国产剧爱好者来到这里在线观看国产剧'</span><span>, </span><span>'好看的国产剧-最新国产剧-经典国产剧-最新国产剧推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>37</div></div><div>
</div></div><div><div><div>38</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'26'</span><span>, </span><span>'其他'</span><span>, </span><span>'qita'</span><span>, </span><span>'4'</span><span>, </span><span>'1'</span><span>, </span><span>'3'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的国产剧,最新国产剧,经典国产剧,国语国产剧电影'</span><span>, </span><span>'2021最新国产剧，好看的国产剧大全和排行榜推荐，免费国产剧在线观看和视频在线播放是由本网站整理和收录，欢迎国产剧爱好者来到这里在线观看国产剧'</span><span>, </span><span>'好看的国产剧-最新国产剧-经典国产剧-最新国产剧推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>39</div></div><div>
</div></div><div><div><div>40</div></div><div>
</div></div><div><div><div>41</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'27'</span><span>, </span><span>'国产动漫'</span><span>, </span><span>'guochandongman'</span><span>, </span><span>'1'</span><span>, </span><span>'1'</span><span>, </span><span>'4'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的国产剧,最新国产剧,经典国产剧,国语国产剧电影'</span><span>, </span><span>'2021最新国产剧，好看的国产剧大全和排行榜推荐，免费国产剧在线观看和视频在线播放是由本网站整理和收录，欢迎国产剧爱好者来到这里在线观看国产剧'</span><span>, </span><span>'好看的国产剧-最新国产剧-经典国产剧-最新国产剧推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>42</div></div><div>
</div></div><div><div><div>43</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'28'</span><span>, </span><span>'日韩动漫'</span><span>, </span><span>'rihandongman'</span><span>, </span><span>'2'</span><span>, </span><span>'1'</span><span>, </span><span>'4'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的国产剧,最新国产剧,经典国产剧,国语国产剧电影'</span><span>, </span><span>'2021最新国产剧，好看的国产剧大全和排行榜推荐，免费国产剧在线观看和视频在线播放是由本网站整理和收录，欢迎国产剧爱好者来到这里在线观看国产剧'</span><span>, </span><span>'好看的国产剧-最新国产剧-经典国产剧-最新国产剧推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>44</div></div><div>
</div></div><div><div><div>45</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'29'</span><span>, </span><span>'欧美动漫'</span><span>, </span><span>'oumeidongman'</span><span>, </span><span>'3'</span><span>, </span><span>'1'</span><span>, </span><span>'4'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的国产剧,最新国产剧,经典国产剧,国语国产剧电影'</span><span>, </span><span>'2021最新国产剧，好看的国产剧大全和排行榜推荐，免费国产剧在线观看和视频在线播放是由本网站整理和收录，欢迎国产剧爱好者来到这里在线观看国产剧'</span><span>, </span><span>'好看的国产剧-最新国产剧-经典国产剧-最新国产剧推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>46</div></div><div>
</div></div><div><div><div>47</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'30'</span><span>, </span><span>'其他'</span><span>, </span><span>'qita'</span><span>, </span><span>'4'</span><span>, </span><span>'1'</span><span>, </span><span>'4'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>'play.html'</span><span>, </span><span>'down.html'</span><span>, </span><span>'好看的国产剧,最新国产剧,经典国产剧,国语国产剧电影'</span><span>, </span><span>'2021最新国产剧，好看的国产剧大全和排行榜推荐，免费国产剧在线观看和视频在线播放是由本网站整理和收录，欢迎国产剧爱好者来到这里在线观看国产剧'</span><span>, </span><span>'好看的国产剧-最新国产剧-经典国产剧-最新国产剧推荐'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div><div><div><div>48</div></div><div>
</div></div><div><div><div>49</div></div><div>
</div></div><div><div><div>50</div></div><div><span>INSERT INTO</span><span> </span><span>`mac_type`</span><span> </span><span>VALUES</span><span> (</span><span>'31'</span><span>, </span><span>'短剧'</span><span>, </span><span>'duanju'</span><span>, </span><span>'6'</span><span>, </span><span>'1'</span><span>, </span><span>'0'</span><span>, </span><span>'1'</span><span>, </span><span>'type.html'</span><span>, </span><span>'show.html'</span><span>, </span><span>'detail.html'</span><span>, </span><span>''</span><span>, </span><span>''</span><span>, </span><span>'最新影视资讯,电影资讯,娱乐资讯'</span><span>, </span><span>'本站提供最新电影,电视剧,综艺,动漫的资讯信息,一览无遗'</span><span>, </span><span>'最新资讯-推荐资讯'</span><span>, </span><span>''</span><span>, </span><span>'{\"class\":\"\",\"area\":\"\",\"lang\":\"\",\"year\":\"\",\"star\":\"\",\"director\":\"\",\"state\":\"\",\"version\":\"\"}'</span><span>,</span><span>''</span><span>,</span><span>''</span><span>,</span><span>''</span><span>);</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
</li>
<li>
<p>最后就可以开始采集了</p>
</li>
<li>
<p>其他</p>
</li>
</ol><p><a href="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/01/mengyaCJPro10.7.3.zip" target="_blank">mengya采集插件下载</a>
<a href="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/01/EZ%E8%81%9A%E5%90%88%E8%B5%84%E6%BA%90%E9%87%87%E9%9B%86%E6%8F%92%E4%BB%B6v10.rar" target="_blank">EZ聚合资源采集插件v10</a>
<a href="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2025/01/uniappCMS.rar" target="_blank">uniappCMS</a></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/9791b8ea/</id>
      <title type="text">【MACCMS】2023年最新可采集CMS视频资源站网址合集</title>
      <published>2024-07-21T08:31:13.000Z</published>
      <updated>2024-07-21T08:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/9791b8ea/"/>
      <summary type="text"></summary>
      <content type="html"><![CDATA[本文已加密保护，请访问网站查看。]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/4fd5a719/</id>
      <title type="text">【工具】GitHub访问设置</title>
      <published>2024-07-19T20:31:13.000Z</published>
      <updated>2024-07-19T20:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/4fd5a719/"/>
      <summary type="text">本文详细介绍了提高GitHub访问速度和稳定性的方法，主要包括修改hosts文件和更换DNS服务器。通过在线DNS解析工具获取GitHub及其子服务的IP地址，并将其添加至hosts文件；推荐了几款高效稳定的DNS服务，如百度DNS、阿里DNS等，帮助用户优化网络环境，确保流畅访问GitHub。</summary>
      <content type="html"><![CDATA[<p><strong>访问GitHub的速度和稳定性可以通过修改hosts文件来提高。‌</strong></p>
<p>首先，‌获取github.com的IP地址是关键的一步。‌</p>
<p>你可以通过在线DNS解析网站，‌如<a href="http://www.ip33.com/dns.html" target="_blank">ip33</a>，‌输入<code>github.com</code>域名，‌获取A记录的IP地址。‌然后将这个IP地址赋值到<code>hosts</code>文件（‌文件路径为<code>C:\Windows\System32\drivers\etc</code>）‌，‌配置好后点击保存即可。‌如果配置后提示保存不了，‌可以尝试将hosts文件copy到桌面重新配置后保存，‌然后再覆盖原路径的文件。‌</p>
<p>此外，‌还有一些特定的IP地址可以帮助加速访问GitHub的特定服务，‌</p>

<p>例如 <a href="avatars.githubusercontent.com">avatars.githubusercontent.com</a>、‌<a href="codeload.github.com">codeload.github.com</a>等，‌这些服务通常用于加载图片、‌代码等资源。‌通过将这些服务与特定的IP地址关联，‌可以进一步提高访问速度和稳定性。‌</p>
<p>需要注意的是，‌这种方法虽然可以提高访问速度和稳定性，‌但并不保证能够完全解决所有访问问题，‌因为GitHub的服务可能会在不同的时间和地点使用不同的IP地址。‌因此，‌如果遇到访问问题，‌可能需要重新通过DNS解析获取最新的可用IP地址。‌</p>
<p>最后，‌还有一些工具和服务提供更新的hosts文件，‌这些文件包含了最新的GitHub域名和IP地址映射，‌使用这些工具和服务可以简化手动更新hosts文件的步骤，‌同时也能保证使用的是最新的、‌有效的IP地址</p>
<p>如果设置host后依旧不能访问，可以尝试修改dns来试试~</p>

<table><thead><tr><th>DNS</th><th>IP地址</th><th>官网</th><th>备注</th></tr></thead><tbody><tr><td>百度DNS</td><td>180.76.76.76</td><td><a href="http://dudns.baidu.com/" target="_blank">http://dudns.baidu.com/</a></td><td>-</td></tr><tr><td>阿里DNS</td><td>223.5.5.5 223.6.6.6</td><td><a href="http://www.alidns.com/" target="_blank">http://www.alidns.com/</a></td><td>-</td></tr><tr><td>DNSPod</td><td>119.29.29.29</td><td><a href="https://www.dnspod.cn/Products/Public.DNS" target="_blank">https://www.dnspod.cn/Products/Public.DNS</a></td><td>腾讯旗下</td></tr><tr><td>114 DNS</td><td>114.114.114.114 114.114.115.115</td><td><a href="http://www.114dns.com/" target="_blank">http://www.114dns.com/</a></td><td>电信合作商</td></tr><tr><td>Google DNS</td><td>8.8.8.8  8.8.4.4</td><td><a href="https://developers.google.com/speed/public-dns/" target="_blank">https://developers.google.com/speed/public-dns/</a></td><td>纯净无污染，注意墙</td></tr><tr><td>SDNS</td><td>1.2.4.8 210.2.4.8</td><td><a href="http://www.sdns.cn/" target="_blank">http://www.sdns.cn/</a></td><td>中国互联网络信息中心提供</td></tr><tr><td>OpenDNS</td><td>208.67.220.220 208.67.222.222</td><td><a href="http://www.opendns.com/" target="_blank">http://www.opendns.com/</a></td><td>资深、专业的公众DNS</td></tr></tbody></table>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/26185413/</id>
      <title type="text">【Linux】DotNet运行命令</title>
      <published>2024-07-01T08:31:13.000Z</published>
      <updated>2024-07-01T08:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/26185413/"/>
      <summary type="text">本文档详细介绍了在Linux环境下运行DotNet应用程序的方法，包括设置系统级环境变量、编写启动脚本、批量启动脚本以及注册系统服务。首先，文档说明了如何通设置DotNet的环境变量，并确保所有用户都能访问。接着，提供了详细的启动脚本，用于启动、停止、重启和检查应用程序的状态。</summary>
      <content type="html"><![CDATA[<section><h2>设置系统级环境变量<a href="#设置系统级环境变量"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># /etc/profile.d/{文件名.sh} 新建并打开配置文件</span></div></div><div><div><div>2</div></div><div><span>vi</span><span> </span><span>/etc/profile.d/dotnet.sh</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 文件末尾加变量定义</span></div></div><div><div><div>5</div></div><div><span># 此处我的dotnet文件在 这个位置  /home/sys_wh/dotnet</span></div></div><div><div><div>6</div></div><div><span>export</span><span> </span><span>DOTNET_ROOT</span><span><span>=</span><span>/</span></span><span>home</span><span>/</span><span>sys_wh</span><span>/</span><span>dotnet</span></div></div><div><div><div>7</div></div><div><span>export</span><span> </span><span>PATH</span><span>=</span><span>$PATH</span><span>:/</span><span>home</span><span>/</span><span>sys_wh</span><span>/</span><span>dotnet</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span># 重载配置文件</span></div></div><div><div><div>10</div></div><div><span>source</span><span> </span><span>/etc/profile.d/dotnet.sh</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span># 终端使用变量,执行以下命令查看是否有版本输出，最好切换下用户测试是否所有用户都可以读到变量</span></div></div><div><div><div>13</div></div><div><span>dotnet</span><span> </span><span>--info</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>启动脚本<a href="#启动脚本"><span>#</span></a></h2><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/bin/bash</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>#这里可替换为你自己的执行程序，其他代码无需更改</span></div></div><div><div><div>4</div></div><div><span>APP_NAME</span><span>=</span><span>CATSTI.YZ.dll</span></div></div><div><div><div>5</div></div><div><span>#这里修改程序运行的端口号</span></div></div><div><div><div>6</div></div><div><span>APP_PORT</span><span>=</span><span>8181</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span>#使用说明，用来提示输入参数</span></div></div><div><div><div>9</div></div><div><span>usage</span><span>() {</span></div></div><div><div><div>10</div></div><div><span>    </span><span>echo</span><span> </span><span>"Usage: sh YZServiceStart.sh [start|stop|restart|status]"</span></div></div><div><div><div>11</div></div><div><span>    </span><span>exit</span><span> </span><span>1</span></div></div><div><div><div>12</div></div><div><span>}</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>#检查程序是否在运行</span></div></div><div><div><div>15</div></div><div><span>is_exist</span><span>(){</span></div></div><div><div><div>16</div></div><div><span>  </span><span>pid</span><span>=</span><span>`</span><span>ps</span><span> </span><span>-ef</span><span>|</span><span>grep</span><span> </span><span>$APP_NAME</span><span>|</span><span>grep</span><span> </span><span>-v</span><span> grep</span><span>|</span><span>awk</span><span> '{print $2}' `</span></div></div><div><div><div>17</div></div><div><span>  </span><span>#如果不存在返回1，存在返回0</span></div></div><div><div><div>18</div></div><div><span>  </span><span>if</span><span><span> [ </span><span>-z</span><span> </span></span><span>"</span><span><span>${</span><span>pid</span><span>}</span></span><span>"</span><span> ]; </span><span>then</span></div></div><div><div><div>19</div></div><div><span>   </span><span>return</span><span> </span><span>1</span></div></div><div><div><div>20</div></div><div><span>  </span><span>else</span></div></div><div><div><div>21</div></div><div><span>    </span><span>return</span><span> </span><span>0</span></div></div><div><div><div>22</div></div><div><span>  </span><span>fi</span></div></div><div><div><div>23</div></div><div><span>}</span></div></div><div><div><div>24</div></div><div>
</div></div><div><div><div>25</div></div><div><span>#启动方法</span></div></div><div><div><div>26</div></div><div><span>start</span><span>(){</span></div></div><div><div><div>27</div></div><div><span>  </span><span>is_exist</span></div></div><div><div><div>28</div></div><div><span>  </span><span>if</span><span> [ </span><span>$?</span><span><span> </span><span>-eq</span><span> </span></span><span>"0"</span><span> ]; </span><span>then</span></div></div><div><div><div>29</div></div><div><span>    </span><span>echo</span><span> </span><span>"</span><span><span>${</span><span>APP_NAME</span><span>}</span></span><span> is already running. pid=</span><span><span>${</span><span>pid</span><span>}</span></span><span> ."</span></div></div><div><div><div>30</div></div><div><span>  </span><span>else</span></div></div><div><div><div>31</div></div><div><span>    </span><span>nohup</span><span> </span><span>dotnet</span><span>  </span><span>$APP_NAME</span><span> </span><span>--urls=http://</span><span>*</span><span>:</span><span>$APP_PORT</span><span> &gt; </span><span>/dev/null</span><span> 2&gt;&amp;1 &amp;</span></div></div><div><div><div>32</div></div><div><span>    </span><span>echo</span><span> </span><span>"</span><span><span>${</span><span>APP_NAME</span><span>}</span></span><span> start success"</span></div></div><div><div><div>33</div></div><div><span>  </span><span>fi</span></div></div><div><div><div>34</div></div><div><span>}</span></div></div><div><div><div>35</div></div><div>
</div></div><div><div><div>36</div></div><div><span>#停止方法</span></div></div><div><div><div>37</div></div><div><span>stop</span><span>(){</span></div></div><div><div><div>38</div></div><div><span>  </span><span>is_exist</span></div></div><div><div><div>39</div></div><div><span>  </span><span>if</span><span> [ </span><span>$?</span><span><span> </span><span>-eq</span><span> </span></span><span>"0"</span><span> ]; </span><span>then</span></div></div><div><div><div>40</div></div><div><span>    </span><span>kill</span><span> </span><span>-9</span><span> </span><span>$pid</span></div></div><div><div><div>41</div></div><div><span>  </span><span>else</span></div></div><div><div><div>42</div></div><div><span>    </span><span>echo</span><span> </span><span>"</span><span><span>${</span><span>APP_NAME</span><span>}</span></span><span> is not running"</span></div></div><div><div><div>43</div></div><div><span>  </span><span>fi</span></div></div><div><div><div>44</div></div><div><span>}</span></div></div><div><div><div>45</div></div><div>
</div></div><div><div><div>46</div></div><div><span>#输出运行状态</span></div></div><div><div><div>47</div></div><div><span>status</span><span>(){</span></div></div><div><div><div>48</div></div><div><span>  </span><span>is_exist</span></div></div><div><div><div>49</div></div><div><span>  </span><span>if</span><span> [ </span><span>$?</span><span><span> </span><span>-eq</span><span> </span></span><span>"0"</span><span> ]; </span><span>then</span></div></div><div><div><div>50</div></div><div><span>    </span><span>echo</span><span> </span><span>"</span><span><span>${</span><span>APP_NAME</span><span>}</span></span><span> is running. Pid is </span><span><span>${</span><span>pid</span><span>}</span></span><span>"</span></div></div><div><div><div>51</div></div><div><span>  </span><span>else</span></div></div><div><div><div>52</div></div><div><span>    </span><span>echo</span><span> </span><span>"</span><span><span>${</span><span>APP_NAME</span><span>}</span></span><span> is NOT running."</span></div></div><div><div><div>53</div></div><div><span>  </span><span>fi</span></div></div><div><div><div>54</div></div><div><span>}</span></div></div><div><div><div>55</div></div><div>
</div></div><div><div><div>56</div></div><div><span>#重启</span></div></div><div><div><div>57</div></div><div><span>restart</span><span>(){</span></div></div><div><div><div>58</div></div><div><span>  </span><span>stop</span></div></div><div><div><div>59</div></div><div><span>  </span><span>start</span></div></div><div><div><div>60</div></div><div><span>}</span></div></div><div><div><div>61</div></div><div>
</div></div><div><div><div>62</div></div><div><span>#根据输入参数，选择执行对应方法，不输入则执行使用说明</span></div></div><div><div><div>63</div></div><div><span>case</span><span> </span><span>"</span><span>$1</span><span>"</span><span> </span><span>in</span></div></div><div><div><div>64</div></div><div><span>  </span><span>"start"</span><span>)</span></div></div><div><div><div>65</div></div><div><span>    </span><span>start</span></div></div><div><div><div>66</div></div><div><span><span>    </span></span><span>;;</span></div></div><div><div><div>67</div></div><div><span>  </span><span>"stop"</span><span>)</span></div></div><div><div><div>68</div></div><div><span>    </span><span>stop</span></div></div><div><div><div>69</div></div><div><span><span>    </span></span><span>;;</span></div></div><div><div><div>70</div></div><div><span>  </span><span>"status"</span><span>)</span></div></div><div><div><div>71</div></div><div><span>    </span><span>status</span></div></div><div><div><div>72</div></div><div><span><span>    </span></span><span>;;</span></div></div><div><div><div>73</div></div><div><span>  </span><span>"restart"</span><span>)</span></div></div><div><div><div>74</div></div><div><span>    </span><span>restart</span></div></div><div><div><div>75</div></div><div><span><span>    </span></span><span>;;</span></div></div><div><div><div>76</div></div><div><span><span>  </span></span><span>*)</span></div></div><div><div><div>77</div></div><div><span>    </span><span>usage</span></div></div><div><div><div>78</div></div><div><span><span>    </span></span><span>;;</span></div></div><div><div><div>79</div></div><div><span>esac</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>
<section><h2>批量启动脚本<a href="#批量启动脚本"><span>#</span></a></h2><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/bin/bash</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span># 应用程序的路径</span></div></div><div><div><div>4</div></div><div><span>APP_PATH</span><span>=</span><span>"/home/sys_wh/yz/30-NewYZ/CATSTI.YZ.dll"</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span># 启动的端口列表</span></div></div><div><div><div>7</div></div><div><span>PORTS</span><span><span>=</span><span>( </span></span><span>"5000"</span><span> </span><span>"5001"</span><span> </span><span>"5002"</span><span> )</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>start</span><span>() {</span></div></div><div><div><div>10</div></div><div><span>  </span><span># 循环启动每个端口的应用程序</span></div></div><div><div><div>11</div></div><div><span>  </span><span>for</span><span> </span><span>PORT</span><span> </span><span>in</span><span> </span><span>"</span><span><span>${</span><span>PORTS</span></span><span>[</span><span>@</span><span>]</span><span>}</span><span>"</span><span>; </span><span>do</span></div></div><div><div><div>12</div></div><div><span>    </span><span>nohup</span><span> </span><span>dotnet</span><span> </span><span>$APP_PATH</span><span> </span><span>--urls</span><span> </span><span>http://</span><span>*</span><span>:</span><span>$PORT</span><span> &gt; </span><span>"app_</span><span>$PORT</span><span>.log"</span><span> 2&gt;&amp;1 &amp;</span></div></div><div><div><div>13</div></div><div><span>    </span><span>echo</span><span> </span><span>"端口 </span><span>$PORT</span><span> 已启动"</span></div></div><div><div><div>14</div></div><div><span>  </span><span>done</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span>  </span><span>echo</span><span> </span><span>"应用程序已批量启动。"</span></div></div><div><div><div>17</div></div><div><span>}</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>stop</span><span>() {</span></div></div><div><div><div>20</div></div><div><span>  </span><span># 循环启动每个端口的应用程序</span></div></div><div><div><div>21</div></div><div><span>  </span><span>for</span><span> </span><span>PORT</span><span> </span><span>in</span><span> </span><span>"</span><span><span>${</span><span>PORTS</span></span><span>[</span><span>@</span><span>]</span><span>}</span><span>"</span><span>; </span><span>do</span></div></div><div><div><div>22</div></div><div><span>    </span><span># 停止端口为5000的应用程序</span></div></div><div><div><div>23</div></div><div><span>    </span><span>kill</span><span> $(</span><span>lsof</span><span> </span><span>-i</span><span> </span><span>:</span><span>$PORT</span><span> </span><span>-t</span><span>)</span></div></div><div><div><div>24</div></div><div><span>    </span><span>echo</span><span> </span><span>"端口 </span><span>$PORT</span><span> 已停止"</span></div></div><div><div><div>25</div></div><div><span>  </span><span>done</span></div></div><div><div><div>26</div></div><div><span>  </span><span>echo</span><span> </span><span>"............应用程序已批量停止。............"</span></div></div><div><div><div>27</div></div><div><span>}</span></div></div><div><div><div>28</div></div><div><span>status</span><span>() {</span></div></div><div><div><div>29</div></div><div><span>  </span><span>for</span><span> </span><span>PORT</span><span> </span><span>in</span><span> </span><span>"</span><span><span>${</span><span>PORTS</span></span><span>[</span><span>@</span><span>]</span><span>}</span><span>"</span><span>; </span><span>do</span></div></div><div><div><div>30</div></div><div><span>    </span><span># 检查端口是否在使用中</span></div></div><div><div><div>31</div></div><div><span>    </span><span>if</span><span><span> [ </span><span>-n</span><span> </span></span><span>"$(</span><span>netstat</span><span> </span><span>-tuln</span><span> </span><span>|</span><span> </span><span>grep</span><span> :</span><span>$PORT</span><span>)"</span><span><span> ] || [ </span><span>-n</span><span> </span></span><span>"$(</span><span>ss</span><span> </span><span>-tuln</span><span> </span><span>|</span><span> </span><span>grep</span><span> :</span><span>$PORT</span><span>)"</span><span> ]; </span><span>then</span></div></div><div><div><div>32</div></div><div><span>      </span><span>echo</span><span> </span><span>"端口 </span><span>$PORT</span><span> 正在使用中"</span></div></div><div><div><div>33</div></div><div><span>    </span><span>else</span></div></div><div><div><div>34</div></div><div><span>      </span><span>echo</span><span> </span><span>"端口 </span><span>$PORT</span><span> 未被使用"</span></div></div><div><div><div>35</div></div><div><span>    </span><span>fi</span></div></div><div><div><div>36</div></div><div><span>  </span><span>done</span></div></div><div><div><div>37</div></div><div><span>}</span></div></div><div><div><div>38</div></div><div>
</div></div><div><div><div>39</div></div><div><span>case</span><span> </span><span>"</span><span>$1</span><span>"</span><span> </span><span>in</span></div></div><div><div><div>40</div></div><div><span>  </span><span>start</span><span>)</span></div></div><div><div><div>41</div></div><div><span>    </span><span>start</span><span> </span><span>"</span><span>$2</span><span>"</span></div></div><div><div><div>42</div></div><div><span>    </span><span>sleep</span><span> </span><span>5s</span></div></div><div><div><div>43</div></div><div><span>    </span><span>status</span><span> </span><span>"</span><span>$2</span><span>"</span></div></div><div><div><div>44</div></div><div><span><span>  </span></span><span>;;</span></div></div><div><div><div>45</div></div><div><span>  </span><span>stop</span><span>)</span></div></div><div><div><div>46</div></div><div><span>    </span><span>stop</span><span> </span><span>"</span><span>$2</span><span>"</span></div></div><div><div><div>47</div></div><div><span><span>  </span></span><span>;;</span></div></div><div><div><div>48</div></div><div><span>  </span><span>status</span><span>)</span></div></div><div><div><div>49</div></div><div><span>    </span><span>status</span><span> </span><span>"</span><span>$2</span><span>"</span></div></div><div><div><div>50</div></div><div><span><span>  </span></span><span>;;</span></div></div><div><div><div>51</div></div><div><span>  </span><span>restart</span><span>)</span></div></div><div><div><div>52</div></div><div><span>    </span><span>stop</span><span> </span><span>"</span><span>$2</span><span>"</span></div></div><div><div><div>53</div></div><div><span>    </span><span>sleep</span><span> </span><span>3s</span></div></div><div><div><div>54</div></div><div><span>    </span><span>start</span><span> </span><span>"</span><span>$2</span><span>"</span></div></div><div><div><div>55</div></div><div><span>    </span><span>sleep</span><span> </span><span>5s</span></div></div><div><div><div>56</div></div><div><span>    </span><span>status</span><span> </span><span>"</span><span>$2</span><span>"</span></div></div><div><div><div>57</div></div><div><span><span>  </span></span><span>;;</span></div></div><div><div><div>58</div></div><div><span><span>  </span></span><span>*)</span></div></div><div><div><div>59</div></div><div><span>    </span><span>echo</span><span> </span><span>"第一个参数请输入:start|stop|restart|status"</span></div></div><div><div><div>60</div></div><div><span>    </span><span>exit</span><span> </span><span>1</span></div></div><div><div><div>61</div></div><div><span><span>  </span></span><span>;;</span></div></div><div><div><div>62</div></div><div><span>esac</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>
<section><h2>注册系统服务<a href="#注册系统服务"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[Unit]</span></div></div><div><div><div>2</div></div><div><span>Description</span><span>=</span><span>Dotnet</span><span> </span><span>Searver</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>[Service]</span></div></div><div><div><div>5</div></div><div><span>LimitMEMLOCK</span><span>=</span><span>infinity</span></div></div><div><div><div>6</div></div><div><span>LimitNOFILE</span><span>=</span><span>65535</span></div></div><div><div><div>7</div></div><div><span>WorkingDirectory</span><span>=</span><span>/app</span></div></div><div><div><div>8</div></div><div><span>Restart</span><span>=</span><span>always</span></div></div><div><div><div>9</div></div><div><span>Type</span><span>=</span><span>forking</span></div></div><div><div><div>10</div></div><div><span>ExecStart</span><span>=</span><span>/app/startup.sh</span></div></div><div><div><div>11</div></div><div><span>ExecStop</span><span>=</span><span>/usr/bin/kill</span><span> </span><span>-15</span><span> </span><span>$MAINPID</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>[Install]</span></div></div><div><div><div>14</div></div><div><span>WantedBy</span><span>=</span><span>multi-user.target</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section>
<section><h2>银河麒麟 V10 SP3 aarch64 安装 .NET 6 Runtime/SDK<a href="#银河麒麟-v10-sp3-aarch64-安装-net-6-runtimesdk"><span>#</span></a></h2><blockquote><p>适用环境：银河麒麟 V10 SP3 aarch64（ARM 鲲鹏架构），离线部署。</p></blockquote><section><h3>⚠️ 前置说明<a href="#️-前置说明"><span>#</span></a></h3><p>麒麟官方 yum 源（update.cs2c.com.cn）里<strong>没有微软原生的 dotnet6 rpm 包</strong>，不要尝试装 CentOS 的 dotnet rpm——架构和 glibc 版本对不上，大概率装不上或运行段错误。</p><p><strong>推荐方案：二进制 tar.gz 压缩包</strong>，与麒麟 V10 SP3 aarch64 适配稳定，等保验收一般认可。</p></section><section><h3>选择 Runtime 还是 SDK？<a href="#选择-runtime-还是-sdk"><span>#</span></a></h3>

<table><thead><tr><th>场景</th><th>选哪个</th></tr></thead><tbody><tr><td>只跑已发布好的 ASP.NET Core Web 程序（生产服务器，99% 是这个）</td><td><strong>ASP.NET Core Runtime</strong></td></tr><tr><td>还要在服务器上编译、发布代码（开发机）</td><td><strong>dotnet SDK</strong>（自带 Runtime）</td></tr></tbody></table></section><section><h3>依赖前置安装（必须）<a href="#依赖前置安装必须"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>yum</span><span> </span><span>install</span><span> </span><span>libicu</span><span> </span><span>openssl-libs</span><span> </span><span>krb5-libs</span><span> </span><span>zlib</span><span> </span><span>-y</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>缺了 <code>libicu</code> 等依赖会报 icu 相关异常，运行直接崩溃。</p></blockquote></section><section><h3>方案一：只装 Runtime（生产推荐）<a href="#方案一只装-runtime生产推荐"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 下载（微软官方 arm64/aarch64）</span></div></div><div><div><div>2</div></div><div><span>wget</span><span> </span><span>https://download.visualstudio.microsoft.com/download/pr/09073424-8463-4419-8128-831705718712/24007b3709292f54140609271875336d/aspnetcore-runtime-6.0.36-linux-arm64.tar.gz</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 解压到固定目录</span></div></div><div><div><div>5</div></div><div><span>mkdir</span><span> </span><span>-p</span><span> </span><span>/usr/share/dotnet</span></div></div><div><div><div>6</div></div><div><span>tar</span><span> </span><span>-zxf</span><span> </span><span>aspnetcore-runtime-6.0.36-linux-arm64.tar.gz</span><span> </span><span>-C</span><span> </span><span>/usr/share/dotnet</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span># 建立软链接，全局可用</span></div></div><div><div><div>9</div></div><div><span>ln</span><span> </span><span>-s</span><span> </span><span>/usr/share/dotnet/dotnet</span><span> </span><span>/usr/bin/dotnet</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span># 验证</span></div></div><div><div><div>12</div></div><div><span>dotnet</span><span> </span><span>--info</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>方案二：安装 SDK（需要编译能力）<a href="#方案二安装-sdk需要编译能力"><span>#</span></a></h3><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 下载</span></div></div><div><div><div>2</div></div><div><span>wget</span><span> </span><span>https://download.visualstudio.microsoft.com/download/pr/09073424-8463-4419-8128-831705718712/50478103581178238877063410141257/dotnet-sdk-6.0.428-linux-arm64.tar.gz</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 解压到固定目录</span></div></div><div><div><div>5</div></div><div><span>mkdir</span><span> </span><span>-p</span><span> </span><span>/usr/share/dotnet</span></div></div><div><div><div>6</div></div><div><span>tar</span><span> </span><span>-zxf</span><span> </span><span>dotnet-sdk-6.0.428-linux-arm64.tar.gz</span><span> </span><span>-C</span><span> </span><span>/usr/share/dotnet</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span># 建立软链接</span></div></div><div><div><div>9</div></div><div><span>ln</span><span> </span><span>-s</span><span> </span><span>/usr/share/dotnet/dotnet</span><span> </span><span>/usr/bin/dotnet</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span># 配置环境变量（systemd 服务启动时需要）</span></div></div><div><div><div>12</div></div><div><span>vi</span><span> </span><span>/etc/profile</span></div></div><div><div><div>13</div></div><div><span># 末尾追加：</span></div></div><div><div><div>14</div></div><div><span>export</span><span> </span><span>DOTNET_ROOT</span><span><span>=</span><span>/</span></span><span>usr</span><span>/</span><span>share</span><span>/</span><span>dotnet</span></div></div><div><div><div>15</div></div><div><span>export</span><span> </span><span>PATH</span><span>=</span><span>$PATH</span><span>:/</span><span>usr</span><span>/</span><span>share</span><span>/</span><span>dotnet</span></div></div><div><div><div>16</div></div><div><span>source</span><span> </span><span>/etc/profile</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span># 验证</span></div></div><div><div><div>19</div></div><div><span>dotnet</span><span> </span><span>--version</span></div></div><div><div><div>20</div></div><div><span>dotnet</span><span> </span><span>--info</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><blockquote><p><strong>Runtime vs SDK 一句话区别：</strong></p><ul>
<li>SDK：<code>dotnet build</code> / <code>dotnet run</code> / <code>dotnet publish</code> 全支持（开发 + 运行）</li>
<li>Runtime：只能运行已发布好的 dll，不能编译</li>
</ul></blockquote></section><section><h3>发布程序时注意<a href="#发布程序时注意"><span>#</span></a></h3><p>使用**框架依赖模式（FDD）**发布，不要用独立包（Self-contained）。FDD 依赖服务器上的全局 Runtime，体积更小，也更符合麒麟等保项目的规范。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 示例：FDD 模式发布（在开发机上执行）</span></div></div><div><div><div>2</div></div><div><span>dotnet</span><span> </span><span>publish</span><span> </span><span>-c</span><span> </span><span>Release</span><span> </span><span>-r</span><span> </span><span>linux-arm64</span><span> </span><span>--self-contained</span><span> </span><span>false</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>配套：ASP.NET Core 程序 systemd 服务模板<a href="#配套aspnet-core-程序-systemd-服务模板"><span>#</span></a></h3><p>将以下配置写入 <code>/usr/lib/systemd/system/mydotnet.service</code>：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[Unit]</span></div></div><div><div><div>2</div></div><div><span>Description</span><span><span>=</span><span>MyDotNet6 WebApp</span></span></div></div><div><div><div>3</div></div><div><span>After</span><span><span>=</span><span>network.target</span></span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>[Service]</span></div></div><div><div><div>6</div></div><div><span>WorkingDirectory</span><span><span>=</span><span>/opt/yourapp</span></span></div></div><div><div><div>7</div></div><div><span>ExecStart</span><span><span>=</span><span>/usr/bin/dotnet /opt/yourapp/xxx.dll</span></span></div></div><div><div><div>8</div></div><div><span>Restart</span><span><span>=</span><span>always</span></span></div></div><div><div><div>9</div></div><div><span>RestartSec</span><span><span>=</span><span>5</span></span></div></div><div><div><div>10</div></div><div><span>User</span><span><span>=</span><span>root</span></span></div></div><div><div><div>11</div></div><div><span>Environment</span><span>=</span><span>ASPNETCORE_URLS</span><span><span>=</span><span>http://0.0.0.0:5000</span></span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>[Install]</span></div></div><div><div><div>14</div></div><div><span>WantedBy</span><span><span>=</span><span>multi-user.target</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p><code>ExecStart</code> 路径不受你装的是 SDK 还是 Runtime 影响，统一用 <code>/usr/bin/dotnet</code>。</p></blockquote><p>启用服务：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>systemctl</span><span> </span><span>daemon-reload</span></div></div><div><div><div>2</div></div><div><span>systemctl</span><span> </span><span>enable</span><span> </span><span>mydotnet</span></div></div><div><div><div>3</div></div><div><span>systemctl</span><span> </span><span>start</span><span> </span><span>mydotnet</span></div></div><div><div><div>4</div></div><div><span>systemctl</span><span> </span><span>status</span><span> </span><span>mydotnet</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/5711187a/</id>
      <title type="text">【Linux】Libgdiplus安装</title>
      <published>2024-07-01T08:31:13.000Z</published>
      <updated>2024-07-01T08:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/5711187a/"/>
      <summary type="text">在CentOS 7上安装libgdiplus的过程，以解决ASP.NET Core MVC项目在处理图片时遇到的The type initializer for ‘Gdip‘ threw an exception错误。首先，通过安装yum-utils和epel-release来获取必要的工具和仓库支持。</summary>
      <content type="html"><![CDATA[<p>ASP.NET Core MVC的项目需要处理图片，部署到CentOS 7上面时会报<code>The type initializer for ‘Gdip‘ threw an exception</code>，需要安装<code>libgdiplus</code>。
做为linux门外汉，虽然网上已经有不少相关内容，还是摸索了不少时间，记录一下。
感谢CentOS7离线安装神器<code>yumdownloader</code>一文的帮助，主要内容均来自此文。
首先在虚拟机上安装CentOS7，需要借用这台能上网的CentOS7虚拟机下载离线安装包。并且要保证这台虚拟机和要部署的目标服务器环境相同，避免下载安装包时遗漏了某些依赖包。
运行以下命令安装<code>yumdownloader</code></p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>yum install yum-utils -y</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>下载EPEL最新发布包：<code>epel-release-7-14.noarch.rpm</code>并安装，否则<code>yumdownloader</code>找不到<code>libgdiplus</code>的离线安装包。</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>rpm -ivh epel-release-7-14.noarch.rpm</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>下载libgdiplus离线安装包</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>yumdownloader</span><span> </span><span>--destdir=./libgdiplus</span><span> </span><span>--resolve</span><span> </span><span>libgdiplus.x86_64</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<p>下载时注意一下，在最小化安装的CentOS7上面，libgdiplus一共是33个包文件，检查一下是否有遗漏，防止下载安装包的虚拟机上已经安装了某些依赖包，导致下载不完整。
将下载的安装包压缩打包</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>tar zcf libgdiplus.tar.gz libgdiplus</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>将压缩包上传到目标服务器并解压</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>tar</span><span> </span><span>zxf</span><span> </span><span>libgdiplus.tar.gz</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>安装</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>libgdiplus</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>rpm</span><span> </span><span>-Uvh</span><span> </span><span>*</span><span>.rpm</span><span> </span><span>--nodeps</span><span> </span><span>--force</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>附件：</p>
<p>这是做好的一个包  <a href="https://raw.githubusercontent.com/wangbin-blog/pic-resources/main/2024/07/01215410360.gz" target="_blank">下载地址</a></p>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/1c39c402/</id>
      <title type="text">【Linux】nginx 离线安装</title>
      <published>2024-06-16T08:31:13.000Z</published>
      <updated>2024-06-16T08:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/1c39c402/"/>
      <summary type="text">本文《【Linux】nginx 离线安装》详细介绍了在Linux环境下离线安装Nginx的全过程。文章详细描述了Nginx的编译安装过程，并提供了启动Nginx的常用命令。最后，文章介绍了如何配置Nginx的开机自启动，确保服务在系统重启后能够自动运行。这些内容对离线环境下的Nginx安装和管理非常有帮助。</summary>
      <content type="html"><![CDATA[<section><h2>资源下载<a href="#资源下载"><span>#</span></a></h2><p>nginx-1.20.1.tar.gz（下载链接中包含<a href="https://so.csdn.net/so/search?q=gcc&amp;spm=1001.2101.3001.7020" target="_blank">gcc</a>、g++、pcre、libtool、nginx）</p><p>链接：<a href="https://pan.baidu.com/s/1Niv33uZa4gj0viYFrnBTBQ" target="_blank">https://pan.baidu.com/s/1Niv33uZa4gj0viYFrnBTBQ</a></p><p>提取码：0b91</p></section>
<section><h2>安装步骤<a href="#安装步骤"><span>#</span></a></h2><section><h3><strong>安装gcc</strong><a href="#安装gcc"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>rpm</span><span> </span><span>-Uvh</span><span> </span><span>*</span><span>.rpm</span><span> </span><span>--nodeps</span><span> </span><span>--force</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>结果</p></blockquote><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@doris54 gcc]# rpm -Uvh *.rpm --nodeps --force</span></div></div><div><div><div>2</div></div><div><span>warning:</span><span> </span><span>cpp-4.8.5-16.el7.x86_64.rpm:</span><span> </span><span>Header</span><span> </span><span>V3</span><span> </span><span>RSA/SHA256</span><span> </span><span>Signature,</span><span> </span><span>key</span><span> </span><span>ID</span><span> </span><span>f4a80eb5:</span><span> </span><span>NOKEY</span></div></div><div><div><div>3</div></div><div><span>Preparing...</span><span>                          </span><span>################################# [100%]</span></div></div><div><div><div>4</div></div><div><span>Updating</span><span> </span><span>/</span><span> </span><span>installing...</span></div></div><div><div><div>5</div></div><div><span>   </span><span>1:zlib-1.2.7-17.el7</span><span>                </span><span>################################# [  6%]</span></div></div><div><div><div>6</div></div><div><span>   </span><span>2:mpfr-3.1.1-4.el7</span><span>                 </span><span>################################# [ 13%]</span></div></div><div><div><div>7</div></div><div><span>   </span><span>3:libmpc-1.0.1-3.el7</span><span>               </span><span>################################# [ 19%]</span></div></div><div><div><div>8</div></div><div><span>   </span><span>4:openssl-libs-1:1.0.2k-8.el7</span><span>      </span><span>################################# [ 25%]</span></div></div><div><div><div>9</div></div><div><span>   </span><span>5:cpp-4.8.5-16.el7</span><span>                 </span><span>################################# [ 31%]</span></div></div><div><div><div>10</div></div><div><span>   </span><span>6:zlib-devel-1.2.7-17.el7</span><span>          </span><span>################################# [ 38%]</span></div></div><div><div><div>11</div></div><div><span>   </span><span>7:kernel-headers-3.10.0-693.el7</span><span>    </span><span>################################# [ 44%]</span></div></div><div><div><div>12</div></div><div><span>   </span><span>8:glibc-headers-2.17-196.el7</span><span>       </span><span>################################# [ 50%]</span></div></div><div><div><div>13</div></div><div><span>   </span><span>9:glibc-devel-2.17-196.el7</span><span>         </span><span>################################# [ 56%]</span></div></div><div><div><div>14</div></div><div><span>  </span><span>10:gcc-4.8.5-16.el7</span><span>                 </span><span>################################# [ 63%]</span></div></div><div><div><div>15</div></div><div><span>  </span><span>11:openssl-devel-1:1.0.2k-8.el7</span><span>     </span><span>################################# [ 69%]</span></div></div><div><div><div>16</div></div><div><span>  </span><span>12:openssl-1:1.0.2k-8.el7</span><span>           </span><span>################################# [ 75%]</span></div></div><div><div><div>17</div></div><div><span>  </span><span>13:openssl098e-0.9.8e-29.el7.centos.#################################</span><span> [ </span><span>81%]</span></div></div><div><div><div>18</div></div><div><span>Cleaning</span><span> </span><span>up</span><span> </span><span>/</span><span> </span><span>removing...</span></div></div><div><div><div>19</div></div><div><span>  </span><span>14:openssl-1:1.0.2k-19.el7</span><span>          </span><span>################################# [ 88%]</span></div></div><div><div><div>20</div></div><div><span>  </span><span>15:openssl-libs-1:1.0.2k-19.el7</span><span>     </span><span>################################# [ 94%]</span></div></div><div><div><div>21</div></div><div><span>  </span><span>16:zlib-1.2.7-18.el7</span><span>                </span><span>################################# [100%]</span></div></div><div><div><div>22</div></div><div><span>[root@doris54 gcc]#</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3><strong>安装g++</strong><a href="#安装g"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>rpm</span><span> </span><span>-Uvh</span><span> </span><span>*</span><span>.rpm</span><span> </span><span>--nodeps</span><span> </span><span>--force</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>结果</p></blockquote><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@doris54 gcc-c++]# rpm -Uvh *.rpm --nodeps --force</span></div></div><div><div><div>2</div></div><div><span>warning:</span><span> </span><span>autogen-libopts-5.18-5.el7.x86_64.rpm:</span><span> </span><span>Header</span><span> </span><span>V3</span><span> </span><span>RSA/SHA256</span><span> </span><span>Signature,</span><span> </span><span>key</span><span> </span><span>ID</span><span> </span><span>f4a80eb5:</span><span> </span><span>NOKEY</span></div></div><div><div><div>3</div></div><div><span>Preparing...</span><span>                          </span><span>################################# [100%]</span></div></div><div><div><div>4</div></div><div><span>Updating</span><span> </span><span>/</span><span> </span><span>installing...</span></div></div><div><div><div>5</div></div><div><span>   </span><span>1:pkgconfig-1:0.27.1-4.el7</span><span>         </span><span>################################# [  5%]</span></div></div><div><div><div>6</div></div><div><span>   </span><span>2:zlib-1.2.7-17.el7</span><span>                </span><span>################################# [ 10%]</span></div></div><div><div><div>7</div></div><div><span>   </span><span>3:libcom_err-1.42.9-10.el7</span><span>         </span><span>################################# [ 15%]</span></div></div><div><div><div>8</div></div><div><span>   </span><span>4:openssl-libs-1:1.0.2k-8.el7</span><span>      </span><span>################################# [ 20%]</span></div></div><div><div><div>9</div></div><div><span>   </span><span>5:ntpdate-4.2.6p5-25.el7.centos.2</span><span>  </span><span>################################# [ 25%]</span></div></div><div><div><div>10</div></div><div><span>   </span><span>6:zlib-devel-1.2.7-17.el7</span><span>          </span><span>################################# [ 30%]</span></div></div><div><div><div>11</div></div><div><span>   </span><span>7:libsepol-devel-2.5-6.el7</span><span>         </span><span>################################# [ 35%]</span></div></div><div><div><div>12</div></div><div><span>   </span><span>8:libselinux-devel-2.5-11.el7</span><span>      </span><span>################################# [ 40%]</span></div></div><div><div><div>13</div></div><div><span>   </span><span>9:libverto-devel-0.2.5-4.el7</span><span>       </span><span>################################# [ 45%]</span></div></div><div><div><div>14</div></div><div><span>  </span><span>10:libstdc++-devel-4.8.5-16.el7</span><span>     </span><span>################################# [ 50%]</span></div></div><div><div><div>15</div></div><div><span>  </span><span>11:keyutils-libs-devel-1.5.8-3.el7</span><span>  </span><span>################################# [ 55%]</span></div></div><div><div><div>16</div></div><div><span>  </span><span>12:krb5-devel-1.15.1-8.el7</span><span>          </span><span>################################# [ 60%]</span></div></div><div><div><div>17</div></div><div><span>  </span><span>13:autogen-libopts-5.18-5.el7</span><span>       </span><span>################################# [ 65%]</span></div></div><div><div><div>18</div></div><div><span>  </span><span>14:ntp-4.2.6p5-25.el7.centos.2</span><span>      </span><span>################################# [ 70%]</span></div></div><div><div><div>19</div></div><div><span>  </span><span>15:openssl-devel-1:1.0.2k-8.el7</span><span>     </span><span>################################# [ 75%]</span></div></div><div><div><div>20</div></div><div><span>  </span><span>16:gcc-c++-4.8.5-16.el7</span><span>             </span><span>################################# [ 80%]</span></div></div><div><div><div>21</div></div><div><span>  </span><span>17:openssl-1:1.0.2k-8.el7</span><span>           </span><span>################################# [ 85%]</span></div></div><div><div><div>22</div></div><div><span>  </span><span>18:openssl098e-0.9.8e-29.el7.centos.#################################</span><span> [ </span><span>90%]</span></div></div><div><div><div>23</div></div><div><span>  </span><span>19:tcl-1:8.5.13-8.el7</span><span>               </span><span>################################# [ 95%]</span></div></div><div><div><div>24</div></div><div><span>Cleaning</span><span> </span><span>up</span><span> </span><span>/</span><span> </span><span>removing...</span></div></div><div><div><div>25</div></div><div><span>  </span><span>20:libcom_err-1.42.9-17.el7</span><span>         </span><span>################################# [100%]</span></div></div><div><div><div>26</div></div><div><span>[root@doris54 gcc-c++]#</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3><strong>验证gcc、g++是否安装成功，执行命令：</strong><a href="#验证gccg是否安装成功执行命令"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>gcc</span><span> </span><span>-v</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>结果</p></blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@doris54 gcc-c++]# gcc -v</span></div></div><div><div><div>2</div></div><div><span>Using</span><span> </span><span>built-in</span><span> </span><span>specs.</span></div></div><div><div><div>3</div></div><div><span>COLLECT_GCC</span><span>=</span><span>gcc</span></div></div><div><div><div>4</div></div><div><span>COLLECT_LTO_WRAPPER</span><span>=</span><span>/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper</span></div></div><div><div><div>5</div></div><div><span>Target:</span><span> </span><span>x86_64-redhat-linux</span></div></div><div><div><div>6</div></div><div><span>Configured</span><span> </span><span>with:</span><span> </span><span>../configure</span><span> </span><span>--prefix=/usr</span><span> </span><span>--mandir=/usr/share/man</span><span> </span><span>--infodir=/usr/share/info</span><span> </span><span>--with-bugurl=http://bugzilla.redhat.com/bugzilla</span><span> </span><span>--enable-bootstrap</span><span> </span><span>--enable-shared</span><span> </span><span>--enable-threads=posix</span><span> </span><span>--enable-checking=release</span><span> </span><span>--with-system-zlib</span><span> </span><span>--enable-__cxa_atexit</span><span> </span><span>--disable-libunwind-exceptions</span><span> </span><span>--enable-gnu-unique-object</span><span> </span><span>--enable-linker-build-id</span><span> </span><span>--with-linker-hash-style=gnu</span><span> </span><span>--enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto</span><span> </span><span>--enable-plugin</span><span> </span><span>--enable-initfini-array</span><span> </span><span>--disable-libgcj</span><span> </span><span>--with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install</span><span> </span><span>--with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install</span><span> </span><span>--enable-gnu-indirect-function</span><span> </span><span>--with-tune=generic</span><span> </span><span>--with-arch_32=x86-64</span><span> </span><span>--build=x86_64-redhat-linux</span></div></div><div><div><div>7</div></div><div><span>Thread</span><span> </span><span>model:</span><span> </span><span>posix</span></div></div><div><div><div>8</div></div><div><span>gcc</span><span> </span><span>version</span><span> </span><span>4.8.5</span><span> </span><span>20150623</span><span> (Red </span><span>Hat</span><span> </span><span>4.8.5-16</span><span>) (</span><span>GCC</span><span>)</span></div></div><div><div><div>9</div></div><div><span>[root@doris54 gcc-c++]#</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>**安装PCRE，先把pcre解压出来，<strong><strong>tar -zxvf pcre-8.35.tar.gz</strong>，解压出来之后就要开始安装了</strong><a href="#安装pcre先把pcre解压出来tar--zxvf-pcre-835targz解压出来之后就要开始安装了"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>pcre-8.35</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>./configure</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>make</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>make</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3><strong>安装libtool,先解压libtool：tar -zxvf libtool-2.4.2.tar.gz，解压出来之后就要开始安装了</strong><a href="#安装libtool先解压libtooltar--zxvf-libtool-242targz解压出来之后就要开始安装了"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>libtool-2.4.2</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span> </span><span>./configure</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span> </span><span>make</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span> </span><span>make</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3><strong>安装nginx，先把nginx解压出来</strong> <strong>tar -zxvf nginx-1.20.1.tar.gz</strong>，解压出来之后就要开始安装了**<a href="#安装nginx先把nginx解压出来-tar--zxvf-nginx-1201targz解压出来之后就要开始安装了"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>nginx-1.20.1</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>  </span><span>./configure</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span> </span><span>make</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span> </span><span>make</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3><strong>启动nginx:</strong> <strong>nginx安装目录地址 -c nginx配置文件地址</strong> <strong>,安装后的路径好像会被变到/usr/local里面</strong><a href="#启动nginx-nginx安装目录地址--c-nginx配置文件地址-安装后的路径好像会被变到usrlocal里面"><span>#</span></a></h3>

<table><thead><tr><th><strong>常用命令</strong></th><th><strong>操作</strong></th></tr></thead><tbody><tr><td>/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf</td><td>启动nginx</td></tr><tr><td>/usr/local/nginx/sbin/nginx -s stop</td><td>停止nginx</td></tr><tr><td>/usr/local/nginx/sbin/nginx -s reload</td><td>重启nginx</td></tr><tr><td>netstat -tunlp</td><td>查看端口占用</td></tr><tr><td>netstat -tunlp</td><td>grep</td></tr></tbody></table><blockquote><p>nginx的配置文件为安装目录下的nginx目录中的nginx.conf，默认端口为80，启动后出现如下页面即为启动成功</p></blockquote></section></section>
<section><h2>开机自启<a href="#开机自启"><span>#</span></a></h2><section><h3><strong>编写自启服务</strong><a href="#编写自启服务"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>vim</span><span> </span><span>/usr/lib/systemd/system/nginx.service</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[Unit]</span></div></div><div><div><div>2</div></div><div><span>Description</span><span>=</span><span>nginx</span></div></div><div><div><div>3</div></div><div><span>After</span><span>=</span><span>network.target</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>[Service]</span></div></div><div><div><div>6</div></div><div><span>Type</span><span>=</span><span>forking</span></div></div><div><div><div>7</div></div><div><span>PIDFile</span><span>=</span><span>/usr/local/nginx/logs/nginx.pid</span></div></div><div><div><div>8</div></div><div><span>ExecStart</span><span>=</span><span>/usr/local/nginx/sbin/nginx</span><span> </span><span>-c</span><span> </span><span>/usr/local/nginx/conf/nginx.conf</span></div></div><div><div><div>9</div></div><div><span>ExecReload</span><span>=</span><span>/usr/local/nginx/sbin/nginx</span><span> </span><span>-s</span><span> </span><span>reload</span></div></div><div><div><div>10</div></div><div><span>ExecStop</span><span>=</span><span>/usr/local/nginx/sbin/nginx</span><span> </span><span>-s</span><span> </span><span>stop</span></div></div><div><div><div>11</div></div><div><span>PrivateTmp</span><span>=</span><span>true</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>[Install]</span></div></div><div><div><div>14</div></div><div><span>WantedBy</span><span>=</span><span>multi-user.target</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3><strong>设置nginx命令</strong><a href="#设置nginx命令"><span>#</span></a></h3><div><div><div><figure><figcaption><span>.bash_profile</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@node1 sbin]# vi  ~/.bash_profile</span></div></div><div><div><div>2</div></div><div><span># Get the aliases and functions</span></div></div><div><div><div>3</div></div><div><span>if</span><span><span> [ </span><span>-f</span><span> ~/.bashrc ]; </span></span><span>then</span></div></div><div><div><div>4</div></div><div><span>    </span><span>.</span><span> </span><span>~/.bashrc</span></div></div><div><div><div>5</div></div><div><span>fi</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># User specific environment and startup programs</span></div></div><div><div><div>8</div></div><div><span># 在原有的PATH 后加 :/usr/local/nginx/sbin</span></div></div><div><div><div>9</div></div><div><span>PATH</span><span><span>=</span><span>{</span></span><span>mathJaxContainer[0]}HOME/bin:/usr/local/nginx/sbin</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>export</span><span> </span><span>PATH</span></div></div><div><div><div>13</div></div><div><span>[root@node1 sbin]# source ~/.bash_profile</span></div></div><div><div><div>14</div></div><div><span>[root@node1 sbin]# nginx -v</span></div></div><div><div><div>15</div></div><div><span>nginx</span><span> </span><span>version:</span><span> </span><span>nginx/1.18.0</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3><strong>设置开机自启</strong><a href="#设置开机自启"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>root@node1</span><span> </span><span>~]#</span><span> </span><span>systemctl</span><span> </span><span>enable</span><span> </span><span>--now</span><span>  </span><span>nginx.service</span></div></div><div><div><div>2</div></div><div><span>[root@node1 ~]# ps -ef |</span><span>grep</span><span> </span><span>nginx</span></div></div><div><div><div>3</div></div><div><span>root</span><span>        </span><span>879</span><span>      </span><span>1</span><span>  </span><span>0</span><span> </span><span>16:17</span><span> </span><span>?</span><span>        </span><span>00:00:00</span><span> </span><span>nginx:</span><span> </span><span>master</span><span> </span><span>process</span><span> </span><span>/usr/local/nginx/sbin/nginx</span></div></div><div><div><div>4</div></div><div><span>nobody</span><span>      </span><span>881</span><span>    </span><span>879</span><span>  </span><span>0</span><span> </span><span>16:17</span><span> </span><span>?</span><span>        </span><span>00:00:00</span><span> </span><span>nginx:</span><span> </span><span>worker</span><span> </span><span>process</span></div></div><div><div><div>5</div></div><div><span>root</span><span>       </span><span>1738</span><span>   </span><span>1645</span><span>  </span><span>0</span><span> </span><span>16:20</span><span> </span><span>pts/0</span><span>    </span><span>00:00:00</span><span> </span><span>grep</span><span> </span><span>--color=auto</span><span> </span><span>nginx</span></div></div><div><div><div>6</div></div><div><span>[root@node1 ~]#</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3><strong>启动命令</strong><a href="#启动命令"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># nginx start</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>systemctl</span><span> </span><span>start</span><span> </span><span>nginx</span></div></div><div><div><div>3</div></div><div><span># nginx stop</span></div></div><div><div><div>4</div></div><div><span>sudo</span><span> </span><span>systemctl</span><span> </span><span>stop</span><span> </span><span>nginx</span></div></div><div><div><div>5</div></div><div><span># nginx reload</span></div></div><div><div><div>6</div></div><div><span>sudo</span><span> </span><span>systemctl</span><span> </span><span>reload</span><span> </span><span>nginx</span></div></div><div><div><div>7</div></div><div><span># nginx status</span></div></div><div><div><div>8</div></div><div><span>sudo</span><span> </span><span>systemctl</span><span> </span><span>status</span><span> </span><span>nginx</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section>
<section><h2>银河麒麟 V10 SP3 aarch64 离线安装（RPM 方式）<a href="#银河麒麟-v10-sp3-aarch64-离线安装rpm-方式"><span>#</span></a></h2><blockquote><p>适用环境：银河麒麟 V10 SP3 aarch64（ARM 鲲鹏架构），服务器无外网，需离线安装 nginx。</p></blockquote><section><h3>为什么不能用 x86_64 的 RPM 包？<a href="#为什么不能用-x86_64-的-rpm-包"><span>#</span></a></h3><p>nginx 官方 CentOS 的 aarch64 rpm 包<strong>不要直接装 ky10</strong>，glibc、openssl 版本不一样，大概率装不上、启动异常。必须用麒麟官方适配的 ky10 版本包。</p></section><section><h3>必下核心包<a href="#必下核心包"><span>#</span></a></h3><p>以下三个包版本号必须<strong>完全一致</strong>（都是 <code>p12</code>），不能混用不同补丁版本：</p>

<table><thead><tr><th>包名</th><th>架构</th><th>说明</th></tr></thead><tbody><tr><td><code>nginx-1.21.5-5.p12.ky10.aarch64.rpm</code></td><td>aarch64</td><td>主程序，必选</td></tr><tr><td><code>nginx-filesystem-1.21.5-5.p12.ky10.noarch.rpm</code></td><td>noarch</td><td>目录、配置文件结构，必选</td></tr><tr><td><code>nginx-all-modules-1.21.5-5.p12.ky10.noarch.rpm</code></td><td>noarch</td><td>全套模块（stream、ssl、http2 等），生产推荐带上</td></tr></tbody></table><p>可选（非必须）：<code>nginx-help-1.21.5-5.p12.ky10.noarch.rpm</code> 帮助文档，服务器可以不下载。</p></section><section><h3>常见报错：依赖缺失<a href="#常见报错依赖缺失"><span>#</span></a></h3><p>直接执行以下命令会报依赖错误：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>rpm</span><span> </span><span>-ivh</span><span> </span><span>nginx-filesystem-1.21.5-5.p12.ky10.noarch.rpm</span><span> </span><span>nginx-1.21.5-5.p12.ky10.aarch64.rpm</span><span> </span><span>nginx-all-modules-1.21.5-5.p12.ky10.noarch.rpm</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>错误信息：</p><ul>
<li><code>libprofiler.so.0()</code> 被 nginx 需要</li>
<li><code>nginx-mod-http-image-filter</code>、<code>nginx-mod-http-perl</code>、<code>nginx-mod-http-xslt-filter</code>、<code>nginx-mod-mail</code>、<code>nginx-mod-stream</code> 被 nginx-all-modules 需要</li>
</ul></blockquote><p><strong>报错原因</strong>：<code>nginx-all-modules</code> 是元包，依赖所有单独模块包；还缺 <code>libprofiler.so.0</code> 这个系统依赖包（来自 <code>gperftools-libs</code>）。</p></section><section><h3>解决方案<a href="#解决方案"><span>#</span></a></h3><section><h4>方案 A：一次性装所有 RPM（本地包齐全时）<a href="#方案-a一次性装所有-rpm本地包齐全时"><span>#</span></a></h4><p>把目录里所有 nginx 相关 RPM 一次性装进去：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>rpm</span><span> </span><span>-ivh</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>  </span><span>nginx-filesystem-1.21.5-5.p12.ky10.noarch.rpm</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>nginx-1.21.5-5.p12.ky10.aarch64.rpm</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>nginx-all-modules-1.21.5-5.p12.ky10.noarch.rpm</span><span> </span><span>\</span></div></div><div><div><div>5</div></div><div><span>  </span><span>nginx-mod-http-image-filter-1.21.5-5.p12.ky10.aarch64.rpm</span><span> </span><span>\</span></div></div><div><div><div>6</div></div><div><span>  </span><span>nginx-mod-http-perl-1.21.5-5.p12.ky10.aarch64.rpm</span><span> </span><span>\</span></div></div><div><div><div>7</div></div><div><span>  </span><span>nginx-mod-http-xslt-filter-1.21.5-5.p12.ky10.aarch64.rpm</span><span> </span><span>\</span></div></div><div><div><div>8</div></div><div><span>  </span><span>nginx-mod-mail-1.21.5-5.p12.ky10.aarch64.rpm</span><span> </span><span>\</span></div></div><div><div><div>9</div></div><div><span>  </span><span>nginx-mod-stream-1.21.5-5.p12.ky10.aarch64.rpm</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>执行完上面这条，如果还报 <code>libprofiler.so.0</code> 缺失，需要额外安装 <code>gperftools-libs</code>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 去麒麟官方更新站下载</span></div></div><div><div><div>2</div></div><div><span>https://update.cs2c.com.cn/NS/V10/V10SP3-2403/os/adv/lic/updates/aarch64/Packages/gperftools-libs-*.ky10.aarch64.rpm</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 安装</span></div></div><div><div><div>5</div></div><div><span>rpm</span><span> </span><span>-ivh</span><span> </span><span>gperftools-libs-</span><span>*</span><span>.rpm</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>方案 B：精简安装（不装 all-modules，按需装模块）<a href="#方案-b精简安装不装-all-modules按需装模块"><span>#</span></a></h4><p>如果不需要全套模块，<strong>不要安装 <code>nginx-all-modules</code></strong>，只装主程序 + filesystem + 需要的模块（大多数场景只需要 stream）：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 只装基础 nginx + stream 模块（常用 TCP 反向代理）</span></div></div><div><div><div>2</div></div><div><span>rpm</span><span> </span><span>-ivh</span><span> </span><span>\</span></div></div><div><div><div>3</div></div><div><span>  </span><span>nginx-filesystem-1.21.5-5.p12.ky10.noarch.rpm</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>  </span><span>nginx-1.21.5-5.p12.ky10.aarch64.rpm</span><span> </span><span>\</span></div></div><div><div><div>5</div></div><div><span>  </span><span>nginx-mod-stream-1.21.5-5.p12.ky10.aarch64.rpm</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>⚠️ <code>libprofiler.so.0</code> 这个依赖是 nginx 主包本身的依赖，不是模块带来的，绕不开，仍需提前下好 <code>gperftools-libs</code>。</p></blockquote></section><section><h4>方案 C：本地 yum 自动解决依赖（机器可连外网时）<a href="#方案-c本地-yum-自动解决依赖机器可连外网时"><span>#</span></a></h4><p>把当前目录作为 yum 本地源，自动处理依赖：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 先创建仓库元数据</span></div></div><div><div><div>2</div></div><div><span>createrepo</span><span> </span><span>.</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 使用本地源安装</span></div></div><div><div><div>5</div></div><div><span>yum</span><span> </span><span>localinstall</span><span> </span><span>*</span><span>.rpm</span><span> </span><span>-y</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>前提：机器能访问麒麟在线源，yum 会自动拉取缺失的 <code>gperftools-libs</code>。纯断网离线环境不行，必须提前下好。</p></blockquote></section></section><section><h3>安装包下载地址<a href="#安装包下载地址"><span>#</span></a></h3><p>银河麒麟官方更新站（V10 SP3 aarch64）：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://update.cs2c.com.cn/NS/V10/V10SP3-2403/os/adv/lic/updates/aarch64/Packages/</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在该目录下搜索 <code>nginx</code>，下载所需 RPM 包。</p><hr /></section></section>
<section><h2>安装后配置与验证<a href="#安装后配置与验证"><span>#</span></a></h2><section><h3>1. 查看版本，确认识别成功<a href="#1-查看版本确认识别成功"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>nginx</span><span> </span><span>-v</span><span>        </span><span># 只看版本</span></div></div><div><div><div>2</div></div><div><span>nginx</span><span> </span><span>-V</span><span>        </span><span># 看编译参数、已加载的模块（检查 stream 等模块是否在）</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>2. 查看 nginx 服务状态 &amp; 启停<a href="#2-查看-nginx-服务状态--启停"><span>#</span></a></h3><p>麒麟 V10 由 systemd 管理：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 查看状态</span></div></div><div><div><div>2</div></div><div><span>systemctl</span><span> </span><span>status</span><span> </span><span>nginx</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 启动</span></div></div><div><div><div>5</div></div><div><span>systemctl</span><span> </span><span>start</span><span> </span><span>nginx</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 设置开机自启（生产必做）</span></div></div><div><div><div>8</div></div><div><span>systemctl</span><span> </span><span>enable</span><span> </span><span>nginx</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 重启（后续改配置用）</span></div></div><div><div><div>11</div></div><div><span>systemctl</span><span> </span><span>restart</span><span> </span><span>nginx</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># 重载配置（不中断业务，改完配置优先用这个）</span></div></div><div><div><div>14</div></div><div><span>systemctl</span><span> </span><span>reload</span><span> </span><span>nginx</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>3. 检查配置文件语法（改配置前一定要跑）<a href="#3-检查配置文件语法改配置前一定要跑"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>nginx</span><span> </span><span>-t</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>输出 <code>test is successful</code> 且显示 <code>/etc/nginx/nginx.conf</code>、<code>/etc/nginx/conf.d/</code> 路径即正常。</p></section><section><h3>4. 本地访问测试<a href="#4-本地访问测试"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>curl</span><span> </span><span>127.0.0.1</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>能返回 nginx 默认欢迎页面 html，说明 web 服务正常。</p></section><section><h3>5. 防火墙放行（外部访问需要）<a href="#5-防火墙放行外部访问需要"><span>#</span></a></h3><p>银河麒麟 V10 默认 firewalld：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 放行 80 端口</span></div></div><div><div><div>2</div></div><div><span>firewall-cmd</span><span> </span><span>--add-service=http</span><span> </span><span>--permanent</span></div></div><div><div><div>3</div></div><div><span>firewall-cmd</span><span> </span><span>--reload</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># HTTPS 443 端口</span></div></div><div><div><div>6</div></div><div><span>firewall-cmd</span><span> </span><span>--add-service=https</span><span> </span><span>--permanent</span><span> &amp;&amp; </span><span>firewall-cmd</span><span> </span><span>--reload</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>6. 常用目录备忘<a href="#6-常用目录备忘"><span>#</span></a></h3>

<table><thead><tr><th>用途</th><th>路径</th></tr></thead><tbody><tr><td>配置文件</td><td><code>/etc/nginx/</code></td></tr><tr><td>网页根目录</td><td><code>/usr/share/nginx/html/</code></td></tr><tr><td>日志文件</td><td><code>/var/log/nginx/</code>（access.log、error.log）</td></tr><tr><td>pid 文件</td><td><code>/run/nginx.pid</code></td></tr></tbody></table></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/7a6abf49/</id>
      <title type="text">【Linux】Redis 离线安装</title>
      <published>2024-06-16T08:31:13.000Z</published>
      <updated>2024-06-16T08:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/7a6abf49/"/>
      <summary type="text">在Linux环境下离线安装Redis的全过程。文章首先提供了Redis的下载链接及解压步骤，接着详细描述了编译和安装Redis的方法，包括解决编译过程中可能遇到的问题。随后，文章介绍了如何启动Redis服务，如何设置Redis的开机自启动，这些内容对离线环境下的Redis安装和管理非常有帮助。</summary>
      <content type="html"><![CDATA[<section><h2>下载并解压Redis<a href="#下载并解压redis"><span>#</span></a></h2><section><h3>执行下面的命令下载redis：<a href="#执行下面的命令下载redis"><span>#</span></a></h3><blockquote><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>wget https://download.redis.io/releases/redis-6.2.6.tar.gz</span></div></div></code></pre><div><div></div><div></div></div></figure></div></blockquote></section><section><h3>解压redis：<a href="#解压redis"><span>#</span></a></h3><blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>tar</span><span> </span><span>xzf</span><span> </span><span>redis-6.2.6.tar.gz</span></div></div></code></pre><div><div></div><div></div></div></figure></div></blockquote></section><section><h3>移动redis目录，一般都会将redis目录放置到 /usr/local/redis目录：<a href="#移动redis目录一般都会将redis目录放置到-usrlocalredis目录"><span>#</span></a></h3><blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>mv</span><span> </span><span>redis-6.2.6</span><span> </span><span>/usr/local/redis</span></div></div></code></pre><div><div></div><div></div></div></figure></div></blockquote></section></section>
<section><h2>编译并安装redis<a href="#编译并安装redis"><span>#</span></a></h2><section><h3>进入redis安装目录，执行make命令编译redis：<a href="#进入redis安装目录执行make命令编译redis"><span>#</span></a></h3><blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/usr/local/redis</span></div></div><div><div><div>2</div></div><div><span>make</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>等待make命令执行完成即可。</p><p>如果执行make命令报错：cc 未找到命令，原因是虚拟机系统中缺少gcc，执行下面命令安装gcc：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>yum</span><span> </span><span>-y</span><span> </span><span>install</span><span> </span><span>gcc</span><span> </span><span>automake</span><span> </span><span>autoconf</span><span> </span><span>libtool</span><span> </span><span>make</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果执行make命令报错：致命错误/jemalloc.h: 没有那个文件或目录，则需要在make指定分配器为libc。执行下面命令即可正常编译：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>make</span><span> </span><span>MALLOC=libc</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>make命令执行完，redis就编译完成了。</p></blockquote></section><section><h3>执行下面命令安装redis，并指定安装目录<a href="#执行下面命令安装redis并指定安装目录"><span>#</span></a></h3><blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>make</span><span> </span><span>install</span><span> </span><span>PREFIX=/usr/local/redis</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/0617144541fff.png" alt="image-20240617144514525" /><figcaption>image-20240617144514525</figcaption></figure><p></p><p>至此，redis即安装成功。</p></blockquote></section><section><h3>启动redis<a href="#启动redis"><span>#</span></a></h3></section><section><h3>进入redis安装目录，执行下面命令启动redis服务<a href="#进入redis安装目录执行下面命令启动redis服务"><span>#</span></a></h3><blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 启动</span></div></div><div><div><div>2</div></div><div><span>./bin/redis-server</span><span> </span><span>redis.conf</span></div></div><div><div><div>3</div></div><div><span># 关闭</span></div></div><div><div><div>4</div></div><div><span>./bin/redis-cli</span><span> </span><span>shutdown</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>此时，可以看到redis服务被成功启动：</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/0617144725fff.png" alt="image-20240617144725136" /><figcaption>image-20240617144725136</figcaption></figure><p></p><p>但这种启动方式不能退出控制台，如果退出，那么redis服务也会停止。如果想要redis以后台方式运行，需要修改redis的配置文件：<code>redis.conf</code>。将该配置文件中的<code>daemonize no</code>改为<code>daemonize yes</code>即可：</p><p>修改完成后，重新执行启动命令启动redis，然后通过下面命令查看redis进程，可以发现redis服务已经被启动了：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ps</span><span> </span><span>-ef</span><span> | </span><span>grep</span><span> </span><span>redis</span></div></div></code></pre><div><div></div><div></div></div></figure></div></blockquote></section><section><h3>其他设置<a href="#其他设置"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>daemonize：如需要在后台运行，把该项的值改为yes</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>pdifile：把pid文件放在/var/run/redis.pid，可以配置到其他地址</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>bind：指定redis只接收来自该IP的请求，如果不设置，那么将处理所有请求，在生产环节中最好设置该项</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span><span>            </span></span><span>(设置0.0.0.0 则改为用iptables来控制访问权限)</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>port：监听端口，默认为6379</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>timeout：设置客户端连接时的超时时间，单位为秒</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>loglevel：等级分为4级，debug，revbose，notice和warning。生产环境下一般开启notice</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>logfile：配置log文件地址，默认使用标准输出，即打印在命令行终端的端口上</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>database：设置数据库的个数，默认使用的数据库是0</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>save：设置redis进行数据库镜像的频率</span></div></div><div><div><div>20</div></div><div>
</div></div><div><div><div>21</div></div><div><span>rdbcompression：在进行镜像备份时，是否进行压缩</span></div></div><div><div><div>22</div></div><div>
</div></div><div><div><div>23</div></div><div><span>dbfilename：镜像备份文件的文件名</span></div></div><div><div><div>24</div></div><div>
</div></div><div><div><div>25</div></div><div><span>dir：数据库镜像备份的文件放置的路径</span></div></div><div><div><div>26</div></div><div>
</div></div><div><div><div>27</div></div><div><span>slaveof：设置该数据库为其他数据库的从数据库</span></div></div><div><div><div>28</div></div><div>
</div></div><div><div><div>29</div></div><div><span>masterauth：当主数据库连接需要密码验证时，在这里设定</span></div></div><div><div><div>30</div></div><div>
</div></div><div><div><div>31</div></div><div><span>requirepass：设置客户端连接后进行任何其他指定前需要使用的密码</span></div></div><div><div><div>32</div></div><div>
</div></div><div><div><div>33</div></div><div><span>maxclients：限制同时连接的客户端数量</span></div></div><div><div><div>34</div></div><div>
</div></div><div><div><div>35</div></div><div><span>maxmemory：设置redis能够使用的最大内存</span></div></div><div><div><div>36</div></div><div>
</div></div><div><div><div>37</div></div><div><span>appendonly：开启appendonly模式后，redis会把每一次所接收到的写操作都追加到appendonly.aof文件中，当redis重新启动时，会从该文件恢复出之前的状态</span></div></div><div><div><div>38</div></div><div>
</div></div><div><div><div>39</div></div><div><span>appendfsync：设置appendonly.aof文件进行同步的频率</span></div></div><div><div><div>40</div></div><div>
</div></div><div><div><div>41</div></div><div><span>vm_enabled：是否开启虚拟内存支持</span></div></div><div><div><div>42</div></div><div>
</div></div><div><div><div>43</div></div><div><span>vm_swap_file：设置虚拟内存的交换文件的路径</span></div></div><div><div><div>44</div></div><div>
</div></div><div><div><div>45</div></div><div><span>vm_max_momery：设置开启虚拟内存后，redis将使用的最大物理内存的大小，默认为0</span></div></div><div><div><div>46</div></div><div>
</div></div><div><div><div>47</div></div><div><span>vm_page_size：设置虚拟内存页的大小</span></div></div><div><div><div>48</div></div><div>
</div></div><div><div><div>49</div></div><div><span>vm_pages：设置交换文件的总的page数量</span></div></div><div><div><div>50</div></div><div>
</div></div><div><div><div>51</div></div><div><span>vm_max_thrrads：设置vm IO同时使用的线程数量</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>通过redis-cli测试redis是否可用，在redis安装目录执行下面命令：<a href="#通过redis-cli测试redis是否可用在redis安装目录执行下面命令"><span>#</span></a></h3><blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>./bin/redis-cli</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/0617144907fff.png" alt="image-20240617144907738" /><figcaption>image-20240617144907738</figcaption></figure><p></p></blockquote><p>​</p><p>此处我们通过下面命令随便set一个字符串类型的值，key是test，value是hello：</p><blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>set</span><span> </span><span>test</span><span> </span><span>hello</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/06/17145110.png" alt="image-20240617145110416" /><figcaption>image-20240617145110416</figcaption></figure><p></p></blockquote><p>​</p><p>然后通过下面命令get出test这个key的value值：</p><blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>get</span><span> </span><span>test</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/2024/06/17145127.png" alt="image-20240617145127840" /><figcaption>image-20240617145127840</figcaption></figure><p></p></blockquote><p>​</p><p>测试没有问题，至此，redis在我们的Linux服务器上就已经安装完成了。</p></section></section>
<section><h2>开机自启<a href="#开机自启"><span>#</span></a></h2><blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>vim</span><span> </span><span>/usr/lib/systemd/system/redis.service</span></div></div></code></pre><div><div></div><div></div></div></figure></div></blockquote><blockquote><p><strong>注意：—daemonize no 为必须的，要不然起不来</strong></p></blockquote><blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[Unit]</span></div></div><div><div><div>2</div></div><div><span>Description</span><span> </span><span>=</span><span> </span><span>Redis</span><span> </span><span>Server</span></div></div><div><div><div>3</div></div><div><span>After</span><span> </span><span>=</span><span> </span><span>network.target</span></div></div><div><div><div>4</div></div><div><span>[Service]</span></div></div><div><div><div>5</div></div><div><span>ExecStart</span><span> </span><span>=</span><span> </span><span>/usr/local/redis/bin/redis-server</span><span> </span><span>/usr/local/redis/etc/redis.conf</span><span> </span><span>--daemonize</span><span> </span><span>no</span></div></div><div><div><div>6</div></div><div><span>ExecStop</span><span> </span><span>=</span><span> </span><span>/usr/local/redis/bin/redis-cli</span><span> </span><span>-p</span><span> </span><span>6379</span><span> </span><span>shutdown</span></div></div><div><div><div>7</div></div><div><span>Restart</span><span> </span><span>=</span><span> </span><span>always</span></div></div><div><div><div>8</div></div><div><span>[Install]</span></div></div><div><div><div>9</div></div><div><span>WantedBy</span><span> </span><span>=</span><span> </span><span>multi-user.target</span></div></div></code></pre><div><div></div><div></div></div></figure></div></blockquote><blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 重新加载服务</span></div></div><div><div><div>2</div></div><div><span>systemctl</span><span> </span><span>daemon-reload</span></div></div><div><div><div>3</div></div><div><span># 开机自动启动</span></div></div><div><div><div>4</div></div><div><span>systemctl</span><span> </span><span>enable</span><span> </span><span>redis.service</span></div></div><div><div><div>5</div></div><div><span># 取消开机自动启动(卸载服务)</span></div></div><div><div><div>6</div></div><div><span>systemctl</span><span> </span><span>disabled</span><span> </span><span>redis.service</span></div></div><div><div><div>7</div></div><div><span># 启动redis服务</span></div></div><div><div><div>8</div></div><div><span>systemctl</span><span> </span><span>start</span><span> </span><span>redis.service</span></div></div><div><div><div>9</div></div><div><span># 查看服务状态</span></div></div><div><div><div>10</div></div><div><span>systemctl</span><span> </span><span>status</span><span> </span><span>redis.service</span></div></div><div><div><div>11</div></div><div><span># 停止服务</span></div></div><div><div><div>12</div></div><div><span>systemctl</span><span> </span><span>stop</span><span> </span><span>redis.service</span></div></div></code></pre><div><div></div><div></div></div></figure></div></blockquote><hr /></section>
<section><h2>银河麒麟 V10 SP3 aarch64 离线安装（RPM 方式）<a href="#银河麒麟-v10-sp3-aarch64-离线安装rpm-方式"><span>#</span></a></h2><blockquote><p>适用环境：银河麒麟 V10 SP3 aarch64（ARM 鲲鹏架构），服务器无外网或需国产化验收。</p></blockquote><section><h3>为什么用官方 RPM 而不是源码编译？<a href="#为什么用官方-rpm-而不是源码编译"><span>#</span></a></h3><ul>
<li>麒麟官方 rpm 包自带 systemd 服务、配置文件、路径，开箱即用</li>
<li>源码编译需要手动写 service 文件，配置路径也容易找不到</li>
<li>等保 / 国产化项目验收，优先选官方适配包</li>
</ul></section><section><h3>下载安装包<a href="#下载安装包"><span>#</span></a></h3><p>麒麟官方更新站（V10 SP3 aarch64）：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://update.cs2c.com.cn/NS/V10/V10SP3-2403/os/adv/lic/updates/aarch64/Packages/redis-7.2.10-1.p01.ky10.aarch64.rpm</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>将 <code>redis-7.2.10-1.p01.ky10.aarch64.rpm</code> 传到服务器 <code>/soft</code> 目录。</p></section><section><h3>安装命令<a href="#安装命令"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/soft</span></div></div><div><div><div>2</div></div><div><span>rpm</span><span> </span><span>-ivh</span><span> </span><span>redis-7.2.10-1.p01.ky10.aarch64.rpm</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>如果报依赖缺失：</p><ul>
<li>能联网：<code>yum localinstall redis-7.2.10-1.p01.ky10.aarch64.rpm</code> 自动拉取依赖</li>
<li>纯断网：去同一个 Packages 目录下载提示缺少的依赖包</li>
</ul></blockquote></section><section><h3>安装完成后操作<a href="#安装完成后操作"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 查看版本</span></div></div><div><div><div>2</div></div><div><span>redis-cli</span><span> </span><span>--version</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 查看状态</span></div></div><div><div><div>5</div></div><div><span>systemctl</span><span> </span><span>status</span><span> </span><span>redis</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 启动 + 开机自启（生产必执行）</span></div></div><div><div><div>8</div></div><div><span>systemctl</span><span> </span><span>start</span><span> </span><span>redis</span></div></div><div><div><div>9</div></div><div><span>systemctl</span><span> </span><span>enable</span><span> </span><span>redis</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span># 重启 / 重载配置</span></div></div><div><div><div>12</div></div><div><span>systemctl</span><span> </span><span>restart</span><span> </span><span>redis</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>默认路径（重要）<a href="#默认路径重要"><span>#</span></a></h3>

<table><thead><tr><th>用途</th><th>路径</th></tr></thead><tbody><tr><td>配置文件</td><td><code>/etc/redis/redis.conf</code>（部分版本在 <code>/etc/redis.conf</code>）</td></tr><tr><td>数据 rdb</td><td><code>/var/lib/redis/</code></td></tr><tr><td>日志</td><td><code>/var/log/redis/redis.log</code></td></tr><tr><td>默认端口</td><td>6379，默认只允许 <code>127.0.0.1</code> 本地访问</td></tr></tbody></table></section><section><h3>基础安全配置（必改）<a href="#基础安全配置必改"><span>#</span></a></h3><p>编辑配置文件：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>vi</span><span> </span><span>/etc/redis/redis.conf</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>修改以下几项：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 注释掉 bind（需要外部连接才开，内网环境建议放开）</span></div></div><div><div><div>2</div></div><div><span># bind 127.0.0.1</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 关闭保护模式（内网环境才关！公网不要关）</span></div></div><div><div><div>5</div></div><div><span>protected-mode no</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 设置密码（推荐）</span></div></div><div><div><div>8</div></div><div><span>requirepass 你的强密码</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>改完重启：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>systemctl</span><span> </span><span>restart</span><span> </span><span>redis</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>防火墙放行（其他机器需要访问 6379 时才执行）<a href="#防火墙放行其他机器需要访问-6379-时才执行"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>firewall-cmd</span><span> </span><span>--add-port=6379/tcp</span><span> </span><span>--permanent</span></div></div><div><div><div>2</div></div><div><span>firewall-cmd</span><span> </span><span>--reload</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>连接测试<a href="#连接测试"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 本地连接</span></div></div><div><div><div>2</div></div><div><span>redis-cli</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 如果设置了密码</span></div></div><div><div><div>5</div></div><div><span>redis-cli</span><span> </span><span>-a</span><span> </span><span>你的密码</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 测试写入读取</span></div></div><div><div><div>8</div></div><div><span>set</span><span> </span><span>name</span><span> </span><span>wangbin</span></div></div><div><div><div>9</div></div><div><span>get</span><span> </span><span>name</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section>
<section><h2>常见报错：E212 Can’t open file for writing<a href="#常见报错e212-cant-open-file-for-writing"><span>#</span></a></h2><p>编辑 <code>redis.conf</code> 时遇到 <code>E212: Can't open file for writing</code>，最常见原因有两个：</p><section><h3>原因一：配置文件路径不对<a href="#原因一配置文件路径不对"><span>#</span></a></h3><p>麒麟 V10 官方 redis rpm 包有两种打包形式，配置文件路径可能不同：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 先执行这条确认文件位置</span></div></div><div><div><div>2</div></div><div><span>find</span><span> </span><span>/etc</span><span> </span><span>-name</span><span> </span><span>"*redis*.conf"</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<table><thead><tr><th>路径</th><th>来源</th></tr></thead><tbody><tr><td><code>/etc/redis/redis.conf</code></td><td>源码安装习惯路径</td></tr><tr><td><code>/etc/redis.conf</code></td><td>麒麟官方 rpm 包常见路径</td></tr></tbody></table><p>如果 <code>find</code> 查到的是 <code>/etc/redis.conf</code>，直接编辑这个：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>vi</span><span> </span><span>/etc/redis.conf</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>原因二：文件不存在<a href="#原因二文件不存在"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 确认 redis 是否安装</span></div></div><div><div><div>2</div></div><div><span>rpm</span><span> </span><span>-qa</span><span> | </span><span>grep</span><span> </span><span>redis</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 查看 systemd 服务文件，确认它读取哪个配置</span></div></div><div><div><div>5</div></div><div><span>cat</span><span> </span><span>/usr/lib/systemd/system/redis.service</span><span> | </span><span>grep</span><span> </span><span>ExecStart</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>正常会看到类似 <code>ExecStart=/usr/bin/redis-server /etc/redis.conf</code>，以这个路径为准。</p></section><section><h3>额外排查：文件被锁定<a href="#额外排查文件被锁定"><span>#</span></a></h3><p>如果文件存在但还报 E212，检查是否有 immutable 属性：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>lsattr</span><span> </span><span>/etc/redis.conf</span></div></div><div><div><div>2</div></div><div><span># 如果有 i 属性，执行</span></div></div><div><div><div>3</div></div><div><span>chattr</span><span> </span><span>-i</span><span> </span><span>/etc/redis.conf</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section>
<section><h2>源码编译安装（想要更高版本 / 自定义参数）<a href="#源码编译安装想要更高版本--自定义参数"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 安装编译依赖</span></div></div><div><div><div>2</div></div><div><span>yum</span><span> </span><span>install</span><span> </span><span>gcc</span><span> </span><span>gcc-c++</span><span> </span><span>make</span><span> </span><span>-y</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 下载并编译</span></div></div><div><div><div>5</div></div><div><span>wget</span><span> </span><span>https://download.redis.io/releases/redis-7.4.1.tar.gz</span></div></div><div><div><div>6</div></div><div><span>tar</span><span> </span><span>xf</span><span> </span><span>redis-7.4.1.tar.gz</span></div></div><div><div><div>7</div></div><div><span>cd</span><span> </span><span>redis-7.4.1</span></div></div><div><div><div>8</div></div><div><span>make</span></div></div><div><div><div>9</div></div><div><span>make</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>源码方式不会自动生成 systemd 服务文件和配置文件，需要自己写。等保 / 国产化验收优先选麒麟官方 RPM 包。</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/dfef5267/</id>
      <title type="text">【Linux】Nacos 问题</title>
      <published>2024-06-16T08:31:13.000Z</published>
      <updated>2024-06-16T08:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/dfef5267/"/>
      <summary type="text">本文《【Linux】Nacos 问题》详细记录了在Linux环境下遇到的Nacos服务连接问题及其解决方法。文章还介绍了如何配置Nacos服务的开机自启动，确保服务在系统重启后能够自动运行。这些内容对解决Nacos连接问题和提高系统稳定性非常有帮助。</summary>
      <content type="html"><![CDATA[<section><h2>启动 jar 连接不上Nacos服务<a href="#启动-jar-连接不上nacos服务"><span>#</span></a></h2><section><h3>前置条件<a href="#前置条件"><span>#</span></a></h3><ul>
<li>Nacos 版本 2.0.3</li>
<li>Nacos 服务没问题，后台页面可以打开</li>
<li>Nacos所在服务器8848/9848/9849/端口都开放，或者防火墙已经关闭</li>
<li>启动相同的jar有的服务器有问题，有的没问题</li>
</ul></section><section><h3>启动jar 报错<a href="#启动jar-报错"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>20:39:30.692</span><span> [main] INFO  c.a.n.c.r.client - [printIfInfoEnabled,60] - [2d2b5901-f6f8-414e-850c-1a92807e9f25_config-0] Try to connect to server on start up, server: {</span><span>serverIp</span><span> </span><span>=</span><span> </span><span>'192.168.x.x',</span><span> </span><span>server</span><span> </span><span>main</span><span> </span><span>port</span><span> </span><span>=</span><span> </span><span>8848</span><span>}</span></div></div><div><div><div>2</div></div><div><span>20:39:33.695</span><span> [main] ERROR c.a.n.c.r.c.g.GrpcClient - [printIfErrorEnabled,99] - Server check fail, please check server 192.168.166.51 ,port 9848 is available , error ={}</span></div></div><div><div><div>3</div></div><div><span>java.util.concurrent.TimeoutException:</span><span> </span><span>Waited</span><span> </span><span>3000</span><span> </span><span>milliseconds</span><span> (plus </span><span>65041</span><span> </span><span>nanoseconds</span><span> </span><span>delay</span><span>) </span><span>for</span><span> com.alibaba.nacos.shaded.io.grpc.stub.ClientCalls</span><span>$GrpcFuture</span><span><span>@77114efe[status</span><span>=</span><span>PENDING, info</span><span>=</span><span>[GrpcFuture{clientCall</span><span>=</span><span>{delegate</span><span>=</span><span>{delegate</span><span>=</span><span>ClientCallImpl{method</span><span>=</span><span>MethodDescriptor{fullMethodName</span><span>=</span><span>Request/request, type</span><span>=</span><span>UNARY, idempotent</span><span>=</span></span><span>false</span><span><span>, safe</span><span>=</span></span><span>false</span><span><span>, sampledToLocalTracing</span><span>=</span></span><span>true</span><span><span>, requestMarshaller</span><span>=</span><span>com.alibaba.nacos.shaded.io.grpc.protobuf.lite.ProtoLiteUtils</span></span><span>$MessageMarshaller</span><span><span>@77681ce4, responseMarshaller</span><span>=</span><span>com.alibaba.nacos.shaded.io.grpc.protobuf.lite.ProtoLiteUtils</span></span><span>$MessageMarshaller</span><span><span>@5d96bdf8, schemaDescriptor</span><span>=</span><span>com.alibaba.nacos.api.grpc.auto.RequestGrpc</span></span><span>$RequestMethodDescriptorSupplier</span><span>@6f76c2cc}}}}}]]</span></div></div><div><div><div>4</div></div><div><span>    </span><span>at</span><span> </span><span>com.alibaba.nacos.shaded.com.google.common.util.concurrent.AbstractFuture.get</span><span>(</span><span>AbstractFuture.java:508</span><span>)</span></div></div><div><div><div>5</div></div><div><span>    </span><span>at</span><span> </span><span>com.alibaba.nacos.common.remote.client.grpc.GrpcClient.serverCheck</span><span>(</span><span>GrpcClient.java:148</span><span>)</span></div></div><div><div><div>6</div></div><div><span>    </span><span>at</span><span> </span><span>com.alibaba.nacos.common.remote.client.grpc.GrpcClient.connectToServer</span><span>(</span><span>GrpcClient.java:264</span><span>)</span></div></div><div><div><div>7</div></div><div><span>    </span><span>at</span><span> </span><span>com.alibaba.nacos.common.remote.client.RpcClient.start</span><span>(</span><span>RpcClient.java:390</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>原因解析<a href="#原因解析"><span>#</span></a></h3><blockquote><p>大概是linux 服务器 执行 hostname -i 反应慢，nacos服务中应该有获取本地ip地方，本质是执行hostname -i ，然后 导致 nacos client执行server 检查的时候超时，这个超时时间源码中是写死的3000毫秒，所以导致服务启动不起来</p></blockquote></section><section><h3>解决办法<a href="#解决办法"><span>#</span></a></h3><blockquote><p>查看连接不了机器的hostnameg跟对应的ip地址</p></blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>127.0.0.1</span><span> </span><span>localhost</span><span> </span><span>host-192-168-166-52</span></div></div><div><div><div>2</div></div><div><span>127.0.0.1</span><span> </span><span>localhost</span><span> </span><span>localhost.localdomain</span><span> </span><span>localhost4</span><span> </span><span>localhost4.localdomain4</span></div></div><div><div><div>3</div></div><div><span>:</span><span>:1</span><span> </span><span>localhost</span><span> </span><span>localhost.localdomain</span><span> </span><span>localhost6</span><span> </span><span>localhost6.localdomain6</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>现在执行</p></blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@host-192-168-166-51 ~]# hostname -i </span><span># 立即返回</span></div></div><div><div><div>2</div></div><div><span>127.0.0.1</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>开机自启<a href="#开机自启"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>vim</span><span> </span><span>/lib/systemd/system/nacos.service</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>#vim /usr/lib/systemd/system/srs.service</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>[Unit]</span></div></div><div><div><div>4</div></div><div><span>Description</span><span>=</span><span>nacos</span></div></div><div><div><div>5</div></div><div><span>After</span><span>=</span><span>network.target</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>[Service]</span></div></div><div><div><div>8</div></div><div><span>Type</span><span>=</span><span>forking</span></div></div><div><div><div>9</div></div><div><span>TimeoutSec</span><span>=</span><span>0</span><span> </span><span>#防止启动超时</span></div></div><div><div><div>10</div></div><div><span>User</span><span>=</span><span>root</span></div></div><div><div><div>11</div></div><div><span>Group</span><span>=</span><span>root</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>ExecStart</span><span>=</span><span>/bin/bash</span><span> </span><span>/home/yunwei/gonggonganquan/soft/nacos/bin/startup.sh</span><span> </span><span>-m</span><span> </span><span>standalone</span></div></div><div><div><div>14</div></div><div><span>ExecReload</span><span>=</span><span>/home/yunwei/gonggonganquan/soft/nacos/bin/shutdown.sh</span></div></div><div><div><div>15</div></div><div><span>ExecStop</span><span>=</span><span>/home/yunwei/gonggonganquan/soft/nacos/bin/shutdown.sh</span></div></div><div><div><div>16</div></div><div><span>Restart</span><span>=</span><span>on-failure</span></div></div><div><div><div>17</div></div><div><span>PrivateTmp</span><span>=</span><span>true</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>[Install]</span></div></div><div><div><div>20</div></div><div><span>WantedBy</span><span>=</span><span>multi-user.target</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>systemctl</span><span> </span><span>daemon-reload</span></div></div><div><div><div>2</div></div><div><span>systemctl</span><span> </span><span>enable</span><span> </span><span>nacos.service</span></div></div><div><div><div>3</div></div><div><span>systemctl</span><span> </span><span>start</span><span> </span><span>nacos.service</span></div></div><div><div><div>4</div></div><div><span>systemctl</span><span> </span><span>status</span><span> </span><span>nacos.service</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/9beaa6c0/</id>
      <title type="text">NET Core 优秀项目和框架精选</title>
      <published>2024-06-12T20:31:13.000Z</published>
      <updated>2024-06-12T20:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/9beaa6c0/"/>
      <summary type="text">帮助开发者发现功能强大、性能优越、创新前沿、简单易用的C#/.NET/.NET Core优秀项目和框架，无论你是寻找灵感、学习新技术、改进代码质量，还是想拓展自己的技术视野，都能为你提供有价值的参考和指导。关注优秀项目和框架精选能让你及时了解C#、.NET和.NET Core领域的最新动态和最佳实践，提高开发效率和质量</summary>
      <content type="html"><![CDATA[<section><h2>C#/.NET/.NET Core优秀项目和框架精选<a href="#cnetnet-core优秀项目和框架精选"><span>#</span></a></h2><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/202406130850957.png" alt="优秀项目和框架精选图" title="优秀项目和框架精选图" /><figcaption>优秀项目和框架精选图</figcaption></figure><p></p></section>
<section><h2>前言<a href="#前言"><span>#</span></a></h2><blockquote><p>注意：排名不分先后，都是十分优秀的开源项目和框架，每周定期更新分享（欢迎关注公众号：<strong>追逐时光者</strong>，第一时间获取每周精选分享资讯🔔）。</p></blockquote><p>帮助开发者发现功能强大、性能优越、创新前沿、简单易用的C#/.NET/.NET Core优秀项目和框架，无论你是寻找灵感、学习新技术、改进代码质量，还是想拓展自己的技术视野，都能为你提供有价值的参考和指导。关注优秀项目和框架精选能让你及时了解C#、.NET和.NET Core领域的最新动态和最佳实践，提高开发效率和质量。坑已挖，欢迎大家踊跃提交PR或者在该<a href="https://github.com/YSGStudyHards/DotNetGuide/issues/5" target="_blank">🏗️C#/.NET/.NET Core优秀项目和框架Issues</a>中留言（<strong>让优秀的项目和框架不被埋没</strong>），我会定期收录、<a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectMonthly.md" target="_blank">公众号推广和分享👀</a>。</p><ul>
<li><a href="https://github.com/trending/c%23?since=daily" target="_blank">📈C# GitHub趋势榜</a></li>
<li><a href="https://github.com/dotNetTreasury" target="_blank">🎁C#/.NET/.NET Core项目宝库组织</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md" target="_blank">🔔C#/.NET/.NET Core优秀项目和框架精选</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/issues/5" target="_blank">🏗️C#/.NET/.NET Core优秀项目和框架Issues</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectMonthly.md" target="_blank">📰C#/.NET/.NET Core优秀项目和框架公众号月刊</a></li>
</ul></section>
<section><h2>项目分类(善用Ctrl+F)<a href="#项目分类善用ctrlf"><span>#</span></a></h2><ul>
<li>
<p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%BC%80%E6%BA%90%E6%A1%86%E6%9E%B6" target="_blank">开源框架</a></p>
<ul>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#web%E5%BA%94%E7%94%A8%E6%A1%86%E6%9E%B6" target="_blank">Web应用框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E6%A1%8C%E9%9D%A2%E5%BA%94%E7%94%A8%E6%A1%86%E6%9E%B6" target="_blank">桌面应用框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E8%B7%A8%E5%B9%B3%E5%8F%B0%E5%BA%94%E7%94%A8%E6%A1%86%E6%9E%B6" target="_blank">跨平台应用框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%88%86%E5%B8%83%E5%BC%8F%E6%A1%86%E6%9E%B6" target="_blank">分布式框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%A1%86%E6%9E%B6" target="_blank">微服务框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net-orm%E6%A1%86%E6%9E%B6" target="_blank">.NET ORM框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E7%BD%91%E7%BB%9C%E9%80%9A%E4%BF%A1%E6%A1%86%E6%9E%B6" target="_blank">网络通信框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E7%B3%BB%E7%BB%9F%E6%97%A5%E5%BF%97%E6%A1%86%E6%9E%B6" target="_blank">系统日志框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#ai%E5%92%8Cllm%E6%A1%86%E6%9E%B6" target="_blank">AI和LLM框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E6%A1%86%E6%9E%B6" target="_blank">深度学习框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95%E6%A1%86%E6%9E%B6" target="_blank">单元测试框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E7%A8%8B%E5%BA%8F%E9%99%90%E6%B5%81%E6%A1%86%E6%9E%B6" target="_blank">程序限流框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%B7%A5%E4%BD%9C%E6%B5%81%E5%BC%95%E6%93%8E%E6%A1%86%E6%9E%B6" target="_blank">工作流引擎框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E8%BA%AB%E4%BB%BD%E8%AE%A4%E8%AF%81%E6%8E%88%E6%9D%83%E6%A1%86%E6%9E%B6" target="_blank">身份认证授权框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%E6%A1%86%E6%9E%B6" target="_blank">反向代理框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#api-%E7%BD%91%E5%85%B3%E6%A1%86%E6%9E%B6" target="_blank">API 网关框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB%E6%A1%86%E6%9E%B6" target="_blank">网络爬虫框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E6%A1%86%E6%9E%B6" target="_blank">内网穿透框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%E6%A1%86%E6%9E%B6" target="_blank">依赖注入框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%BC%80%E6%BA%90%E7%BC%93%E5%AD%98%E6%A1%86%E6%9E%B6" target="_blank">开源缓存框架</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%85%B6%E4%BB%96%E5%BC%80%E6%BA%90%E6%A1%86%E6%9E%B6" target="_blank">其他开源框架</a></li>
</ul>
</li>
<li>
<p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE" target="_blank">开源项目</a></p>
<ul>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%90%8E%E5%8F%B0%E6%9D%83%E9%99%90%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9Fadminrbacworkflow" target="_blank">后台&amp;权限&amp;工作流管理系统</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%95%86%E5%9F%8E%E9%A1%B9%E7%9B%AE%E7%B3%BB%E7%BB%9Fshop" target="_blank">商城项目系统（Shop）</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E4%BB%93%E5%BA%93%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9Fwms" target="_blank">仓库管理系统（WMS）</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%88%B6%E9%80%A0%E6%89%A7%E8%A1%8C%E7%B3%BB%E7%BB%9Fmes" target="_blank">制造执行系统（MES）</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%86%85%E5%AE%B9%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9Fcms" target="_blank">内容管理系统（CMS）</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%AE%A2%E6%88%B7%E5%85%B3%E7%B3%BB%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9Fcrm" target="_blank">客户关系管理系统（CRM）</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E4%BC%81%E4%B8%9A%E8%B5%84%E6%BA%90%E8%AE%A1%E5%88%92%E7%B3%BB%E7%BB%9Ferp" target="_blank">企业资源计划系统（ERP）</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%8D%B3%E6%97%B6%E9%80%9A%E8%AE%AF%E7%B3%BB%E7%BB%9Fim" target="_blank">即时通讯系统（IM）</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%85%8D%E7%BD%AE%E4%B8%AD%E5%BF%83%E7%B3%BB%E7%BB%9Fccs" target="_blank">配置中心系统（CCS）</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E4%BB%BB%E5%8A%A1%E8%B0%83%E5%BA%A6%E7%B3%BB%E7%BB%9Fscheduler" target="_blank">任务调度系统（Scheduler）</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88" target="_blank">分布式事务解决方案</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%8D%9A%E5%AE%A2%E7%B3%BB%E7%BB%9Fblog" target="_blank">博客系统（Blog）</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%8A%9E%E5%85%AC%E7%B3%BB%E7%BB%9Foa" target="_blank">办公系统（OA）</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%AA%92%E4%BD%93%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%B3%BB%E7%BB%9Fmedia" target="_blank">媒体服务器系统（Media）</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E8%87%AA%E5%8A%A8%E5%8C%96%E6%9E%84%E5%BB%BA%E7%B3%BB%E7%BB%9F" target="_blank">自动化构建系统</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E4%BB%BB%E5%8A%A1%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F" target="_blank">任务管理系统</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E8%BF%9B%E9%94%80%E5%AD%98%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F" target="_blank">进销存管理系统</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%9C%A8%E7%BA%BF%E8%80%83%E8%AF%95%E7%B3%BB%E7%BB%9F" target="_blank">在线考试系统</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%A4%A7%E5%B1%8F%E5%B9%95%E6%8A%A5%E8%A1%A8%E7%B3%BB%E7%BB%9F" target="_blank">大屏幕&amp;报表系统</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E6%96%87%E6%A1%A3%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F" target="_blank">文档管理系统</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E8%AE%BF%E5%AE%A2%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F" target="_blank">访客管理系统</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%8C%BB%E7%96%97%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F" target="_blank">医疗管理系统</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E6%95%B0%E6%8D%AE%E5%BA%93%E7%B3%BB%E7%BB%9F" target="_blank">数据库系统</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%85%B6%E4%BB%96%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE" target="_blank">其他开源项目</a></li>
</ul>
</li>
<li>
<p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7%E8%BD%AF%E4%BB%B6" target="_blank">实用工具&amp;软件</a></p>
<ul>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E6%A1%8C%E9%9D%A2%E5%B7%A5%E5%85%B7%E7%AE%B1" target="_blank">桌面工具箱</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E6%A1%8C%E9%9D%A2%E5%90%AF%E5%8A%A8%E5%99%A8" target="_blank">桌面启动器</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%8F%8D%E7%BC%96%E8%AF%91%E5%B7%A5%E5%85%B7" target="_blank">反编译工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E4%BB%A3%E7%A0%81%E6%B7%B7%E6%B7%86%E5%B7%A5%E5%85%B7" target="_blank">代码混淆工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E6%A1%8C%E9%9D%A2%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7" target="_blank">桌面管理工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7" target="_blank">文件管理工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E8%BF%9C%E7%A8%8B%E6%A1%8C%E9%9D%A2%E5%B7%A5%E5%85%B7" target="_blank">远程桌面工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E6%95%B0%E6%8D%AE%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7" target="_blank">数据管理工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%AE%9E%E7%94%A8%E6%A1%8C%E9%9D%A2%E5%B7%A5%E5%85%B7" target="_blank">实用桌面工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#dns%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%B7%A5%E5%85%B7" target="_blank">DNS服务器工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E6%88%AA%E5%9B%BE%E5%BD%95%E5%B1%8F%E5%B7%A5%E5%85%B7" target="_blank">截图&amp;录屏工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#github%E5%8A%A0%E9%80%9F%E5%B7%A5%E5%85%B7" target="_blank">GitHub加速工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E7%B3%BB%E7%BB%9F%E4%BC%98%E5%8C%96%E5%B7%A5%E5%85%B7" target="_blank">系统优化工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E6%80%A7%E8%83%BD%E5%8E%8B%E6%B5%8B%E5%B7%A5%E5%85%B7" target="_blank">性能压测工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90%E5%B7%A5%E5%85%B7" target="_blank">性能分析工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#excel%E8%BD%ACjson%E5%B7%A5%E5%85%B7" target="_blank">Excel转JSON工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%85%8D%E8%B4%B9%E7%9A%84%E6%8A%A2%E7%A5%A8%E8%BD%AF%E4%BB%B6" target="_blank">免费的抢票软件</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#office%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7" target="_blank">Office实用工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#git%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7" target="_blank">Git管理工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%80%9A%E8%AE%AF%E8%B0%83%E8%AF%95%E5%B7%A5%E5%85%B7" target="_blank">通讯调试工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E7%BF%BB%E8%AF%91%E5%B7%A5%E5%85%B7" target="_blank">翻译工具</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%85%B6%E4%BB%96%E5%B7%A5%E5%85%B7%E8%BD%AF%E4%BB%B6" target="_blank">其他工具&amp;软件</a></li>
</ul>
</li>
<li>
<p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%AE%9E%E7%94%A8sdk%E7%B1%BB%E5%BA%93" target="_blank">实用SDK&amp;类库</a></p>
<ul>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#c%E7%89%88%E5%BE%AE%E4%BF%A1sdk" target="_blank">C#版微信SDK</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#c%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7%E7%B1%BB%E5%BA%93" target="_blank">C#实用工具类库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net%E4%BA%BA%E8%84%B8%E8%AF%86%E5%88%AB%E5%BA%93" target="_blank">.NET人脸识别库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#cffmpeg%E5%B0%81%E8%A3%85%E5%BA%93" target="_blank">C#FFmpeg封装库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net%E9%AB%98%E7%B2%BE%E5%BA%A6%E6%95%B0%E5%80%BC%E8%AE%A1%E7%AE%97%E5%BA%93" target="_blank">.NET高精度数值计算库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net%E7%AC%AC%E4%B8%89%E6%96%B9%E7%99%BB%E5%BD%95%E6%95%B4%E5%90%88%E5%BA%93" target="_blank">.NET第三方登录整合库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net-ui%E8%87%AA%E5%8A%A8%E5%8C%96%E5%BA%93" target="_blank">.NET UI自动化库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net%E5%9B%BE%E5%BD%A2%E5%9B%BE%E8%A1%A8%E8%A1%A8%E6%A0%BC%E5%BA%93" target="_blank">.NET图形&amp;图表&amp;表格库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net%E4%BA%8C%E7%BB%B4%E7%A0%81%E7%B1%BB%E5%BA%93" target="_blank">.NET二维码类库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net%E5%8A%A0%E5%AF%86%E8%A7%A3%E5%AF%86%E5%BA%93" target="_blank">.NET加密解密库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net%E6%94%AF%E4%BB%98sdk" target="_blank">.NET支付SDK</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net-office%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C%E5%BA%93" target="_blank">.NET Office文件操作库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net-json%E5%A4%84%E7%90%86%E5%BA%93" target="_blank">.NET JSON处理库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net%E5%AF%B9%E8%B1%A1%E6%98%A0%E5%B0%84%E5%BA%93" target="_blank">.NET对象映射库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net-redis%E5%AE%A2%E6%88%B7%E7%AB%AF%E9%A9%B1%E5%8A%A8%E5%BA%93" target="_blank">.NET Redis客户端驱动库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net%E7%9A%84ocr%E5%B7%A5%E5%85%B7%E7%B1%BB%E5%BA%93" target="_blank">.NET的OCR工具类库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E6%95%8F%E6%84%9F%E8%AF%8D%E6%A3%80%E6%B5%8B%E7%BB%84%E4%BB%B6%E5%BA%93" target="_blank">敏感词检测组件库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#c%E6%8B%BC%E9%9F%B3%E5%AD%97%E6%AF%8D%E8%BD%AC%E5%8C%96%E7%B1%BB%E5%BA%93" target="_blank">C#拼音字母转化类库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net%E6%9E%9A%E4%B8%BE%E5%B7%A5%E5%85%B7%E7%B1%BB%E5%BA%93" target="_blank">.NET枚举工具类库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net%E7%94%B5%E5%AD%90%E9%82%AE%E4%BB%B6%E5%A4%84%E7%90%86%E5%BA%93" target="_blank">.NET电子邮件处理库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net%E4%B8%AD%E6%96%87%E5%88%86%E8%AF%8D%E7%B1%BB%E5%BA%93" target="_blank">.NET中文分词类库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net%E6%A8%A1%E6%8B%9F%E5%BA%93" target="_blank">.NET模拟库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#net%E5%88%86%E5%B8%83%E5%BC%8Fid%E7%94%9F%E6%88%90%E5%BA%93" target="_blank">.NET分布式ID生成库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#efef-core%E6%89%A9%E5%B1%95%E7%B1%BB%E5%BA%93" target="_blank">EF/EF Core扩展类库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%BC%B9%E6%80%A7%E5%92%8C%E7%9E%AC%E6%80%81%E6%95%85%E9%9A%9C%E5%A4%84%E7%90%86%E5%BA%93" target="_blank">弹性和瞬态故障处理库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E5%85%B6%E4%BB%96%E7%AC%AC%E4%B8%89%E6%96%B9sdk%E7%B1%BB%E5%BA%93" target="_blank">其他第三方SDK&amp;类库</a></li>
</ul>
</li>
<li>
<p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E7%95%8C%E9%9D%A2%E6%8E%A7%E4%BB%B6ui%E5%BA%93" target="_blank">界面&amp;控件&amp;UI库</a></p>
<ul>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#blazor-ui%E5%BA%93" target="_blank">Blazor UI库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#wpf-ui%E5%BA%93" target="_blank">WPF UI库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#winform-ui%E5%BA%93" target="_blank">WinForm UI库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#avalonia-ui%E5%BA%93" target="_blank">Avalonia UI库</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#maui-ui%E5%BA%93" target="_blank">MAUI UI库</a></li>
</ul>
</li>
<li>
<p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86%E5%BA%93" target="_blank">程序设计基础知识库</a></p>
<ul>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F" target="_blank">设计模式</a></li>
<li><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95" target="_blank">数据结构与算法</a></li>
</ul>
</li>
</ul></section>
<section><h2>项目列表<a href="#项目列表"><span>#</span></a></h2><section><h3>开源框架<a href="#开源框架"><span>#</span></a></h3><section><h4>Web应用框架<a href="#web应用框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>10</td><td></td><td></td><td></td></tr><tr><td>9</td><td></td><td></td><td></td></tr><tr><td>8</td><td><a href="https://github.com/ServiceStack/ServiceStack" target="_blank">ServiceStack</a></td><td>一个简单、快速、通用且高效的全功能 Web 和 Web 服务框架，其架构经过精心设计，可减少人工复杂性并通过基于消息的设计促进远程服务最佳实践，从而实现最大程度的重用利用集成服务网关创建松散耦合的模块化服务架构。</td><td><a href="https://github.com/ServiceStack/ServiceStack" target="_blank">https://github.com/ServiceStack/ServiceStack</a></td></tr><tr><td>7</td><td><a href="https://github.com/json-api-dotnet/JsonApiDotNetCore" target="_blank">JsonApiDotNetCore</a></td><td>用于使用 ASP.NET 和 Entity Framework Core 构建符合 JSON 的 REST API 的框架。</td><td><a href="https://github.com/json-api-dotnet/JsonApiDotNetCore" target="_blank">https://github.com/json-api-dotnet/JsonApiDotNetCore</a></td></tr><tr><td>6</td><td><a href="https://github.com/FastEndpoints/FastEndpoints" target="_blank">FastEndpoints</a></td><td>适用于 ASP.NET 6 及更高版本的轻量级 REST API 开发框架。</td><td><a href="https://github.com/FastEndpoints/FastEndpoints" target="_blank">https://github.com/FastEndpoints/FastEndpoints</a></td></tr><tr><td>5</td><td><a href="https://github.com/dotnetcore/Util" target="_blank">Util</a></td><td>Util是一个.Net平台下的应用框架，旨在提升中小团队的开发能力，由工具类、分层架构基类、Ui组件，配套代码生成模板，权限等组成。</td><td><a href="https://github.com/dotnetcore/Util" target="_blank">https://github.com/dotnetcore/Util</a></td></tr><tr><td>4</td><td><a href="https://github.com/MonkSoul/Furion" target="_blank">Furion</a></td><td>Furion框架是一个基于ASP.NET Core的快速开发框架。</td><td><a href="https://github.com/MonkSoul/Furion" target="_blank">https://github.com/MonkSoul/Furion</a></td></tr><tr><td>3</td><td><a href="https://github.com/abpframework/abp" target="_blank">ABP Framework</a></td><td>ABP是一个开源应用程序框架,专注于基于ASP.NET Core的Web应用程序开发,但也支持开发其他类型的应用程序。</td><td><a href="https://docs.abp.io/zh-Hans/abp/latest/" target="_blank">https://docs.abp.io/zh-Hans/abp/latest/</a></td></tr><tr><td>2</td><td><a href="https://github.com/masastack/MASA.Framework" target="_blank">MASA Framework</a></td><td>.NET下一代微服务开发框架，提供基于分布式应用运行时Dapr的云原生最佳实践，可以快速实现分布式、微服务、DDD、SaaS等现代应用开发。</td><td><a href="https://github.com/masastack/MASA.Framework" target="_blank">https://github.com/masastack/MASA.Framework</a></td></tr><tr><td>1</td><td><a href="https://github.com/dotnet/aspnetcore" target="_blank">ASP.NET Core</a></td><td>ASP.NET Core是一个开源、跨平台、高性能的 .NET 框架，用于在 Windows、Mac 或 Linux 上构建基于云的现代 Web 应用程序。</td><td><a href="https://github.com/dotnet/aspnetcore" target="_blank">https://github.com/dotnet/aspnetcore</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>桌面应用框架<a href="#桌面应用框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/dotnet/winforms" target="_blank">WinForm（Windows Forms）</a></td><td>WinForm是一个传统的桌面应用程序框架，它基于 Windows 操作系统的原生控件和窗体。通过简单易用的 API，开发者可以快速构建基于窗体的应用程序，并且可以利用多种控件和事件来实现应用程序的功能和交互。</td><td><a href="https://learn.microsoft.com/zh-cn/dotnet/desktop/winforms/get-started/create-app-visual-studio?view=netdesktop-7.0" target="_blank">https://learn.microsoft.com/zh-cn/dotnet/desktop/winforms/get-started/create-app-visual-studio?view=netdesktop-7.0</a></td></tr><tr><td>1</td><td><a href="https://github.com/dotnet/wpf" target="_blank">WPF（Windows Presentation Foundation）</a></td><td>WPF 是一个强大的桌面应用程序框架，用于构建具有丰富用户界面的 Windows 应用。它提供了灵活的布局、数据绑定、样式和模板、动画效果等功能，让开发者可以创建出吸引人且交互性强的应用程序。</td><td><a href="https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/overview/?view=netdesktop-7.0" target="_blank">https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/overview/?view=netdesktop-7.0</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>跨平台应用框架<a href="#跨平台应用框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/AvaloniaUI/Avalonia" target="_blank">Avalonia</a></td><td>Avalonia是一个强大的框架，使开发人员能够使用.NET创建跨平台应用程序。它使用自己的渲染引擎绘制UI控件，确保在Windows、macOS、Linux、Android、iOS和WebAssembly等不同平台上具有一致的外观和行为。这意味着开发人员可以共享他们的UI代码，并在不同的目标平台上保持统一的外观和感觉。</td><td><a href="https://github.com/AvaloniaUI/Avalonia" target="_blank">https://github.com/AvaloniaUI/Avalonia</a></td></tr><tr><td>1</td><td><a href="https://github.com/dotnet/maui" target="_blank">.NET MAUI</a></td><td>.NET MAUI是一个开源、免费（MIT License）的跨平台框架（支持Android、iOS、macOS 和 Windows多平台运行），是 Xamarin.Forms 的进化版，从移动场景扩展到了桌面场景，并从头重新生成了 UI 控件，以提高性能和可扩展性。 如果以前使用过 Xamarin.Forms 来生成跨平台用户界面，那么你会注意到它与 .NET MAUI 有许多相似之处。 但也有一些差异。 通过使用 .NET MAUI，可使用单个项目创建多平台应用，但如果有必要，可以添加特定于平台的源代码和资源。 .NET MAUI 的主要目的之一是使你能够在单个代码库中实现尽可能多的应用逻辑和 UI 布局。</td><td><a href="https://github.com/dotnet/maui" target="_blank">https://github.com/dotnet/maui</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>分布式框架<a href="#分布式框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td><a href="https://github.com/MassTransit/MassTransit" target="_blank">MassTransit</a></td><td>MassTransit 是一个免费的、开源的.NET 分布式应用程序框架。 MassTransit 可以轻松创建利用基于消息的松散耦合异步通信来实现更高可用性、可靠性和可扩展性的应用程序和服务。</td><td><a href="https://github.com/MassTransit/MassTransit" target="_blank">https://github.com/MassTransit/MassTransit</a></td></tr><tr><td>2</td><td><a href="https://github.com/dotnet/orleans" target="_blank">orleans</a></td><td>Orleans 是一个用于构建稳健、可扩展的分布式应用程序的跨平台框架。它是由微软研究院开发的开源项目，旨在简化分布式系统的开发过程（Orleans 提供了一种编程模型，使开发人员可以使用面向对象的方式来构建分布式应用程序）。</td><td><a href="https://github.com/dotnet/orleans" target="_blank">https://github.com/dotnet/orleans</a></td></tr><tr><td>1</td><td><a href="https://github.com/NewLifeX/Stardust" target="_blank">NewLife.Stardust</a></td><td>一款由新生命开发团队开源的.NET轻量级分布式服务框架，星尘是一个轻量级分布式服务框架。它的功能包含配置中心、集群管理、远程自动发布、服务治理、服务自动注册和发现、负载均衡、动态伸缩、故障转移、性能监控。</td><td><a href="https://github.com/NewLifeX/Stardust" target="_blank">https://github.com/NewLifeX/Stardust</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>微服务框架<a href="#微服务框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>10</td><td></td><td></td><td></td></tr><tr><td>9</td><td></td><td></td><td></td></tr><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td></td><td></td><td></td></tr><tr><td>6</td><td><a href="https://github.com/simpleway2016/JMS" target="_blank">JMSFramework</a></td><td>JMSFramework是一个基于.NET的微服务开源框架，它可以快速构建支持分布式事务的微服务。支持服务发现、服务注册、限流、容错和故障转移、负载均衡、双机热备、分布式锁、零代码支持分布式事务等特性。</td><td><a href="https://github.com/simpleway2016/JMS" target="_blank">https://github.com/simpleway2016/JMS</a></td></tr><tr><td>5</td><td><a href="https://github.com/AlphaYu/Adnc" target="_blank">ADNC</a></td><td>ADNC 是一个基于 .NET 平台的分布式/微服务开源框架，采用现代化的架构设计和最佳实践，同时也适用于单体架构系统的开发。它提供了一系列的工具和库，帮助开发人员快速构建和部署微服务应用程序，包括服务注册/发现、配置中心、链路跟踪、负载均衡、熔断、容错、分布式事务、分布式缓存、消息队列、RPC调用(http/grpc)、认证授权、读写分离、日志记录等，同时也提供了完善的文档和示例代码，方便开发人员使用和学习。</td><td><a href="https://github.com/AlphaYu/Adnc" target="_blank">https://github.com/AlphaYu/Adnc</a></td></tr><tr><td>4</td><td><a href="https://github.com/duyanming/Viper" target="_blank">Viper</a></td><td>Viper 是一个基于Anno微服务引擎开发的Dashboard示例项目。Anno 底层通讯采用 grpc、thrift。自带服务发现、调用链追踪、Cron 调度、限流、事件总线等。</td><td><a href="https://github.com/duyanming/Viper" target="_blank">https://github.com/duyanming/Viper</a></td></tr><tr><td>3</td><td><a href="https://gitee.com/linguicheng/Wing" target="_blank">Wing</a></td><td>Wing致力于打造一个功能强大、最接地气的.NET微服务框架，支持.NET Core 3.1+运行平台。支持Consul服务注册与发现，服务间通讯支持http和grpc调用，内置负载均衡器。支持服务策略配置，服务异常降级处理。支持 Saga分布式事务，支持三种恢复策略：向前恢复、向后恢复、先前再后。自带配置中心，服务配置可以在线集中统一管理。支持http/grpc/sql链路追踪APM及耗时分析统计。内置服务网关，支持全局服务策略和个性化服务策略配置。支持RabbitMQ事件总线，自带人性化的Dashboard管理界面。</td><td><a href="https://linguicheng.gitee.io/wing/" target="_blank">https://linguicheng.gitee.io/wing/</a></td></tr><tr><td>2</td><td><a href="https://github.com/fanliang11/surging" target="_blank">Surging</a></td><td>surging 是一个分布式微服务框架,提供高性能RPC远程服务调用，采用Zookeeper、Consul作为surging服务的注册中心，集成了哈希，随机，轮询，压力最小优先作为负载均衡的算法，RPC可以选择采用netty或thrift框架，采用异步非阻塞传输。</td><td><a href="https://github.com/fanliang11/surging" target="_blank">https://github.com/fanliang11/surging</a></td></tr><tr><td>1</td><td><a href="https://github.com/ThreeMammals/Ocelot" target="_blank">Ocelot</a></td><td>Ocelot 是一个 .NET API 网关。该项目面向使用 .NET 运行微服务/面向服务架构的人，他们需要一个统一的入口点进入他们的系统。但是，它适用于任何使用 HTTP 的内容并在 ASP.NET Core 支持的任何平台上运行。</td><td><a href="https://github.com/ThreeMammals/Ocelot" target="_blank">https://github.com/ThreeMammals/Ocelot</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET ORM框架<a href="#net-orm框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>20</td><td></td><td></td><td></td></tr><tr><td>19</td><td></td><td></td><td></td></tr><tr><td>18</td><td></td><td></td><td></td></tr><tr><td>17</td><td></td><td></td><td></td></tr><tr><td>16</td><td><a href="https://github.com/nhibernate/nhibernate-core" target="_blank">nhibernate-core</a></td><td>NHibernate是.NET框架的成熟、开源的对象关系映射工具。它在积极开发中，功能齐全，并已成功应用于数千个项目中。</td><td><a href="https://github.com/nhibernate/nhibernate-core" target="_blank">https://github.com/nhibernate/nhibernate-core</a></td></tr><tr><td>15</td><td><a href="https://github.com/dotnet/efcore" target="_blank">EF/EF Core</a></td><td>Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技术，EF Core 是适用于 .NET 的现代对象数据库映射器。它支持 LINQ 查询、更改跟踪、更新和架构迁移。EF Core 通过提供程序插件 API 与 SQL Server、Azure SQL 数据库、SQLite、Azure Cosmos DB、MySQL、PostgreSQL 和其他数据库一起使用。(微软官方出品)。</td><td><a href="https://learn.microsoft.com/zh-cn/ef/" target="_blank">https://learn.microsoft.com/zh-cn/ef/</a></td></tr><tr><td>14</td><td><a href="https://github.com/sqlkata/querybuilder" target="_blank">querybuilder</a></td><td>SQL 查询构建器，用 c# 编写，帮助您轻松构建复杂的查询，支持 SqlServer、MySql、PostgreSql、Oracle、Sqlite 和 Firebird。</td><td><a href="https://github.com/sqlkata/querybuilder" target="_blank">https://github.com/sqlkata/querybuilder</a></td></tr><tr><td>13</td><td><a href="https://github.com/sdrapkin/SecurityDriven.TinyORM" target="_blank">TinyORM</a></td><td>TinyORM是一个简单、快速且安全的微型.NET ORM。</td><td><a href="https://github.com/sdrapkin/SecurityDriven.TinyORM" target="_blank">https://github.com/sdrapkin/SecurityDriven.TinyORM</a></td></tr><tr><td>12</td><td><a href="https://github.com/cyq1162/cyqdata" target="_blank">cyqdata</a></td><td>cyq.data是一个高性能且功能最强大的orm（支持.NET Core），支持Txt、Xml、Access、Sqlite、Mssql、Mysql、Oracle、Sybase、Postgres、DB2、Redis、MemCache。</td><td><a href="https://github.com/cyq1162/cyqdata" target="_blank">https://github.com/cyq1162/cyqdata</a></td></tr><tr><td>11</td><td><a href="https://github.com/jonwagner/Insight.Database" target="_blank">Insight.Database</a></td><td>Insight.Database是一个用于 .NET 的快速、轻量级的 micro-orm。</td><td><a href="https://github.com/jonwagner/Insight.Database" target="_blank">https://github.com/jonwagner/Insight.Database</a></td></tr><tr><td>10</td><td><a href="https://github.com/praeclarum/sqlite-net" target="_blank">SQLite-net</a></td><td>简单、强大、跨平台的 SQLite 客户端和 .NET 的 ORM。</td><td><a href="https://github.com/praeclarum/sqlite-net" target="_blank">https://github.com/praeclarum/sqlite-net</a></td></tr><tr><td>9</td><td><a href="https://github.com/mikependon/RepoDB" target="_blank">RepoDb</a></td><td>RepoDB是一个开源的.NET ORM库，它弥合了微ORM和完整ORM之间的差距。它帮助您简化在开发过程中何时使用基本操作和高级操作的切换。</td><td><a href="https://github.com/mikependon/RepoDB" target="_blank">https://github.com/mikependon/RepoDB</a></td></tr><tr><td>8</td><td><a href="https://github.com/linq2db/linq2db" target="_blank">linq2db</a></td><td>LINQ to DB 是最快的LINQ数据库访问库，在POCO对象和数据库之间提供了一个简单、轻量、快速且类型安全的层。在架构上，它比 Dapper、Massive 或 PetaPoco 等微 ORM 高出一步，因为您使用 LINQ 表达式，而不是魔术字符串，同时在代码和数据库之间维护一个薄抽象层。您的查询由 C# 编译器检查并允许轻松重构。但是，它不像 LINQ to SQL 或实体框架那么重。没有更改跟踪，因此您必须自己进行管理，但从积极的方面来说，您可以获得更多控制权并更快地访问您的数据。</td><td><a href="https://github.com/linq2db/linq2db" target="_blank">https://github.com/linq2db/linq2db</a></td></tr><tr><td>7</td><td><a href="https://github.com/CollaboratingPlatypus/PetaPoco" target="_blank">PetaPoco</a></td><td>PetaPoco 是一个用于 .NET（4、4.5+、net standard 2.0+）和 Mono 的微型、快速、易于使用的 micro-ORM。由于 PetaPoco 所代表的简单性和易用性，它受到许多人的喜爱。PetaPoco 是首选的微 ORM，也是任何体面的开发人员工具包中必不可少的实用程序。</td><td><a href="https://github.com/CollaboratingPlatypus/PetaPoco" target="_blank">https://github.com/CollaboratingPlatypus/PetaPoco</a></td></tr><tr><td>6</td><td><a href="https://github.com/dotnetcore/SmartSql" target="_blank">SmartSql</a></td><td>SmartSql = C# 中的 MyBatis + .NET Core+ 缓存（内存/Redis）+ R/W 拆分 + PropertyChangedTrack +动态存储库 + InvokeSync + 诊断。SmartSql 借鉴了 MyBatis 的思想，使用 XML 来管理 SQL ，并且提供了若干个筛选器标签来消除代码层面的各种 if/else 的判断分支。SmartSql将管理你的 SQL ，并且通过筛选标签来维护本来你在代码层面的各种条件判断，使你的代码更加优美。</td><td><a href="https://github.com/dotnetcore/SmartSql" target="_blank">https://github.com/dotnetcore/SmartSql</a></td></tr><tr><td>5</td><td><a href="https://github.com/shuxinqin/Chloe" target="_blank">Chloe.ORM</a></td><td>Chloe.ORM 是一款国产十分稳定可靠的 ORM 框架。除了常规增删查改外还支持连接查询、分组查询、聚合查询、子查询，大部分操作可通过 lambda 完成。还支持分库分表分页、聚合、分组聚合，并支持多个字段组合分片以及多字段路由。</td><td><a href="https://github.com/shuxinqin/Chloe" target="_blank">https://github.com/shuxinqin/Chloe</a></td></tr><tr><td>4</td><td><a href="https://github.com/donet5/SqlSugar" target="_blank">SqlSugar</a></td><td>SqlSugar是一款老牌 .NET 开源ORM框架，支持.NET CORE 和 MySql、SqlServer、Sqlite、Oracle 、 postgresql 、达梦、人大金仓 数据库，具有EF NH的功能，比EF更人性化的语法，支持真实的批量操作，另外还有媲美Dapper的性能。</td><td><a href="https://www.donet5.com/" target="_blank">https://www.donet5.com/</a></td></tr><tr><td>3</td><td><a href="https://github.com/dotnetcore/FreeSql" target="_blank">FreeSql</a></td><td>FreeSql 是一款功能强大的对象关系映射（O/RM）组件，支持 .NET Core 2.1+、.NET Framework 4.0+ 以及 Xamarin。</td><td><a href="https://freesql.net/" target="_blank">https://freesql.net/</a></td></tr><tr><td>2</td><td><a href="https://github.com/DapperLib/Dapper" target="_blank">Dapper</a></td><td>Dapper是一个简单的.NET对象映射器，在速度方面具有”King of Micro ORM”的头衔，几乎与使用原始的ADO.NET数据读取器一样快。ORM是一个对象关系映射器，它负责数据库和编程语言之间的映射。Dapper通过扩展IDbConnection提供一些有用的扩展方法去查询您的数据库。</td><td><a href="https://github.com/DapperLib/Dapper" target="_blank">https://github.com/DapperLib/Dapper</a></td></tr><tr><td>1</td><td><a href="https://github.com/ServiceStack/ServiceStack.OrmLite" target="_blank">ServiceStack.OrmLite</a></td><td>OrmLite是一个快速、简单、类型化的.NET ORM，OrmLite 的目标是提供一个方便、DRY、无配置、与 RDBMS 无关的类型包装器，该包装器与 SQL 保持高度亲和性，公开直观的 API，生成可预测的 SQL 并干净地映射到断开连接和数据传输对象 (DTO) 友好、普通的旧C# 对象 (POCO)。这种方法更容易推理您的数据访问，从而清楚地知道什么 SQL 在什么时间执行，同时减轻意外行为、隐式 N+1 查询和重对象关系映射器 (ORM) 中普遍存在的泄漏数据访问。</td><td><a href="https://github.com/ServiceStack/ServiceStack.OrmLite" target="_blank">https://github.com/ServiceStack/ServiceStack.OrmLite</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>网络通信框架<a href="#网络通信框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td></td><td></td><td></td></tr><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td><a href="https://github.com/beetlex-io/BeetleX" target="_blank">BeetleX</a></td><td>BeetleX是一个开源的高性能 .NET Core网络库，提供了TCP、UDP、HTTP和WebSocket协议的支持。它的设计目标是简单易用、高性能、可扩展性强，并支持大规模并发连接。BeetleX基于.NET Core实现，支持跨平台运行，可以运行在Windows、Linux和macOS等系统上。</td><td><a href="https://github.com/beetlex-io/BeetleX" target="_blank">https://github.com/beetlex-io/BeetleX</a></td></tr><tr><td>3</td><td><a href="https://github.com/SignalR/SignalR" target="_blank">SignalR</a></td><td>SignalR 是一个实时网络通信框架，可以进行服务器到客户端和客户端到客户端的双向通信。它支持 WebSocket、Server-Sent Events 和 Long Polling 等传输协议，适用于实时聊天、实时推送等场景。</td><td><a href="https://learn.microsoft.com/zh-cn/aspnet/core/signalr/introduction?view=aspnetcore-7.0" target="_blank">https://learn.microsoft.com/zh-cn/aspnet/core/signalr/introduction?view=aspnetcore-7.0</a></td></tr><tr><td>2</td><td><a href="https://github.com/RRQM/TouchSocket" target="_blank">TouchSocket</a></td><td>TouchSocket是.Net(包括 C# 、VB.Net、F#)的一个整合性的、超轻量级的网络通信框架。包含了 tcp、udp、ssl、http、websocket、rpc、jsonrpc、webapi、xmlrpc等一系列的通信模块。一键式解决 TCP 黏分包问题，udp大数据包分片组合问题等。使用协议模板，可快速实现「固定包头」、「固定长度」、「区间字符」等一系列的数据报文解析。</td><td><a href="https://rrqm_home.gitee.io/touchsocket/" target="_blank">https://rrqm_home.gitee.io/touchsocket/</a></td></tr><tr><td>1</td><td><a href="https://github.com/Azure/DotNetty" target="_blank">DotNetty</a></td><td>DotNetty是Netty的移植版，它是一个异步事件驱动的网络应用程序框架，用于快速开发可维护的高性能协议服务器和客户端。</td><td><a href="https://github.com/Azure/DotNetty" target="_blank">https://github.com/Azure/DotNetty</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>系统日志框架<a href="#系统日志框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td><a href="https://github.com/NLog/NLog" target="_blank">NLog</a></td><td>是一个功能强大且易于配置的日志记录库，它提供了多种输出目标和过滤器，可以满足各种日志记录需求。NLog 支持异步日志记录、日志级别、事件跟踪等功能。</td><td><a href="https://github.com/NLog/NLog" target="_blank">https://github.com/NLog/NLog</a></td></tr><tr><td>2</td><td><a href="https://github.com/serilog/serilog" target="_blank">Serilog</a></td><td>是一个简单而灵活的日志记录库，它支持结构化日志记录，并提供了丰富的日志输出和处理方式。通过使用 Serilog，可以轻松地将日志记录到不同的目标，如控制台、文件、数据库等。</td><td><a href="https://github.com/serilog/serilog" target="_blank">https://github.com/serilog/serilog</a></td></tr><tr><td>1</td><td><a href="https://github.com/apache/logging-log4net" target="_blank">Log4net</a></td><td>是一个成熟稳定的日志记录框架，它被广泛用于.NET 应用程序开发。log4net 提供了高度可配置的日志记录功能，支持多种日志输出目标和日志级别。</td><td><a href="https://github.com/apache/logging-log4net" target="_blank">https://github.com/apache/logging-log4net</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>AI和LLM框架<a href="#ai和llm框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>10</td><td></td><td></td><td></td></tr><tr><td>9</td><td></td><td></td><td></td></tr><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td><a href="https://github.com/openai/openai-dotnet" target="_blank">OpenAI .NET</a></td><td>OpenAI API的官方.NET客户端库。</td><td><a href="https://github.com/openai/openai-dotnet" target="_blank">https://github.com/openai/openai-dotnet</a></td></tr><tr><td>6</td><td><a href="https://github.com/microsoft/autogen" target="_blank">AutoGen</a></td><td>AutoGen 是一个框架，它通过多个代理进行对话以解决任务，从而实现 LLM 应用的开发。AutoGen 代理可定制、可对话，并且能够无缝地允许人类参与。它们可以在不同的模式下运行，使用 LLM、人类输入和工具的组合。</td><td><a href="https://github.com/microsoft/autogen" target="_blank">https://github.com/microsoft/autogen</a></td></tr><tr><td>5</td><td><a href="https://github.com/betalgo/openai" target="_blank">Betalgo.OpenAI</a></td><td>OpenAI .NET SDK其中包括了Azure OpenAI、ChatGPT、Whisper 和 DALL-E。</td><td><a href="https://github.com/betalgo/openai" target="_blank">https://github.com/betalgo/openai</a></td></tr><tr><td>4</td><td><a href="https://github.com/microsoft/semantic-kernel" target="_blank">Semantic Kernel</a></td><td>Semantic Kernel是一个开源的软件开发工具包（SDK），旨在将大型语言模型（LLM）如OpenAI、Azure OpenAI和Hugging Face与传统的编程语言如C#、Python和Java集成。这个项目通过提供插件系统，允许开发者轻松地创建能够调用这些大型语言模型的应用程序。</td><td><a href="https://github.com/microsoft/semantic-kernel" target="_blank">https://github.com/microsoft/semantic-kernel</a></td></tr><tr><td>3</td><td><a href="https://github.com/SciSharp/BotSharp" target="_blank">BotSharp</a></td><td>BotSharp 是一个面向企业级 LLM 应用的开源 AI 框架，旨在促进智能机器人助手在面向业务系统中的开发和应用。该项目涉及自然语言理解、计算机视觉和音频处理技术，并旨在推动智能机器人助手在企业级系统中的开发和应用。BotSharp 提供了开箱即用的机器学习算法，使普通程序员能够更快、更轻松地开发人工智能应用程序。</td><td><a href="https://github.com/SciSharp/BotSharp" target="_blank">https://github.com/SciSharp/BotSharp</a></td></tr><tr><td>2</td><td><a href="https://github.com/RageAgainstThePixel/OpenAI-DotNet" target="_blank">OpenAI DotNet</a></td><td>一个简单的.NET客户端库，用于通过OpenAI的RESTful API进行访问（非官方）。</td><td><a href="https://github.com/RageAgainstThePixel/OpenAI-DotNet" target="_blank">https://github.com/RageAgainstThePixel/OpenAI-DotNet</a></td></tr><tr><td>1</td><td><a href="https://github.com/SciSharp/LLamaSharp" target="_blank">LLamaSharp</a></td><td>LLamaSharp是一个跨平台库，用于在本地设备上运行LLaMA/LLaVA模型（以及其他模型）。它基于llama.cpp，能够在CPU和GPU上高效进行推理。通过提供高级API和RAG支持，LLamaSharp使得在应用程序中部署大型语言模型（LLM）变得方便。</td><td><a href="https://github.com/SciSharp/LLamaSharp" target="_blank">https://github.com/SciSharp/LLamaSharp</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>深度学习框架<a href="#深度学习框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td><a href="https://github.com/dotnet/TorchSharp" target="_blank">TorchSharp</a></td><td>TorchSharp 是一个.NET库，它提供了访问支持 PyTorch 的库的功能。TorchSharp 的重点是绑定由 libtorch 提供的 API，特别关注张量操作。设计意图是尽可能接近 PyTorch 的使用体验，同时在适当的情况下利用.NET静态类型系统的优势。例如，当PyTorch为特定参数定义了多个有效类型时，会使用方法重载进行处理。</td><td><a href="https://github.com/dotnet/TorchSharp" target="_blank">https://github.com/dotnet/TorchSharp</a></td></tr><tr><td>4</td><td><a href="https://github.com/SciSharp/Keras.NET" target="_blank">Keras.NET </a></td><td>是一个基于 .NET 平台的 Keras 框架移植版，Keras 是一个流行的深度学习框架，以易用性和可扩展性而闻名。通过 Keras.NET，您可以在 .NET 应用程序中使用 Keras 的高级 API 构建和训练神经网络模型。</td><td><a href="https://github.com/SciSharp/Keras.NET" target="_blank">https://github.com/SciSharp/Keras.NET</a></td></tr><tr><td>3</td><td><a href="https://github.com/SciSharp/TensorFlow.NET" target="_blank">TensorFlow.NET</a></td><td>是一个将 TensorFlow 框架移植到 .NET 平台的项目。它提供了用于构建和训练深度学习模型的强大功能和 API，并允许开发者在 .NET 应用程序中直接使用 TensorFlow 的功能。</td><td><a href="https://github.com/SciSharp/TensorFlow.NET" target="_blank">https://github.com/SciSharp/TensorFlow.NET</a></td></tr><tr><td>2</td><td><a href="https://github.com/dotnet/machinelearning" target="_blank">ML.NET</a></td><td>由 Microsoft 推出的开源机器学习框架，它提供了一套简单易用的 API 和工具，便于开发者在.NET 应用程序中进行机器学习和深度学习任务。</td><td><a href="https://dotnet.microsoft.com/zh-cn/apps/machinelearning-ai/ml-dotnet" target="_blank">https://dotnet.microsoft.com/zh-cn/apps/machinelearning-ai/ml-dotnet</a></td></tr><tr><td>1</td><td><a href="https://github.com/sdcb/PaddleSharp" target="_blank">PaddleSharp</a></td><td>基于百度飞桨的深度学习框架.NET封装。</td><td><a href="https://www.cnblogs.com/sdflysha/p/20230724-paddlesharp-in-a-year.html" target="_blank">https://www.cnblogs.com/sdflysha/p/20230724-paddlesharp-in-a-year.html</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>单元测试框架<a href="#单元测试框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td><a href="https://github.com/fixie/fixie" target="_blank">Fixie</a></td><td>Fixie是一个类似于NUnit和xUnit的现代化.NET测试框架，但更注重简洁的默认设置和灵活的定制。</td><td><a href="https://github.com/fixie/fixie" target="_blank">https://github.com/fixie/fixie</a></td></tr><tr><td>2</td><td><a href="https://github.com/xunit/xunit" target="_blank">xUnit.net</a></td><td>xUnit.net是一个.NET平台上的开源单元测试框架，它提供了简洁、现代化的设计和丰富的功能，使开发人员能够轻松编写高效的单元测试。</td><td><a href="https://github.com/xunit/xunit" target="_blank">https://github.com/xunit/xunit</a></td></tr><tr><td>1</td><td><a href="https://github.com/nunit/nunit" target="_blank">NUnit</a></td><td>NUnit是一个流行的.NET平台上的开源单元测试框架，它提供了强大的功能和灵活性，使开发人员能够编写高质量的单元测试代码。</td><td><a href="https://github.com/nunit/nunit" target="_blank">https://github.com/nunit/nunit</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>程序限流框架<a href="#程序限流框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/stefanprodan/AspNetCoreRateLimit" target="_blank">AspNetCoreRateLimit</a></td><td>AspNetCoreRateLimit是一个基于ASP.NET Core的限流框架，提供了灵活的限流功能，帮助开发人员控制和保护应用程序中的HTTP请求频率和数量。</td><td><a href="https://github.com/stefanprodan/AspNetCoreRateLimit" target="_blank">https://github.com/stefanprodan/AspNetCoreRateLimit</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>工作流引擎框架<a href="#工作流引擎框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td><a href="https://github.com/aelassas/wexflow" target="_blank">Wexflow</a></td><td>Wexflow 是一个开源、跨平台的工作流引擎和自动化平台，旨在实现重复性任务的自动化。在 Wexflow 的帮助下，构建自动化和工作流程变得轻而易举。</td><td><a href="https://github.com/aelassas/wexflow" target="_blank">https://github.com/aelassas/wexflow</a></td></tr><tr><td>3</td><td><a href="https://github.com/besley/slickflow" target="_blank">Slickflow</a></td><td>Slickflow是一款.NET开源的工作流引擎，Slickflow工作流引擎，选取BPMN模型作为工作流模型的语义表达，BPMN模型消除技术和业务之间的隔阂，注重业务人员对流程的需求和理解，而不是以技术为本位，相对来说，更近一步体现技术服务于业务需求的概念。</td><td><a href="https://github.com/besley/slickflow" target="_blank">https://github.com/besley/slickflow</a></td></tr><tr><td>2</td><td><a href="https://github.com/elsa-workflows/elsa-core" target="_blank">Elsa Core</a></td><td>Elsa Core项目建立在.NET Core平台上，一个强大且灵活的工作流引擎和设计器，适用于构建各种类型的工作流应用。提供了一组功能强大且灵活的工具和组件，用于定义、运行和监控工作流。它支持多种工作流模型、活动节点、并行执行、条件分支、定时触发等特性，使得开发人员能够根据业务需要构建复杂的工作流程。</td><td><a href="https://github.com/elsa-workflows/elsa-core" target="_blank">https://github.com/elsa-workflows/elsa-core</a></td></tr><tr><td>1</td><td><a href="https://github.com/danielgerlag/workflow-core" target="_blank">Workflow Core</a></td><td>Workflow Core是一个基于.NET的开源工作流引擎，提供了可扩展和灵活的工作流管理功能，帮助开发人员设计和执行复杂的工作流程。</td><td><a href="https://github.com/danielgerlag/workflow-core" target="_blank">https://github.com/danielgerlag/workflow-core</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>身份认证授权框架<a href="#身份认证授权框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td><a href="https://github.com/openiddict/openiddict-core" target="_blank">OpenIddict</a></td><td>一个开源的身份认证和授权框架，用于简化实现身份验证、令牌颁发和访问控制等功能的过程。 提供了丰富的配置选项和扩展点，使开发人员能够根据自己的需求进行定制和扩展。它还提供了与 ASP.NET Core 和 Entity Framework Core 的无缝集成，使其更容易与现有的应用程序和数据存储进行整合。</td><td><a href="https://github.com/openiddict/openiddict-core" target="_blank">https://github.com/openiddict/openiddict-core</a></td></tr><tr><td>2</td><td><a href="https://github.com/casbin/Casbin.NET" target="_blank">Casbin.NET </a></td><td>一种授权库，支持在.NET（C#）中的ACL、RBAC、ABAC等访问控制模型。</td><td><a href="https://github.com/casbin/Casbin.NET" target="_blank">https://github.com/casbin/Casbin.NET</a></td></tr><tr><td>1</td><td><a href="https://github.com/IdentityServer/IdentityServer4" target="_blank">IdentityServer4</a></td><td>IdentityServer4是一个基于OpenID Connect和OAuth 2.0的开源身份认证和授权框架，用于构建安全的认证服务器和单点登录解决方案。</td><td><a href="https://github.com/IdentityServer/IdentityServer4" target="_blank">https://github.com/IdentityServer/IdentityServer4</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>反向代理框架<a href="#反向代理框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/microsoft/reverse-proxy" target="_blank">YARP</a></td><td>YARP (Yet Another Reverse Proxy) 是一个开源的反向代理项目，由微软推出并维护。它提供了一个灵活、高性能和可扩展的反向代理解决方案。YARP 的设计目标是为开发人员提供一个简单而强大的工具，用于构建和管理反向代理服务。它支持多种功能和特性，包括负载均衡、路由规则、请求转发、请求/响应修改、流量控制等。该项目采用基于配置的方式来定义反向代理的行为。通过简单的配置文件，您可以指定转发规则、负载均衡策略、路由规则以及其他扩展功能。这使得 YARP 可以适应不同类型的应用场景和需求。</td><td><a href="https://github.com/microsoft/reverse-proxy" target="_blank">https://github.com/microsoft/reverse-proxy</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>API 网关框架<a href="#api-网关框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td><a href="https://github.com/239573049/FastGateway/" target="_blank">FastGateway</a></td><td>基于 .NET8+FreeSql超轻量级网关，为了代替Nginx而生，基于使用Yarp打造更快更轻量级的网关，并且提供了完整的UI界面提供了地区请求数据统计，提供了免费的HTTPS证书申请，并且支持HTTP内网穿透，还提供了黑白名单，并且提供动态更新，支持限流等。</td><td><a href="https://github.com/239573049/FastGateway/" target="_blank">https://github.com/239573049/FastGateway/</a></td></tr><tr><td>4</td><td><a href="https://gitee.com/iioter/iotgateway" target="_blank">iotgateway</a></td><td>基于.NET6的跨平台物联网网关。通过可视化配置，轻松的连接到你的任何设备和系统(如PLC、扫码枪、CNC、数据库、串口设备、上位机、OPC Server、OPC UA Server、Mqtt Server等)，从而与 Thingsboard、IoTSharp或您自己的物联网平台(MES、SCADA)进行双向数据通讯。提供简单的驱动开发接口；当然也可以进行边缘计算。</td><td><a href="https://gitee.com/iioter/iotgateway" target="_blank">https://gitee.com/iioter/iotgateway</a></td></tr><tr><td>3</td><td><a href="https://gitee.com/dotnetchina/ThingsGateway" target="_blank">ThingsGateway</a></td><td>ThingsGateway是一款基于.NET8的跨平台高性能边缘采集网关，提供底层PLC通讯库，通讯调试软件等。</td><td><a href="https://gitee.com/dotnetchina/ThingsGateway" target="_blank">https://gitee.com/dotnetchina/ThingsGateway</a></td></tr><tr><td>2</td><td><a href="https://github.com/ThreeMammals/Ocelot" target="_blank">Ocelot</a></td><td>Ocelot是一个基于.NET Core的开源网关库，它提供了一种简单而灵活的方式来构建和管理微服务架构中的API网关。通过使用Ocelot，您可以轻松地实现反向代理、路由、请求转发、负载均衡、身份验证、授权等功能。</td><td><a href="https://github.com/ThreeMammals/Ocelot" target="_blank">https://github.com/ThreeMammals/Ocelot</a></td></tr><tr><td>1</td><td><a href="https://gitee.com/apiumc/Gateway" target="_blank">Apiumc Gateway</a></td><td>Apiumc Gateway 是高性能的Web网关，它从底层Socket原始通信层开始，采用多线程、多任务模式从新构建Web服务，充分发挥当下多核的CPU的多任务并行性能，达到不输nginx的性能表现，而多线程、多任务天生比多进程模式更有编程可控性，基于这此原理，为Apiumc带来丰富多的基于网关深度应用，是网关功能集大成者；它一个工具等于Nginx + 网关登录 + 图片处理 + 内网穿透 + 免费Ssl证书，且配置全程界面化，让你告别难懂、难记易出错的指令配置。</td><td><a href="https://gitee.com/apiumc/Gateway" target="_blank">https://gitee.com/apiumc/Gateway</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>网络爬虫框架<a href="#网络爬虫框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td><a href="https://github.com/sjdirect/abot" target="_blank">Abot</a></td><td>Abot是一个基于C#的开源网络爬虫框架，旨在提供高速和灵活的爬取功能。它负责底层的任务调度、多线程处理、HTTP 请求、链接解析等繁琐的细节，开发者只需要注册事件来处理页面数据。</td><td><a href="https://github.com/sjdirect/abot" target="_blank">https://github.com/sjdirect/abot</a></td></tr><tr><td>2</td><td><a href="https://github.com/JBildstein/SpiderEye" target="_blank">SpiderEye</a></td><td>SpiderEye是一个基于.NET的Web爬虫框架，旨在为开发者提供构建高效、可扩展的网络爬虫的工具。与其他类似的框架相比，SpiderEye使用操作系统的原生webview而不是捆绑Chromium，从而提供更轻量级的解决方案。</td><td><a href="https://github.com/JBildstein/SpiderEye" target="_blank">https://github.com/JBildstein/SpiderEye</a></td></tr><tr><td>1</td><td><a href="https://github.com/dotnetcore/DotnetSpider" target="_blank">DotnetSpider</a></td><td>DotnetSpider是一个轻量、灵活、高性能、跨平台的分布式网络爬虫框架。</td><td><a href="https://github.com/dotnetcore/DotnetSpider" target="_blank">https://github.com/dotnetcore/DotnetSpider</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>内网穿透框架<a href="#内网穿透框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/xljiulang/CYarp" target="_blank">CYarp</a></td><td>基于Yarp的http内网穿透中间件。支持tcp、http/2.0或http/3.0作为http/1.1的传输层。</td><td><a href="https://github.com/xljiulang/CYarp" target="_blank">https://github.com/xljiulang/CYarp</a></td></tr><tr><td>1</td><td><a href="https://gitee.com/Hgui/FastTunnel" target="_blank">FastTunnel</a></td><td>FastTunnel 高性能跨平台内网穿透工具，使用它可以实现将内网服务暴露到公网供自己或任何人访问。</td><td><a href="https://gitee.com/Hgui/FastTunnel" target="_blank">https://gitee.com/Hgui/FastTunnel</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>依赖注入框架<a href="#依赖注入框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>10</td><td></td><td></td><td></td></tr><tr><td>9</td><td></td><td></td><td></td></tr><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td><a href="https://github.com/autofac/Autofac" target="_blank">Autofac</a></td><td>Autofac是微软.NET平台上的一个IoC容器。它管理类之间的依赖关系，使得随着应用程序规模和复杂性的增长，应用程序保持易于修改。这是通过将普通的.NET类视为组件来实现的。</td><td><a href="https://github.com/autofac/Autofac" target="_blank">https://github.com/autofac/Autofac</a></td></tr><tr><td>6</td><td><a href="https://github.com/khellang/Scrutor" target="_blank">Scrutor</a></td><td>Scrutor 是一个开源的 .NET 库，旨在简化程序集扫描和依赖注入容器的使用。通过 Scrutor，您可以方便地进行程序集扫描，并根据特定的约定自动注册服务到依赖注入容器中。这个框架使得在使用 Microsoft.Extensions.DependencyInjection 进行依赖注入时更加灵活和方便。Scrutor 提供了各种功能，包括程序集扫描、服务装饰等，帮助简化和优化您的依赖注入配置过程。</td><td><a href="https://github.com/khellang/Scrutor" target="_blank">https://github.com/khellang/Scrutor</a></td></tr><tr><td>5</td><td><a href="https://github.com/JasperFx/lamar" target="_blank">Lamar</a></td><td>快速的控制反转工具，是StructureMap的继任者。</td><td><a href="https://github.com/JasperFx/lamar" target="_blank">https://github.com/JasperFx/lamar</a></td></tr><tr><td>4</td><td><a href="https://github.com/seesharper/LightInject" target="_blank">LightInject</a></td><td>.NET开源的一个超轻量级的IoC容器。</td><td><a href="https://github.com/seesharper/LightInject" target="_blank">https://github.com/seesharper/LightInject</a></td></tr><tr><td>3</td><td><a href="https://github.com/ipjohnson/Grace" target="_blank">Grace</a></td><td>Grace是一个.NET开源的功能丰富的依赖注入容器库。</td><td><a href="https://github.com/ipjohnson/Grace" target="_blank">https://github.com/ipjohnson/Grace</a></td></tr><tr><td>2</td><td><a href="https://github.com/dadhi/DryIoc" target="_blank">DryIOC</a></td><td>DryIoc是一个快速、小巧、功能齐全的.NET IoC容器。</td><td><a href="https://github.com/dadhi/DryIoc" target="_blank">https://github.com/dadhi/DryIoc</a></td></tr><tr><td>1</td><td><a href="https://github.com/structuremap/structuremap" target="_blank">StructureMap</a></td><td>一个用于.NET的依赖注入/控制反转工具。</td><td><a href="https://github.com/structuremap/structuremap" target="_blank">https://github.com/structuremap/structuremap</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>开源缓存框架<a href="#开源缓存框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/ZiggyCreatures/FusionCache" target="_blank">FusionCache</a></td><td>FusionCache是一个用于构建高效缓存系统的.NET框架（基于MIT License协议开源、强大、易于使用），旨在提供简单易用、高性能和可靠的缓存解决方案。支持内存缓存、分布式缓存、http 缓存、CDN、浏览器缓存、离线缓存等等。</td><td><a href="https://github.com/ZiggyCreatures/FusionCache" target="_blank">https://github.com/ZiggyCreatures/FusionCache</a></td></tr><tr><td>1</td><td><a href="https://github.com/dotnetcore/EasyCaching" target="_blank">EasyCaching</a></td><td>EasyCaching是一个.NET开源的缓存库，包含了缓存的基本用法和一些高级用法，可以帮助开发者更轻松地处理缓存。</td><td><a href="https://github.com/dotnetcore/EasyCaching" target="_blank">https://github.com/dotnetcore/EasyCaching</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>其他开源框架<a href="#其他开源框架"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td></td><td></td><td></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section></section><section><h3>开源项目<a href="#开源项目"><span>#</span></a></h3><section><h4>后台&amp;权限&amp;工作流管理系统（Admin&amp;RBAC&amp;Workflow）<a href="#后台权限工作流管理系统adminrbacworkflow"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>30</td><td></td><td></td><td></td></tr><tr><td>29</td><td></td><td></td><td></td></tr><tr><td>28</td><td></td><td></td><td></td></tr><tr><td>27</td><td></td><td></td><td></td></tr><tr><td>26</td><td></td><td></td><td></td></tr><tr><td>25</td><td><a href="https://github.com/dymproject/purest-admin" target="_blank">Purest Admin</a></td><td>基于 .NET 8 + Vue3 实现的极简RABC权限管理系统后端 后端基于精简后的ABP框架，前端基于vue-pure-admin，前端极强的表格框架vxe-table，旨在打造一款最合适二次开发的极简.NET框架。</td><td><a href="https://github.com/dymproject/purest-admin" target="_blank">https://github.com/dymproject/purest-admin</a></td></tr><tr><td>24</td><td><a href="https://github.com/jxnkwlp/abp-elsa-module" target="_blank">abp-elsa-module</a></td><td>Elsa Abp模块和工作流应用程序。</td><td><a href="https://github.com/jxnkwlp/abp-elsa-module" target="_blank">https://github.com/jxnkwlp/abp-elsa-module</a></td></tr><tr><td>23</td><td><a href="https://gitee.com/LongbowEnterprise/BootstrapAdmin" target="_blank">BootstrapAdmin</a></td><td>基于 RBAC 的 Net7 后台管理框架，权限管理，前后台分离，支持多站点单点登录，兼容所有主流浏览器，内置微信、支付宝、QQ等多种登录方式，内置多种样式，可切换至 Blazor 多 Tabs 模式，权限控制细化到网页内任意元素（按钮、表格、文本框等等）。</td><td><a href="https://gitee.com/LongbowEnterprise/BootstrapAdmin" target="_blank">https://gitee.com/LongbowEnterprise/BootstrapAdmin</a></td></tr><tr><td>22</td><td><a href="https://gitee.com/ccnetcore/Yi" target="_blank">Yi.Admin</a></td><td>YiFramework是一个基于.Net8+Abp.vNext+SqlSugar的DDD领域驱动设计后端开源框架，前端Vue3，框架三层架构\DDD领域驱动设计，内置Rbac权限管理、Bbs论坛社区系统 以用户体验出发。 架构干净整洁、采用微软风格原生框架封装。 适合小中大型项目上线、.Net8学习、Abp.vNext学习、Sqlsugar学习 、项目二次开发。</td><td><a href="https://gitee.com/ccnetcore/Yi" target="_blank">https://gitee.com/ccnetcore/Yi</a></td></tr><tr><td>21</td><td><a href="https://github.com/nsnail/NetAdmin" target="_blank">NetAdmin</a></td><td>通用后台权限管理系统、快速开发框架（基于C#12/.NET8、Vue3/Vite、Element Plus等现代技术构建，具有十分整洁、优雅的编码规范）。</td><td><a href="https://github.com/nsnail/NetAdmin" target="_blank">https://github.com/nsnail/NetAdmin</a></td></tr><tr><td>20</td><td><a href="https://gitee.com/feiyit/fytsoa" target="_blank">FytSoa Admin</a></td><td>FytSoa Admin 是一个快速搭建中后台解决方案，后台基于 NetCore 6 和前端 VUE3+Element+Plus 实现。使用最新的前沿技术栈，提供各类使用组件方便在业务开发时调用，并且持续性的提供丰富的业务模块，帮助你快速搭建企业级中后台任务。</td><td><a href="https://gitee.com/feiyit/fytsoa" target="_blank">https://gitee.com/feiyit/fytsoa</a></td></tr><tr><td>19</td><td><a href="https://github.com/91270/Meiam.System" target="_blank">Meiam.System</a></td><td>.NET 7 / .NET 5 WebAPI + Vue 2.0 + RBAC 企业级前后端分离权限框架。</td><td><a href="https://github.com/91270/Meiam.System" target="_blank">https://github.com/91270/Meiam.System</a></td></tr><tr><td>18</td><td><a href="https://gitee.com/qian_wei_hong/WaterCloud" target="_blank">WaterCloud</a></td><td>.NET和Layui集成的最佳实践；敏捷开发优选框架，自带权限包含字段、数据权限，自带流程表单设计，基于多数据库的多租户等。</td><td><a href="https://gitee.com/qian_wei_hong/WaterCloud" target="_blank">https://gitee.com/qian_wei_hong/WaterCloud</a></td></tr><tr><td>17</td><td><a href="https://gitee.com/izory/ZrAdminNetCore" target="_blank">ZR.Admin.NET</a></td><td>一款前后端分离的、跨平台基于RBAC的通用权限管理后台。ORM采用SqlSugar。前端采用Vue、AntDesign，支持多种数据库、缓存、任务调度、支持统一异常处理、接口限流、支持一键生成前后端代码，支持动态国际化翻译(Vue3)，等诸多黑科技，代码简洁易懂、易扩展让开发更简单、更通用。</td><td><a href="https://gitee.com/izory/ZrAdminNetCore" target="_blank">https://gitee.com/izory/ZrAdminNetCore</a></td></tr><tr><td>16</td><td><a href="https://github.com/dotnetcore/osharp" target="_blank">OSharp</a></td><td>OSharp是一个基于.Net6.0的快速开发框架，框架对 AspNetCore 的配置、依赖注入、日志、缓存、实体框架、Mvc(WebApi)、身份认证、功能权限、数据权限等模块进行更高一级的自动化封装，并规范了一套业务实现的代码结构与操作流程，使 .Net 框架更易于应用到实际项目开发中。</td><td><a href="https://github.com/dotnetcore/osharp" target="_blank">https://github.com/dotnetcore/osharp</a></td></tr><tr><td>15</td><td><a href="https://github.com/serenity-is/Serenity" target="_blank">Serenity</a></td><td>Serenity 是一个 ASP.NET Core / TypeScript 应用程序平台，旨在通过基于服务的架构简化和缩短以数据为中心的业务应用程序的开发过程。它旨在通过避免模板代码、减少重复性任务所花费的时间以及应用最佳软件设计实践，使开发更轻松，同时降低维护成本。</td><td><a href="https://github.com/serenity-is/Serenity" target="_blank">https://github.com/serenity-is/Serenity</a></td></tr><tr><td>14</td><td><a href="https://github.com/leooneone/aibpm.plus" target="_blank">AIBPM</a></td><td>采用开源.NET框架中台Admin（前后端分离权限管理系统）开发的工作流/工单系统，自己实现的顺序流引擎。</td><td><a href="https://github.com/leooneone/aibpm.plus" target="_blank">https://github.com/leooneone/aibpm.plus</a></td></tr><tr><td>13</td><td><a href="https://github.com/cq-panda/Vue.NetCore" target="_blank">Vue.NetCore</a></td><td>一款基于Vue（提供Vue2/Vue3版本）和.Net Core前后端分离、开源免费（MIT License）、强大、跨平台的快速开发框架，并且框架内置代码生成器（解决重复性工作，提高开发效率），支持移动端(iOS/Android/H5/微信小程序）。</td><td><a href="https://github.com/cq-panda/Vue.NetCore" target="_blank">https://github.com/cq-panda/Vue.NetCore</a></td></tr><tr><td>12</td><td><a href="https://gitee.com/dotnetchina/OpenAuth.Net" target="_blank">OpenAuth.Net</a></td><td>.Net权限管理及快速开发框架、最好用的权限工作流系统。源于Martin Fowler企业级应用开发思想及最新技术组合（SqlSugar、EF、Quartz、AutoFac、WebAPI、Swagger、Mock、NUnit、Vue2/3、Element-ui/plus、IdentityServer等）。包括：角色授权、代码生成、打印设计、表单设计、工作流等。架构易扩展，是中小企业的首选。</td><td><a href="https://gitee.com/dotnetchina/OpenAuth.Net" target="_blank">https://gitee.com/dotnetchina/OpenAuth.Net</a></td></tr><tr><td>11</td><td><a href="https://gitee.com/zxzyjs/SimpleAdmin" target="_blank">SimpleAdmin</a></td><td>SimpleAdmin是一个小而美的通用业务型后台管理系统，专为解决开发过程中的痛点难点而生。Vue3+Vite+Vuex+JS,并在此基础上增加更人性化功能,后端基于.NET6/7+Furion,ORM采用Sqlsugar+单例模式,插件式开发。采用RBAC+多机构的权限管理模式，实现全网最灵活的接口级别数据权限控制，集成国密加解密，导入导出、导入导出、批量修改等常用插件。后端代码注释覆盖率&gt;90%，并配备超牛皮的代码生成器和超详细的手摸手教学文档，非常适合二次开发。</td><td><a href="https://gitee.com/zxzyjs/SimpleAdmin" target="_blank">https://gitee.com/zxzyjs/SimpleAdmin</a></td></tr><tr><td>10</td><td><a href="https://github.com/zhontai/Admin.Core" target="_blank">Admin.Core</a></td><td>Admin后端，前后端分离的权限管理系统。支持多租户、数据权限、动态Api、任务调度、OSS文件上传、滑块拼图验证、国内外主流数据库自由切换和动态高级查询。基于.Net跨平台开发的WebApi。集成统一认证授权、事件总线、数据验证、分布式缓存、分布式事务、Ip限流、全Api鉴权、集成测试、性能分析、健康检查、接口文档等。</td><td><a href="https://github.com/zhontai/Admin.Core" target="_blank">https://github.com/zhontai/Admin.Core</a></td></tr><tr><td>9</td><td><a href="https://github.com/dotnetcore/WTM" target="_blank">WTM</a></td><td>WalkingTec.Mvvm框架（简称WTM）是基于.net core的快速开发框架。支持Layui(前后端不分离), React(前后端分离),VUE(前后端分离)，内置代码生成器，最大程度的提高开发效率，是一款高效开发的利器。</td><td><a href="https://github.com/dotnetcore/WTM" target="_blank">https://github.com/dotnetcore/WTM</a></td></tr><tr><td>8</td><td><a href="https://gitee.com/yuebon/YuebonNetCore" target="_blank">YuebonCore</a></td><td>YuebonCore基于.Net7.0的权限管理及快速开发框架，前后端分离，核心模块包括：组织机构、角色用户、权限授权、多系统、多应用管理、定时任务、业务单据编码规则、代码生成器等，整合应用最新技术包括Asp.NetCore MVC、SqlSugar、WebAPI、Swagger、Vue等。它的架构易于扩展，是中小项目的首选。</td><td><a href="https://gitee.com/yuebon/YuebonNetCore" target="_blank">https://gitee.com/yuebon/YuebonNetCore</a></td></tr><tr><td>7</td><td><a href="https://github.com/xianhc/apevolo-api" target="_blank">ApeVolo</a></td><td>.Net 6.0 、SqlSugar、Vue、RBAC、前后端分离的开箱即用的企业级中后台管理系统。</td><td><a href="https://github.com/xianhc/apevolo-api" target="_blank">https://github.com/xianhc/apevolo-api</a></td></tr><tr><td>6</td><td><a href="https://github.com/hzy-6/hzy-admin" target="_blank">HzyAdmin</a></td><td>HzyAdmin 是前后端分离权限管理系统基架。</td><td><a href="https://github.com/hzy-6/hzy-admin" target="_blank">https://github.com/hzy-6/hzy-admin</a></td></tr><tr><td>5</td><td><a href="https://gitee.com/zhengguojing/magic-net" target="_blank">Magic.NET</a></td><td>基于Furion/.NET 7实现的通用管理平台（RBAC模式）。整合最新技术，模块插件式开发，前后端分离，开箱即用。集成Sqlsugar、多租户、缓存、数据校验、鉴权、事件总线、动态API、通讯、远程请求、任务调度、工作流等众多黑科技。代码简洁、易扩展，让开发更简单、更通用、更流行！</td><td><a href="https://gitee.com/zhengguojing/magic-net" target="_blank">https://gitee.com/zhengguojing/magic-net</a></td></tr><tr><td>4</td><td><a href="https://github.com/liukuo362573/YiShaAdmin" target="_blank">YiShaAdmin</a></td><td>YiShaAdmin基于.NET Core Web + Bootstrap开发，借鉴了很多开源项目的优点，让你开发Web管理系统和移动端Api更简单。 她可以用于所有的Web应用程序，例如网站管理后台、CMS、CRM、ERP、OA这类的系统和移动端Api（基于MIT License开源，免费可商用）。</td><td><a href="https://github.com/liukuo362573/YiShaAdmin" target="_blank">https://github.com/liukuo362573/YiShaAdmin</a></td></tr><tr><td>3</td><td><a href="https://github.com/Coldairarrow/Colder.Admin.AntdVue" target="_blank">Colder.Admin.AntdVue</a></td><td>Web后台快速开发框架,.NET5+Ant Design Vue版本。</td><td><a href="https://github.com/Coldairarrow/Colder.Admin.AntdVue" target="_blank">https://github.com/Coldairarrow/Colder.Admin.AntdVue</a></td></tr><tr><td>2</td><td><a href="https://github.com/lampo1024/DncZeus" target="_blank">DncZeus</a></td><td>DncZeus是一个基于 .NET 7 + Vue.js 的前后端分离的通用后台管理系统框架。后端使用.NET 7 + Entity Framework Core 构建，UI 则是目前流行的基于 Vue.js 的 iView。项目实现了前后端的动态权限管理和控制以及基于 JWT 的用户令牌认证机制，让前后端的交互更流畅。</td><td><a href="https://github.com/lampo1024/DncZeus" target="_blank">https://github.com/lampo1024/DncZeus</a></td></tr><tr><td>1</td><td><a href="https://github.com/anjoy8/Blog.Core" target="_blank">Blog.Core</a></td><td>Blog.Core一个开箱即用的企业级前后端分离【ASP.NET Core 8.0 Api + Vue 2.x + RBAC】权限框架。</td><td><a href="http://apk.neters.club/.doc/" target="_blank">http://apk.neters.club/.doc/</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>商城项目系统（Shop）<a href="#商城项目系统shop"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>10</td><td></td><td></td><td></td></tr><tr><td>9</td><td></td><td></td><td></td></tr><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td><a href="https://github.com/dotnet/eShop" target="_blank">eShop</a></td><td>eShop是由.NET团队提供的电子商务系统示例项目，演示了如何使用.NET技术栈构建现代化的电子商务网站，包括微服务架构、领域驱动设计和事件驱动架构等最佳实践。</td><td><a href="https://github.com/dotnet/eShop" target="_blank">https://github.com/dotnet/eShop</a></td></tr><tr><td>6</td><td><a href="https://github.com/simplcommerce/SimplCommerce" target="_blank">SimplCommerce</a></td><td>基于 .NET Core 开源的简单、跨平台、模块化电子商务系统。</td><td><a href="https://github.com/simplcommerce/SimplCommerce" target="_blank">https://github.com/simplcommerce/SimplCommerce</a></td></tr><tr><td>5</td><td><a href="https://github.com/smartstore/SmartStoreNET" target="_blank">SmartStoreNET</a></td><td>ASP.NET MVC开源的企业电子商务购物车解决方案。</td><td><a href="https://github.com/smartstore/SmartStoreNET" target="_blank">https://github.com/smartstore/SmartStoreNET</a></td></tr><tr><td>4</td><td><a href="https://github.com/trueai-org/module-shop" target="_blank">Module Shop</a></td><td>一个基于.NET Core构建的简单、跨平台、模块化、完全开源免费（MIT License）的商城系统。</td><td><a href="https://github.com/trueai-org/module-shop" target="_blank">https://github.com/trueai-org/module-shop</a></td></tr><tr><td>3</td><td><a href="https://github.com/CoreUnion/CoreShop" target="_blank">CoreShop</a></td><td>基于 Asp.Net Core 7.0、Uni-App开发，支持可视化布局的小程序商城系统，前后端分离，支持分布式部署，跨平台运行，拥有分销、代理、团购、拼团、秒杀、直播、优惠券、自定义表单等众多营销功能，拥有完整SKU、下单、售后、物流流程。支持一套代码编译发布微信小程序版、H5版、Android版、iOS版、支付宝小程序版、字节跳动小程序版、QQ小程序版等共10个平台。</td><td><a href="https://github.com/CoreUnion/CoreShop" target="_blank">https://github.com/CoreUnion/CoreShop</a></td></tr><tr><td>2</td><td><a href="https://github.com/jerrytang67/SoMall" target="_blank">SoMall</a></td><td>SoMall 多租户多商户多应用开源平台。</td><td><a href="https://github.com/jerrytang67/SoMall" target="_blank">https://github.com/jerrytang67/SoMall</a></td></tr><tr><td>1</td><td><a href="https://github.com/nopSolutions/nopCommerce" target="_blank">nopCommerce</a></td><td>一个功能丰富、免费、灵活且可定制的开源电子商务解决方案(大家假如有商城需求可以直接使用该项目进行二次开发，省时省力)</td><td><a href="https://github.com/nopSolutions/nopCommerce" target="_blank">https://github.com/nopSolutions/nopCommerce</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>仓库管理系统（WMS）<a href="#仓库管理系统wms"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td><a href="https://github.com/qq283335746/Wms" target="_blank">WMS（智能仓储配送平台）</a></td><td>WMS（智能仓储配送平台），一个具有后端+前端+移动/PDA端的项目。</td><td><a href="https://github.com/qq283335746/Wms" target="_blank">https://github.com/qq283335746/Wms</a></td></tr><tr><td>4</td><td><a href="https://github.com/comsmobiler/SmoWMS" target="_blank">SmoWMS</a></td><td>SmoWMS仓库管理系统，移动端APP开源项目，支持Android、iOS，基于.NET（C#、VB）。SmoWMS仓库管理系统包含了仓库管理、订单、主数据维护、图表分析、个人信息等几大功能。</td><td><a href="https://github.com/comsmobiler/SmoWMS" target="_blank">https://github.com/comsmobiler/SmoWMS</a></td></tr><tr><td>3</td><td><a href="https://github.com/awesomedotnetcore/WMS/" target="_blank">ZEQP.WMS</a></td><td>ZEQP是一个.NET Core开源、跨平台的仓储管理系统，数据库支持MSSQL/MySQL。</td><td><a href="https://github.com/awesomedotnetcore/WMS/" target="_blank">https://github.com/awesomedotnetcore/WMS/</a></td></tr><tr><td>2</td><td><a href="https://github.com/lysilver/KopSoftWms" target="_blank">KopSoftWms</a></td><td>KopSoftWms是.NET开源免费的WMS仓库管理系统。</td><td><a href="https://github.com/lysilver/KopSoftWms" target="_blank">https://github.com/lysilver/KopSoftWms</a></td></tr><tr><td>1</td><td><a href="https://github.com/fjykTec/ModernWMS" target="_blank">ModernWMS</a></td><td>ModernWMS库存管理系统是我们从多年ERP系统研发中总结出来的一套针对小型物流仓储供应链流程。在工作过程中我们很多的中小企业，由于IT预算有限，所以无法用上适合他们的系统，却又实实在在存在仓储管理方面的需求，以此我们开始了这个项目。为了帮助一些有需要的用户。</td><td><a href="https://github.com/fjykTec/ModernWMS" target="_blank">https://github.com/fjykTec/ModernWMS</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>制造执行系统（MES）<a href="#制造执行系统mes"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://gitee.com/ZM-Rid/imes" target="_blank">iMES工厂管家</a></td><td>一款基于.NetCore3.1和Vue3的MES管理系统。项目亮点：模版打印，Excel模版导出，自定义实体扩展，移动端精美设计，大屏设计等功能。</td><td><a href="https://gitee.com/ZM-Rid/imes" target="_blank">https://gitee.com/ZM-Rid/imes</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>内容管理系统（CMS）<a href="#内容管理系统cms"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>15</td><td></td><td></td><td></td></tr><tr><td>14</td><td></td><td></td><td></td></tr><tr><td>13</td><td></td><td></td><td></td></tr><tr><td>12</td><td></td><td></td><td></td></tr><tr><td>11</td><td></td><td></td><td></td></tr><tr><td>10</td><td><a href="https://github.com/PiranhaCMS/piranha.core" target="_blank">Piranha CMS</a></td><td>Piranha CMS是一个针对 .NET 8 和 Entity Framework Core 构建的解耦式、跨平台 CMS。它具有模块化和可扩展的架构，支持多种托管和部署方案。</td><td><a href="https://github.com/PiranhaCMS/piranha.core" target="_blank">https://github.com/PiranhaCMS/piranha.core</a></td></tr><tr><td>9</td><td><a href="https://github.com/SeriaWei/ZKEACMS" target="_blank">ZKEACMS</a></td><td>ZKEACMS build with .Net 7 (.Net CMS)可视化设计在线编辑内容管理系统。</td><td><a href="https://github.com/SeriaWei/ZKEACMS" target="_blank">https://github.com/SeriaWei/ZKEACMS</a></td></tr><tr><td>8</td><td><a href="https://github.com/oqtane/oqtane.framework" target="_blank">Oqtane Framework</a></td><td>Blazor 和 .NET MAUI 的 CMS &amp; 应用程序框架。</td><td><a href="https://github.com/oqtane/oqtane.framework" target="_blank">https://github.com/oqtane/oqtane.framework</a></td></tr><tr><td>7</td><td><a href="https://github.com/aprilyush/EasyCMS" target="_blank">EasyCms</a></td><td>EasyCms是一个基于Asp.net Core的后台快速开发框架，内容管理系统（建站CMS系统）。</td><td><a href="https://github.com/aprilyush/EasyCMS" target="_blank">https://github.com/aprilyush/EasyCMS</a></td></tr><tr><td>6</td><td><a href="https://github.com/umbraco/Umbraco-CMS" target="_blank">Umbraco CMS</a></td><td>Umbraco是最友好、最灵活、增长最快的ASP.NET开源的内容管理系统。</td><td><a href="https://github.com/umbraco/Umbraco-CMS" target="_blank">https://github.com/umbraco/Umbraco-CMS</a></td></tr><tr><td>5</td><td><a href="https://github.com/ixre/cms" target="_blank">JR-CMS</a></td><td>基于.NET + DDD 构建的跨平台多站点开源内容管理系统，同时支持ASP.NET 4.x和.NET6.0，可以运行在Windows,Linux,MacOSX等操作系统，支持Docker容器。</td><td><a href="https://github.com/ixre/cms" target="_blank">https://github.com/ixre/cms</a></td></tr><tr><td>4</td><td><a href="https://github.com/OrchardCMS/OrchardCore" target="_blank">OrchardCore</a></td><td>Orchard Core 是一个采用 ASP.NET Core 构建的开源模块化多租户应用程序框架，也是一个建立在该框架之上的内容管理系统（CMS）。</td><td><a href="https://github.com/OrchardCMS/OrchardCore" target="_blank">https://github.com/OrchardCMS/OrchardCore</a></td></tr><tr><td>3</td><td><a href="https://gitee.com/feiyit/FytSoaCms" target="_blank">FytSoaCms</a></td><td>一款基于NetCore2.2/3.1（Razor Page）功能强大的Cms建站系统，支持前后端分离。</td><td><a href="https://gitee.com/feiyit/FytSoaCms" target="_blank">https://gitee.com/feiyit/FytSoaCms</a></td></tr><tr><td>2</td><td><a href="https://github.com/luoyunchong/lin-cms-dotnetcore" target="_blank">lin-cms-dotnetcore</a></td><td>基于.NET 7+FreeSql实现的简单实用的CMS，前后端分离、Docker部署、OAtuh2授权登录、QQ、Github、Gitee快速登录、代码生成器、仿掘金专栏、IdentityServer4。</td><td><a href="https://github.com/luoyunchong/lin-cms-dotnetcore" target="_blank">https://github.com/luoyunchong/lin-cms-dotnetcore</a></td></tr><tr><td>1</td><td><a href="https://github.com/siteserver/cms" target="_blank">SSCMS</a></td><td>SSCMS是一个基于.NET Core开源的、能够以最低的成本、最少的人力投入在最短的时间内架设一个功能齐全、性能优异、规模庞大并易于维护的网站平台。</td><td><a href="https://github.com/siteserver/cms" target="_blank">https://github.com/siteserver/cms</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>客户关系管理系统（CRM）<a href="#客户关系管理系统crm"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/WebVella/WebVella-ERP" target="_blank">WebVella-ERP</a></td><td>WebVella ERP是一款免费的开源Web软件，旨在满足任何业务数据管理需求的极端定制和可插拔性。基于 ASP.NET Core、RazorPages 和 PostgreSQL 的免费开源可插拔 ERP 和 CRM 软件。以 Linux 或 Windows 为主机操作系统。这款系统的最大亮点在于其可插拔的设计。无需担心系统的耦合问题，可以轻松地将各个模块进行组合和扩展。系统的各个组件都遵循开放标准，在构建企业级应用时更加得心应手。无论是ERP还是CRM，都可以根据自身需求进行定制开发，实现最佳的业务流程。</td><td><a href="https://github.com/WebVella/WebVella-ERP" target="_blank">https://github.com/WebVella/WebVella-ERP</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>企业资源计划系统（ERP）<a href="#企业资源计划系统erp"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/WebVella/WebVella-ERP" target="_blank">WebVella-ERP</a></td><td>WebVella ERP是一款免费的开源Web软件，旨在满足任何业务数据管理需求的极端定制和可插拔性。基于 ASP.NET Core、RazorPages 和 PostgreSQL 的免费开源可插拔 ERP 和 CRM 软件。以 Linux 或 Windows 为主机操作系统。这款系统的最大亮点在于其可插拔的设计。无需担心系统的耦合问题，可以轻松地将各个模块进行组合和扩展。系统的各个组件都遵循开放标准，在构建企业级应用时更加得心应手。无论是ERP还是CRM，都可以根据自身需求进行定制开发，实现最佳的业务流程。</td><td><a href="https://github.com/WebVella/WebVella-ERP" target="_blank">https://github.com/WebVella/WebVella-ERP</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>即时通讯系统（IM）<a href="#即时通讯系统im"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/2881099/FreeIM" target="_blank">FreeIM</a></td><td>FreeIM 使用 websocket 协议实现简易、高性能（单机支持5万+连接）、集群即时通讯组件，支持点对点通讯、群聊通讯、上线下线事件消息等众多实用性功能。</td><td><a href="https://github.com/2881099/FreeIM" target="_blank">https://github.com/2881099/FreeIM</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>配置中心系统（CCS）<a href="#配置中心系统ccs"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/dotnetcore/AgileConfig" target="_blank">AgileConfig</a></td><td>AgileConfig基于.NET Core开发的轻量级分布式配置中心，秉承轻量化的特点，部署简单、配置简单、使用简单、学习简单，它只提取了必要的一些功能，并没有像Apollo那样复杂且庞大。</td><td><a href="https://github.com/dotnetcore/AgileConfig" target="_blank">https://github.com/dotnetcore/AgileConfig</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>任务调度系统（Scheduler）<a href="#任务调度系统scheduler"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>15</td><td></td><td></td><td></td></tr><tr><td>14</td><td></td><td></td><td></td></tr><tr><td>13</td><td></td><td></td><td></td></tr><tr><td>12</td><td></td><td></td><td></td></tr><tr><td>11</td><td><a href="https://github.com/dahall/TaskScheduler" target="_blank">TaskScheduler</a></td><td>这个原始的.NET封装器用于Windows任务计划程序，它整合了多个版本，并提供了本地化的控件用于编辑。</td><td><a href="https://github.com/dahall/TaskScheduler" target="_blank">https://github.com/dahall/TaskScheduler</a></td></tr><tr><td>10</td><td><a href="https://github.com/mausch/QuartzNetWebConsole" target="_blank">QuartzNetWebConsole</a></td><td>可嵌入的Quartz.Net Web控制台。</td><td><a href="https://github.com/mausch/QuartzNetWebConsole" target="_blank">https://github.com/mausch/QuartzNetWebConsole</a></td></tr><tr><td>9</td><td><a href="https://github.com/guryanovev/CrystalQuartz" target="_blank">CrystalQuartz</a></td><td>CrystalQuartz一个轻量级的用于管理和监控Quartz.NET调度器的开源Web应用程序，它提供了一个用户友好的界面，使得用户可以方便地查看和管理各种调度作业。</td><td><a href="https://github.com/guryanovev/CrystalQuartz" target="_blank">https://github.com/guryanovev/CrystalQuartz</a></td></tr><tr><td>8</td><td><a href="https://github.com/cq-panda/Quartz.NetUI" target="_blank">Quartz.NetUI</a></td><td>基于.NetCore + Quartz.Net + Vue + IView开箱即用的定时任务UI。不依赖数据库,只需在界面做简单配置。</td><td><a href="https://github.com/cq-panda/Quartz.NetUI" target="_blank">https://github.com/cq-panda/Quartz.NetUI</a></td></tr><tr><td>7</td><td><a href="https://github.com/l2999019/GZY.Quartz.MUI" target="_blank">GZY.Quartz.MUI</a></td><td>基于Quartz的轻量级,注入化的UI组件。</td><td><a href="https://github.com/l2999019/GZY.Quartz.MUI" target="_blank">https://github.com/l2999019/GZY.Quartz.MUI</a></td></tr><tr><td>6</td><td><a href="https://github.com/maikebing/SilkierQuartz" target="_blank">SilkierQuartz</a></td><td>SilkierQuartz可以作为Quartz.NET插件在现有应用程序中使用，并自动创建嵌入式Web服务器，使用起来非常方便。</td><td><a href="https://github.com/maikebing/SilkierQuartz" target="_blank">https://github.com/maikebing/SilkierQuartz</a></td></tr><tr><td>5</td><td><a href="https://github.com/yuzd/Hangfire.HttpJob" target="_blank">Hangfire.HttpJob</a></td><td>基于Hangfire开发的一个组件、一个调度器（调度服务），这个调度器启动后你可以在管理面板上添加作业(让你通过web请求的方式去调度你的作业)。</td><td><a href="https://github.com/yuzd/Hangfire.HttpJob" target="_blank">https://github.com/yuzd/Hangfire.HttpJob</a></td></tr><tr><td>4</td><td><a href="https://github.com/fluentscheduler/FluentScheduler" target="_blank">FluentScheduler</a></td><td>这是一个针对.NET平台的自动化作业调度器，它提供了易于操作的流畅接口。可以用它来自动地安排和执行各种任务，让工作变得更加高效、方便。</td><td><a href="https://github.com/fluentscheduler/FluentScheduler" target="_blank">https://github.com/fluentscheduler/FluentScheduler</a></td></tr><tr><td>3</td><td><a href="https://github.com/2881099/FreeScheduler" target="_blank">FreeScheduler</a></td><td>轻量化定时任务调度，支持临时的延时任务和重复循环任务(可持久化)，可按秒，每天/每周/每月固定时间，自定义间隔执行，支持 .NET Core 2.1+、.NET Framework 4.0+ 运行环境。</td><td><a href="https://github.com/2881099/FreeScheduler" target="_blank">https://github.com/2881099/FreeScheduler</a></td></tr><tr><td>2</td><td><a href="https://github.com/quartznet/quartznet" target="_blank">Quartz.Net</a></td><td>一款功能齐全的任务调度系统，从小型应用到大型企业级系统都能适用。功能齐全体现在触发器的多样性上面，即支持简单的定时器，也支持Cron表达式；即能执行重复的作业任务，也支持指定例外的日历；任务也可以是多样性的，只要继承IJob接口即可。</td><td><a href="https://github.com/quartznet/quartznet" target="_blank">https://github.com/quartznet/quartznet</a></td></tr><tr><td>1</td><td><a href="https://github.com/HangfireIO/Hangfire" target="_blank">Hangfire</a></td><td>一个开源的.NET任务调度框架，提供了内置集成化的控制台，可以直观明了的查看作业调度情况，并且Hangfire不需要依赖于单独的应用程序执行（如：windows服务，window计划）。并且支持持久性存储。</td><td><a href="https://www.hangfire.io/" target="_blank">https://www.hangfire.io/</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>分布式事务解决方案<a href="#分布式事务解决方案"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/dotnetcore/CAP" target="_blank">CAP</a></td><td>CAP 是一个基于 .NET Standard 的 C# 库，它是一种处理分布式事务的解决方案，同样具有 EventBus 的功能，它具有轻量级、易使用、高性能等特点。</td><td><a href="https://github.com/dotnetcore/CAP" target="_blank">https://github.com/dotnetcore/CAP</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>博客系统（Blog）<a href="#博客系统blog"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>10</td><td></td><td></td><td></td></tr><tr><td>9</td><td></td><td></td><td></td></tr><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td><a href="https://github.com/lixinyang123/CoreHome" target="_blank">CoreHome</a></td><td>基于.NET8开源的个人博客项目，采用前后端分离、高并发、高可用的微服务架构，支持 MySQL、SqlServer、Redis 等多种数据库。</td><td><a href="https://github.com/lixinyang123/CoreHome" target="_blank">https://github.com/lixinyang123/CoreHome</a></td></tr><tr><td>6</td><td><a href="https://github.com/linkdotnet/Blog" target="_blank">LinkDotNet.Blog</a></td><td>基于C#和Blazor编写的博客引擎，旨在成为一个简单易用且易于扩展的博客平台。博客文章以Markdown格式编写，并渲染为HTML。</td><td><a href="https://github.com/linkdotnet/Blog" target="_blank">https://github.com/linkdotnet/Blog</a></td></tr><tr><td>5</td><td><a href="https://github.com/ldqk/Masuit.MyBlogs" target="_blank">Masuit.MyBlogs</a></td><td>基于C#/.NET8的 masuit.org个人博客站项目源码，高性能高安全性低占用的博客系统，仅3MB的代码量！ 目前日均处理请求数80-600w次，同时在线活跃用户数60-600人。</td><td><a href="https://github.com/ldqk/Masuit.MyBlogs" target="_blank">https://github.com/ldqk/Masuit.MyBlogs</a></td></tr><tr><td>4</td><td><a href="https://github.com/madskristensen/Miniblog.Core" target="_blank">Miniblog.Core</a></td><td>一个基于ASP.NET Core 7（3.1及以上版本）构建的功能齐全但简单易用的博客引擎。</td><td><a href="https://github.com/madskristensen/Miniblog.Core" target="_blank">https://github.com/madskristensen/Miniblog.Core</a></td></tr><tr><td>3</td><td><a href="https://github.com/blogifierdotnet/Blogifier" target="_blank">Blogifier</a></td><td>Blogifier 是一个使用 ASP.NET 和 Blazor WebAssembly 编写的开源发布平台。使用 Blogifier 可以创建个人博客或网站。</td><td><a href="https://github.com/blogifierdotnet/Blogifier" target="_blank">https://github.com/blogifierdotnet/Blogifier</a></td></tr><tr><td>2</td><td><a href="https://github.com/Deali-Axy/StarBlog" target="_blank">StarBlog</a></td><td>StarBlog是对Markdown支持友好的博客系统。基于.Net6 + Vue开发，遵循RESTFul接口规范，同时提供了一套从零开始开发的教程文章，可作为 .Net Core 入门项目学习。</td><td><a href="https://github.com/Deali-Axy/StarBlog" target="_blank">https://github.com/Deali-Axy/StarBlog</a></td></tr><tr><td>1</td><td><a href="https://github.com/EdiWang/Moonglade" target="_blank">Moonglade</a></td><td>Moonglade是一个专为开发人员优化的基于Microsoft Azure的.NET博客系统，提供了包括文章、评论、分类、归档、标签和页面等常见博客功能。</td><td><a href="https://github.com/EdiWang/Moonglade" target="_blank">https://github.com/EdiWang/Moonglade</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>办公系统（OA）<a href="#办公系统oa"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/HalngYao/MicroOA" target="_blank">MicroOA</a></td><td>MicroOA是一款基于C# asp.net 编写的OA系统，她不需要您具备专业的开发知识或开发经验，通过页面交互式即可实现动态搭建表单、动态搭建审批流的微型办公自动化系统，画面简洁清爽，功能强大。</td><td><a href="https://github.com/HalngYao/MicroOA" target="_blank">https://github.com/HalngYao/MicroOA</a></td></tr><tr><td>1</td><td><a href="https://gitee.com/qikj/QJ_Single" target="_blank">OneLotus</a></td><td>OneLotus信息化平台基于.NET 架构，能够很大程度上节约企业软件开发成本，用户可以直接使用平台已有功能进行信息化建设，框架提供了完整的用户管理，权限管理，表单引擎，流程引擎，报表引擎和信息管理体系，可以大大减化企业信息化建设成本和业务应用开发难度。</td><td><a href="https://www.yuque.com/yibulianhua/lotus/xx0iqe" target="_blank">https://www.yuque.com/yibulianhua/lotus/xx0iqe</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>媒体服务器系统（Media）<a href="#媒体服务器系统media"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/jellyfin/jellyfin" target="_blank">jellyfin</a></td><td>Jellyfin是一个免费软件媒体系统，让你完全控制管理和流媒体播放你的媒体文件。它是专有软件Emby和Plex的替代品，通过多个应用程序将媒体从专用服务器提供给最终用户设备。Jellyfin衍生自Emby的3.5.2版本，并移植到.NET Core框架，以实现完全的跨平台支持。</td><td><a href="https://github.com/jellyfin/jellyfin" target="_blank">https://github.com/jellyfin/jellyfin</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>自动化构建系统<a href="#自动化构建系统"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/cake-build/cake" target="_blank">cake</a></td><td>Cake是一个构建自动化系统，使用C# DSL来执行诸如编译代码、复制文件/文件夹、运行单元测试、压缩文件和构建NuGet包等任务。</td><td><a href="https://github.com/cake-build/cake" target="_blank">https://github.com/cake-build/cake</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>任务管理系统<a href="#任务管理系统"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/davidfowl/TodoApi" target="_blank">TodoApi</a></td><td>使用 ASP.NET Core Blazor WASM、Minimal APIs 和身份验证实现 Todo 应用程序。</td><td><a href="https://github.com/davidfowl/TodoApi" target="_blank">https://github.com/davidfowl/TodoApi</a></td></tr><tr><td>1</td><td><a href="https://github.com/YSGStudyHards/YyFlight.ToDoList" target="_blank">YyFlight.ToDoList</a></td><td>【.NET7 MongoDB 待办清单系统】.NET7 MongoDB从入门到实战基础教程，该项目后端使用的是.NET7、前端页面使用Blazor、使用MongoDB存储数据，更多相关内容大家可以看目录中的MongoDB从入门到实战的相关教程。该系列教程可作为.NET Core入门项目进行学习，感兴趣的小伙伴可以关注博主和我一起学习共同进步。</td><td><a href="https://github.com/YSGStudyHards/YyFlight.ToDoList" target="_blank">https://github.com/YSGStudyHards/YyFlight.ToDoList</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>进销存管理系统<a href="#进销存管理系统"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/go2ismail/Asp.Net-Core-Inventory-Order-Management-System" target="_blank">Inventory-Order-Management-System</a></td><td>这是一个示例项目，采用Asp.Net Core Mvc实现了库存订单管理系统。该系统包括仓库、产品、供应商、客户、采购订单、销售订单、出货、收货等功能。</td><td><a href="https://github.com/go2ismail/Asp.Net-Core-Inventory-Order-Management-System" target="_blank">https://github.com/go2ismail/Asp.Net-Core-Inventory-Order-Management-System</a></td></tr><tr><td>1</td><td><a href="https://gitee.com/a106_admin/tuling-member" target="_blank">TulingMember</a></td><td>使用.net6，基于 Furion +viewui开发的一套极简的进销存管理系统。</td><td><a href="https://gitee.com/a106_admin/tuling-member" target="_blank">https://gitee.com/a106_admin/tuling-member</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>在线考试系统<a href="#在线考试系统"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://gitee.com/pig0224/ExamKing" target="_blank">考试君</a></td><td>考试君 - 基于 .NET 6 语言的 Furion 框架在线考试系统。</td><td><a href="https://gitee.com/pig0224/ExamKing" target="_blank">https://gitee.com/pig0224/ExamKing</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>大屏幕&amp;报表系统<a href="#大屏幕报表系统"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td><a href="https://github.com/majorsilence/My-FyiReporting" target="_blank">My-FyiReporting</a></td><td>FYIReporting Designer是一个基于Microsoft的报表定义语言（RDL）的报表和图表系统。它完全支持表格、自由形式、矩阵和图表。支持HTML、PDF、XML、.Net控件和打印功能。可视化设计工具允许您无需了解RDL即可创建报表。还提供了向现有报表中插入新表格、矩阵和图表的向导。</td><td><a href="https://github.com/majorsilence/My-FyiReporting" target="_blank">https://github.com/majorsilence/My-FyiReporting</a></td></tr><tr><td>3</td><td><a href="https://github.com/ariacom/Seal-Report" target="_blank">Seal-Report</a></td><td>Seal Report &amp; ETL是一个开源的、基于Microsoft .Net平台的工具，用于从任何数据库或No SQL数据源生成日报表并执行复杂ETL操作，注重简单安装和报表设计。</td><td><a href="https://github.com/ariacom/Seal-Report" target="_blank">https://github.com/ariacom/Seal-Report</a></td></tr><tr><td>2</td><td><a href="https://github.com/FastReports/FastReport" target="_blank">FastReport</a></td><td>适用于 .NET6/.NET Core/.NET Framework 的免费开源报告工具，可帮助您的应用程序生成类似文档的报告。</td><td><a href="https://github.com/FastReports/FastReport" target="_blank">https://github.com/FastReports/FastReport</a></td></tr><tr><td>1</td><td><a href="https://gitee.com/NoneDay/CellReport" target="_blank">CellReport</a></td><td>CellReport 是一个以复杂中国式报表为核心目标的制作、运行工具，可以让任意net程序具有js脚本功能。支持数据看板、大屏制作。你可以使用数据库、excel文件、api服务、已有报表等为数据源，通过内置的集合函数组织数据，以类excel界面设计最终呈现结果。</td><td><a href="https://gitee.com/NoneDay/CellReport" target="_blank">https://gitee.com/NoneDay/CellReport</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>文档管理系统<a href="#文档管理系统"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/dorisoy/Dorisoy.Pan" target="_blank">Dorisoy.Pan</a></td><td>Dorisoy.Pan 是基于.net core5的跨平台文档管理系统，使用 MS SQL 2012 / MySql8.0（或更高版本）后端数据库，您可以在Windows、Linux 或Mac上运行它,项目中的所有方法都是异步的,支持令牌基身份验证,项目体系结构遵循著名的软件模式和最佳安全实践。</td><td><a href="https://github.com/dorisoy/Dorisoy.Pan" target="_blank">https://github.com/dorisoy/Dorisoy.Pan</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>访客管理系统<a href="#访客管理系统"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/neozhu/visitormanagement" target="_blank">visitormanagement</a></td><td>智能访客管理系统及门卫登记设备，可以安全可靠地进行来访人员管理，主要提供上传健康码，行程码，核酸报告和多级审批功能，不仅可以保障各个单位的安全，更可以提高企事业单位的电子化访客登记水平和形象。</td><td><a href="https://github.com/neozhu/visitormanagement" target="_blank">https://github.com/neozhu/visitormanagement</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>医疗管理系统<a href="#医疗管理系统"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/zjxi/HospitalManagementSystem-WPF" target="_blank">HospitalManagementSystem-WPF</a></td><td>医疗信息管理系统，基于WPF (XAML前端+C#后台)，内附SQL Server 2012数据库，界面友好，功能实用。</td><td><a href="https://github.com/zjxi/HospitalManagementSystem-WPF" target="_blank">https://github.com/zjxi/HospitalManagementSystem-WPF</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>数据库系统<a href="#数据库系统"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/microsoft/garnet" target="_blank">Garnet</a></td><td>Garnet是一款由微软研究院基于.NET开源的高性能、跨平台的分布式缓存存储数据库，该项目提供强大的性能（吞吐量和延迟）、可扩展性、存储、恢复、集群分片、密钥迁移和复制功能。并且无需做任何修改可以与现有的 Redis 客户端配合使用。</td><td><a href="https://microsoft.github.io/garnet/docs" target="_blank">https://microsoft.github.io/garnet/docs</a></td></tr><tr><td>1</td><td><a href="https://github.com/mbdavid/LiteDB" target="_blank">LiteDB</a></td><td>LiteDB 一个小巧、快速、轻量级的 NoSQL 嵌入式数据库。</td><td><a href="https://github.com/mbdavid/LiteDB" target="_blank">https://github.com/mbdavid/LiteDB</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>其他开源项目<a href="#其他开源项目"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td></td><td></td><td></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section></section><section><h3>实用工具&amp;软件<a href="#实用工具软件"><span>#</span></a></h3><section><h4>桌面工具箱<a href="#桌面工具箱"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td></td><td></td><td></td></tr><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>6</td><td><a href="https://github.com/veler/DevToys" target="_blank">DevToys</a></td><td>C#开源（MIT License开源协议）、免费、离线、功能齐全的Windows开发者工具箱，号称开发人员的瑞士军刀，可以帮助开发者完成日常工作开发中常用功能。</td><td><a href="https://github.com/veler/DevToys" target="_blank">https://github.com/veler/DevToys</a></td></tr><tr><td>5</td><td><a href="https://github.com/microsoft/PowerToys" target="_blank">PowerToys</a></td><td>微软官方发布的C#开源、免费、实用的Windows工具箱，帮助用户调整和简化Windows系统的体验，从而提高工作效率。</td><td><a href="https://github.com/microsoft/PowerToys" target="_blank">https://github.com/microsoft/PowerToys</a></td></tr><tr><td>4</td><td><a href="https://github.com/DGP-Studio/Snap.Hutao" target="_blank">Snap.Hutao</a></td><td>胡桃工具箱是一款.NET开源（MIT License）、免费、实用的多功能原神工具箱，专为现代化 Windows 平台设计，旨在改善桌面端玩家的游戏体验。通过将既有的官方资源与开发团队设计的全新功能相结合，它提供了一套完整且实用的工具集，且无需依赖任何移动设备。它不对游戏客户端进行任何破坏性修改以确保工具箱的安全性。</td><td><a href="https://github.com/DGP-Studio/Snap.Hutao" target="_blank">https://github.com/DGP-Studio/Snap.Hutao</a></td></tr><tr><td>3</td><td><a href="https://github.com/BeyondDimension/SteamTools" target="_blank">SteamTools</a></td><td>一个开源跨平台的多功能 Steam 工具箱（是一个开源跨平台的多功能游戏工具箱，此工具的大部分功能都是需要您下载安装 Steam 才能使用）。</td><td><a href="https://github.com/BeyondDimension/SteamTools" target="_blank">https://github.com/BeyondDimension/SteamTools</a></td></tr><tr><td>2</td><td><a href="https://github.com/landv/LuYao.Toolkit" target="_blank">LuYao.Toolkit</a></td><td>路遥工具箱是笔者在学习 WPF 时练手所作的一个小工具，主要用于解决一些开发过程中常见的功能性需求，并将其自动化。截至目前，本工具已拥有十数项功能。</td><td><a href="https://github.com/landv/LuYao.Toolkit" target="_blank">https://github.com/landv/LuYao.Toolkit</a></td></tr><tr><td>1</td><td><a href="https://github.com/QiBowen2008/SuperTextToolBox" target="_blank">SuperTextToolBox</a></td><td>C#开源的一个免费的文字处理工具箱（功能包括OCR识别、文字转语音、词云生成、文字转拼音、翻译、分词等功能（除了翻译功能均可以离线使用））。</td><td><a href="https://github.com/QiBowen2008/SuperTextToolBox" target="_blank">https://github.com/QiBowen2008/SuperTextToolBox</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>桌面启动器<a href="#桌面启动器"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/OrgEleCho/CurvaLauncher" target="_blank">CurvaLauncher</a></td><td>一款WPF开源、简单、轻便、快速的桌面启动器（支持多主题、多语言：简体中文、繁体中文、英文等）。</td><td><a href="https://github.com/OrgEleCho/CurvaLauncher" target="_blank">https://github.com/OrgEleCho/CurvaLauncher</a></td></tr><tr><td>1</td><td><a href="https://github.com/Flow-Launcher/Flow.Launcher" target="_blank">Flow Launcher</a></td><td>Flow Launcher是一款.NET开源（MIT License）、免费、功能强大的Windows快速文件搜索和应用程序启动器，能够帮助你快速查找文件、启动应用程序和执行系统操作，提高工作效率和操作便利性。并且生态完善，有插件商店，你可以查看完整的插件列表，或通过”设置”中的”插件商店”菜单快速安装插件。</td><td><a href="https://github.com/Flow-Launcher/Flow.Launcher" target="_blank">https://github.com/Flow-Launcher/Flow.Launcher</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>反编译工具<a href="#反编译工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td></td><td></td><td></td></tr><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td><a href="https://github.com/dnSpyEx/dnSpy" target="_blank">dnSpyEx</a></td><td>dnSpyEx是dnSpy（该代码库已于2020年12月21日被所有者归档为只读状态）项目的非官方Fork维护版本，一款开源、功能强大的.NET反编译工具和调试器，可用于在没有源代码的情况下编辑和调试程序集。</td><td><a href="https://github.com/dnSpyEx/dnSpy" target="_blank">https://github.com/dnSpyEx/dnSpy</a></td></tr><tr><td>3</td><td><a href="https://github.com/icsharpcode/ILSpy" target="_blank">ILSpy</a></td><td>ILSpy是一款免费、开源的 .NET 反编译工具，能够将已编译的 .NET 程序集转换为易于阅读和理解的源代码。</td><td><a href="https://github.com/icsharpcode/ILSpy" target="_blank">https://github.com/icsharpcode/ILSpy</a></td></tr><tr><td>2</td><td><a href="https://github.com/dnSpy/dnSpy" target="_blank">dnSpy</a></td><td>dnSpy是一个功能强大的调试器和.NET程序集编辑器，可用于在没有源代码的情况下编辑和调试程序集。（虽然dnSpy该代码库已于2020年12月21日被所有者归档为只读状态，但这并不影响你继续使用dnSpy工具本身。）</td><td><a href="https://github.com/dnSpy/dnSpy" target="_blank">https://github.com/dnSpy/dnSpy</a></td></tr><tr><td>1</td><td><a href="https://github.com/dotNetTreasury/JustDecompileEngine" target="_blank">JustDecompile</a></td><td>JustDecompile是一款功能强大的.NET反编译工具，可帮助您恢复丢失的源代码或查看程序集的内部结构。</td><td><a href="https://github.com/dotNetTreasury/JustDecompileEngine" target="_blank">https://github.com/dotNetTreasury/JustDecompileEngine</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>代码混淆工具<a href="#代码混淆工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td></td><td></td><td></td></tr><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td><a href="https://github.com/dcsoft-yyf/JIEJIE.NET" target="_blank">IEJIE.NET</a></td><td>JIEJIE.NET是一个开源的.NET程序集混淆工具，旨在帮助保护.NET应用程序的版权和知识产权。它被描述为轻量级、快速且强大。该项目的主要目标是通过对程序集进行混淆，使其难以逆向工程和分析，从而增加代码的保护程度。</td><td><a href="https://github.com/dcsoft-yyf/JIEJIE.NET" target="_blank">https://github.com/dcsoft-yyf/JIEJIE.NET</a></td></tr><tr><td>2</td><td><a href="https://github.com/obfuscar/obfuscar" target="_blank">Obfuscar</a></td><td>Obfuscar是一个开源的.NET程序集混淆工具，可以通过控制流和名称混淆、字符串加密、资源保护等功能来保护.NET应用程序的知识产权和防止逆向工程。</td><td><a href="https://github.com/obfuscar/obfuscar" target="_blank">https://github.com/obfuscar/obfuscar</a></td></tr><tr><td>1</td><td><a href="https://github.com/mkaring/ConfuserEx" target="_blank">ConfuserEx</a></td><td>ConfuserEx是一个功能强大且广泛使用的.NET代码混淆工具。它支持多种混淆技术，包括控制流混淆、字符串加密、资源加密等。它具有灵活的配置选项，可以根据不同的需求进行定制（不足的是目前只支持.NET Framework 2.0/3.0/3.5/4.0/4.5/4.6/4.7/4.8，不支持.NET Core代码混淆）。</td><td><a href="https://github.com/mkaring/ConfuserEx" target="_blank">https://github.com/mkaring/ConfuserEx</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>桌面管理工具<a href="#桌面管理工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/he55/DreamScene2" target="_blank">DreamScene2</a></td><td>.NET开源、免费（MIT license）的一个小而快并且功能强大的 Windows 动态桌面软件，支持视频和网页动画播放，支持 Windows10/11 系统。</td><td><a href="https://github.com/he55/DreamScene2" target="_blank">https://github.com/he55/DreamScene2</a></td></tr><tr><td>1</td><td><a href="https://github.com/BookerLiu/GeekDesk" target="_blank">GeekDesk</a></td><td>一款.NET开源的小巧、美观的桌面快速启动工具（GeekDesk 极客桌面）。</td><td><a href="https://github.com/BookerLiu/GeekDesk" target="_blank">https://github.com/BookerLiu/GeekDesk</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>文件管理工具<a href="#文件管理工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/QL-Win/QuickLook" target="_blank">QuickLook</a></td><td>QuickLook是一款在Windows操作系统上的实用工具，它提供了一种快速预览文件内容的方式。通过使用QuickLook，用户可以在不打开文件的情况下，直接在文件资源管理器中快速查看文件的内容。</td><td><a href="https://github.com/QL-Win/QuickLook" target="_blank">https://github.com/QL-Win/QuickLook</a></td></tr><tr><td>1</td><td><a href="https://github.com/files-community/Files" target="_blank">Files</a></td><td>一款.NET开源的、简洁、易用的Windows文件管理器。</td><td><a href="https://github.com/files-community/Files" target="_blank">https://github.com/files-community/Files</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>远程桌面工具<a href="#远程桌面工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td></td><td></td><td></td></tr><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td><a href="https://github.com/immense/Remotely" target="_blank">Remotely</a></td><td>一个基于.NET 8、Blazor和SignalR构建的远程控制和远程脚本解决方案。</td><td><a href="https://github.com/immense/Remotely" target="_blank">https://github.com/immense/Remotely</a></td></tr><tr><td>3</td><td><a href="https://gitee.com/dotnetchina/SiMayRemoteMonitorOS" target="_blank">SiMayRemoteMonitorOS</a></td><td>SiMay远程控制管理系统是一个Windows远程控制系统，底层基于IOCP的异步通信模型，实时监控海量客户端，目前功能已实现：逐行扫描远程桌面协助、经典的文件管理、实时远程语音、实时摄像头、经典注册表管理、命令行终端、实时系统进程管理、用户桌面视图墙轮播等功能。并且可捕获UAC,WinLogon桌面。系统实现了中间会话服务器，可支持不同平台多主控端同时监控同一被控端。被控服务端支持绿色启动及以系统服务方式安装，项目完全采用C#.NET开发，代码仅供参考，项目不定时更新。</td><td><a href="https://gitee.com/dotnetchina/SiMayRemoteMonitorOS" target="_blank">https://gitee.com/dotnetchina/SiMayRemoteMonitorOS</a></td></tr><tr><td>2</td><td><a href="https://github.com/xunki/RemoteDesktopManage" target="_blank">RemoteDesktopManage</a></td><td>基于 MSTSC 连接 Windows 远程桌面，并对其进行封装实现管理多个远程桌面配置的小工具。</td><td><a href="https://github.com/xunki/RemoteDesktopManage" target="_blank">https://github.com/xunki/RemoteDesktopManage</a></td></tr><tr><td>1</td><td><a href="https://github.com/1Remote/1Remote" target="_blank">1Remote</a></td><td>一款由.NET开源且免费的远程桌面管理软件。</td><td><a href="https://github.com/1Remote/1Remote" target="_blank">https://github.com/1Remote/1Remote</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>数据管理工具<a href="#数据管理工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://gitee.com/dotnetchina/SmartSQL" target="_blank">SmartSQL</a></td><td>一款方便、快捷的数据库文档查询、生成工具，致力于成为帮助企业快速实现数字化转型的元数据管理工具。</td><td><a href="https://gitee.com/dotnetchina/SmartSQL" target="_blank">https://gitee.com/dotnetchina/SmartSQL</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>DNS服务器工具<a href="#dns服务器工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/TechnitiumSoftware/DnsServer" target="_blank">Technitium DNS Server</a></td><td>一款.NET开源跨平台的开箱即用的DNS服务器软件（用于提供 DNS 解析服务）。</td><td><a href="https://github.com/TechnitiumSoftware/DnsServer" target="_blank">https://github.com/TechnitiumSoftware/DnsServer</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>截图&amp;录屏工具<a href="#截图录屏工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/ShareX/ShareX" target="_blank">ShareX</a></td><td>一款.NET开源免费（基于GPL3.0开源协议）、功能强大、简洁灵活的 Windows 截图、录屏、Gif动图制作神器。</td><td><a href="https://github.com/ShareX/ShareX" target="_blank">https://github.com/ShareX/ShareX</a></td></tr><tr><td>1</td><td><a href="https://github.com/NickeManarin/ScreenToGif" target="_blank">ScreenToGif</a></td><td>一款由C#语言开发且开源的操作简单、免费的屏幕录制和GIF动画制作神器。</td><td><a href="https://github.com/NickeManarin/ScreenToGif" target="_blank">https://github.com/NickeManarin/ScreenToGif</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>GitHub加速工具<a href="#github加速工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/BeyondDimension/SteamTools" target="_blank">SteamTools</a></td><td>一款C#开源的、跨平台的GitHub加速神器。</td><td><a href="https://github.com/BeyondDimension/SteamTools" target="_blank">https://github.com/BeyondDimension/SteamTools</a></td></tr><tr><td>1</td><td><a href="https://github.com/dotNetTreasury/FastGithub" target="_blank">FastGithub</a></td><td>GitHub加速神器，解决GitHub打不开、用户头像无法加载、releases无法上传下载、git-clone、git-pull、git-push失败等问题。</td><td><a href="https://github.com/dotNetTreasury/FastGithub" target="_blank">https://github.com/dotNetTreasury/FastGithub</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>系统优化工具<a href="#系统优化工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/IgorMundstein/WinMemoryCleaner" target="_blank">WinMemoryCleaner</a></td><td>一款小巧、便携、智能、免费的Windows内存清理工具，使用Windows原生功能优化内存空间。</td><td><a href="https://github.com/IgorMundstein/WinMemoryCleaner" target="_blank">https://github.com/IgorMundstein/WinMemoryCleaner</a></td></tr><tr><td>1</td><td><a href="https://github.com/hellzerg/optimizer" target="_blank">Optimizer</a></td><td>Optimizer是一款功能强大的Windows系统优化工具，可帮助用户提高计算机性能、加强隐私和安全保护。该工具支持22种语言，同时提供了许多实用的功能，如关闭不必要的Windows服务、停止Windows自动更新、卸载UWP应用、清理系统垃圾文件和浏览器配置文件、修复常见的注册表问题等。此外，Optimizer还提供了硬件检测工具、IP连通性和延迟测试工具、快速更改DNS服务器、编辑HOSTS文件、识别和终止文件锁定句柄等实用工具。</td><td><a href="https://github.com/hellzerg/optimizer" target="_blank">https://github.com/hellzerg/optimizer</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>性能压测工具<a href="#性能压测工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/dotnet/crank" target="_blank">Crank</a></td><td>Crank是一个用于测量Web应用性能和稳定性的工具。它提供了一种简单的方法，用于构建针对Web应用的基准测试和负载测试，并提供了一个可视化仪表板，用于监控测试结果和Web应用的状态。</td><td><a href="https://github.com/dotnet/crank" target="_blank">https://github.com/dotnet/crank</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>性能分析工具<a href="#性能分析工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/microsoft/perfview" target="_blank">PerfView</a></td><td>PerfView 是一款免费的性能分析工具，可帮助隔离与 CPU 和内存相关的性能问题。它是一个 Windows 工具，但它也支持分析在 Linux 机器上收集的数据。它适用于各种方案，但具有许多特殊功能，用于调查为 .NET 运行时编写的代码中的性能问题。</td><td><a href="https://github.com/microsoft/perfview" target="_blank">https://github.com/microsoft/perfview</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>Excel转JSON工具<a href="#excel转json工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/neil3d/excel2json" target="_blank">excel2json</a></td><td>.NET开源的把Excel表转换成json对象，并保存到一个文本文件中。</td><td><a href="https://github.com/neil3d/excel2json" target="_blank">https://github.com/neil3d/excel2json</a></td></tr><tr><td>1</td><td><a href="https://github.com/brianlagunas/Excel2Json" target="_blank">Excel2Json</a></td><td>Excel转JSON - 将Excel和CSV转换为JSON。</td><td><a href="https://github.com/brianlagunas/Excel2Json" target="_blank">https://github.com/brianlagunas/Excel2Json</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>免费的抢票软件<a href="#免费的抢票软件"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://www.bypass.cn/" target="_blank">Bypass</a></td><td>Bypass是一款基于.NET开发的、完全免费的火车票分流抢票软件，全程自动抢票、自动抢候补、自动识别验证码、多线程秒单、稳定捡漏。支持多天、多车次、多席别、多乘客等功能。</td><td><a href="https://www.bypass.cn/" target="_blank">https://www.bypass.cn/</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>Office实用工具<a href="#office实用工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td><a href="https://github.com/wmjordan/PDFPatcher" target="_blank">PDFPatcher</a></td><td>C#开源的一个 PDF 处理工具，可以编辑书签、剪裁旋转页面、解除限制、提取或合并文档，探查文档结构，提取图片、转成图片等等。</td><td><a href="https://github.com/wmjordan/PDFPatcher" target="_blank">https://github.com/wmjordan/PDFPatcher</a></td></tr><tr><td>4</td><td><a href="https://github.com/OdysseusYuan/Mocreak" target="_blank">Mocreak</a></td><td>基于 LKY_OfficeTools 构建的图形化版本。一键自动化下载、安装、部署 Office 正版的办公增强工具。该工具完全免费、无广告、绿色、无毒、简约、高效、安全。</td><td><a href="https://github.com/OdysseusYuan/Mocreak" target="_blank">https://github.com/OdysseusYuan/Mocreak</a></td></tr><tr><td>3</td><td><a href="https://github.com/jm33-m0/kms-activate" target="_blank">kms-activate</a></td><td>Microsoft Windows/Office 一键激活工具。</td><td><a href="https://github.com/jm33-m0/kms-activate" target="_blank">https://github.com/jm33-m0/kms-activate</a></td></tr><tr><td>2</td><td><a href="https://github.com/YerongAI/Office-Tool" target="_blank">Office Tool Plus</a></td><td>Office Tool Plus是一个强大且实用的Office部署工具，你也可以使用其他功能、小工具快捷、可以方便地激活和管理Office。</td><td><a href="https://github.com/YerongAI/Office-Tool" target="_blank">https://github.com/YerongAI/Office-Tool</a></td></tr><tr><td>1</td><td><a href="https://github.com/OdysseusYuan/LKY_OfficeTools" target="_blank">LKY_OfficeTools</a></td><td>一款.NET开源、绿色、安全、无毒的支持一键自动化下载、安装、激活Microsoft Office的利器。</td><td><a href="https://github.com/OdysseusYuan/LKY_OfficeTools" target="_blank">https://github.com/OdysseusYuan/LKY_OfficeTools</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>Git管理工具<a href="#git管理工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/gitextensions/gitextensions" target="_blank">Git Extensions</a></td><td>Git Extensions是一个.NET开源、免费的用于管理 Git 存储库的独立 UI 工具，它还与 Windows 资源管理器和 Microsoft Visual Studio (2015/2017/2019) 集成。</td><td><a href="https://github.com/gitextensions/gitextensions" target="_blank">https://github.com/gitextensions/gitextensions</a></td></tr><tr><td>1</td><td><a href="https://github.com/sourcegit-scm/sourcegit" target="_blank">SourceGit</a></td><td>一款.NET Avalonia开源、免费、跨平台、快速的Git可视化管理工具。</td><td><a href="https://github.com/sourcegit-scm/sourcegit" target="_blank">https://github.com/sourcegit-scm/sourcegit</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>通讯调试工具<a href="#通讯调试工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/chenxuuu/llcom" target="_blank">LLCOM</a></td><td>LLCOM是一个.NET开源的、功能强大的串口调试工具。支持Lua自动化处理、串口调试、串口监听、串口曲线、TCP测试、MQTT测试、编码转换、乱码恢复等功能。</td><td><a href="https://github.com/chenxuuu/llcom" target="_blank">https://github.com/chenxuuu/llcom</a></td></tr><tr><td>1</td><td><a href="https://github.com/Monika1313/Wu.CommTool" target="_blank">Wu.CommTool</a></td><td>基于C#、WPF、Prism、MaterialDesign、HandyControl开发的通讯调试工具，支持Modbus RTU、MQTT调试，界面色彩丰富。</td><td><a href="https://github.com/Monika1313/Wu.CommTool" target="_blank">https://github.com/Monika1313/Wu.CommTool</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>翻译工具<a href="#翻译工具"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/ZGGSONG/STranslate" target="_blank">STranslate</a></td><td>一款由WPF开源的、免费的（MIT License）、即开即用、即用即走的翻译、OCR工具。</td><td><a href="https://github.com/ZGGSONG/STranslate" target="_blank">https://github.com/ZGGSONG/STranslate</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>其他工具&amp;软件<a href="#其他工具软件"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>30</td><td></td><td></td><td></td></tr><tr><td>29</td><td></td><td></td><td></td></tr><tr><td>28</td><td></td><td></td><td></td></tr><tr><td>27</td><td></td><td></td><td></td></tr><tr><td>26</td><td></td><td></td><td></td></tr><tr><td>25</td><td></td><td></td><td></td></tr><tr><td>24</td><td></td><td></td><td></td></tr><tr><td>24</td><td><a href="https://github.com/BluePointLilac/ContextMenuManager" target="_blank">ContextMenuManager</a></td><td>C#开源免费的一个纯粹的Windows右键菜单管理工具。</td><td><a href="https://github.com/BluePointLilac/ContextMenuManager" target="_blank">https://github.com/BluePointLilac/ContextMenuManager</a></td></tr><tr><td>23</td><td><a href="https://github.com/hitchao/Jvedio" target="_blank">Jvedio</a></td><td>Jvedio是.NET开源、功能强大的本地视频管理软件，支持扫描本地视频并导入软件，建立视频库，提取出视频的唯一识别码，自动分类视频，添加标签管理视频，使用人工智能识别演员，支持翻译信息，基于FFmpeg截取视频图片，Window桌面端流畅美观的应用软件。Jvedio 是本地视频管理软件，支持扫描本地视频并导入软件，建立视频库， 提取出视频的 唯一识别码，自动分类视频， 添加标签管理视频，使用人工智能识别演员，支持翻译信息， 基于 FFmpeg 截取视频图片，Window 桌面端流畅美观的应用软件。</td><td><a href="https://github.com/hitchao/Jvedio" target="_blank">https://github.com/hitchao/Jvedio</a></td></tr><tr><td>22</td><td><a href="https://github.com/0x5bfa/FluentHub" target="_blank">FluentHub</a></td><td>一个.NET开源（MIT License）、免费、时尚、功能强大的 Windows GitHub 客户端。</td><td><a href="https://github.com/0x5bfa/FluentHub" target="_blank">https://github.com/0x5bfa/FluentHub</a></td></tr><tr><td>21</td><td><a href="https://github.com/Clean-Reader/CleanReader.Desktop" target="_blank">CleanReader.Desktop</a></td><td>一款.NET开源、免费、简洁易用的Windows桌面小说阅读应用(是原生的 Windows 应用，为 Windows 11 系统设计)。</td><td><a href="https://github.com/Clean-Reader/CleanReader.Desktop" target="_blank">https://github.com/Clean-Reader/CleanReader.Desktop</a></td></tr><tr><td>20</td><td><a href="https://github.com/AlexanderPro/SmartSystemMenu" target="_blank">SmartSystemMenu</a></td><td>.NET开源、免费（MIT License）、功能丰富、灵活易用、小巧（不到1M）的 Windows 窗口增强工具。</td><td><a href="https://github.com/AlexanderPro/SmartSystemMenu" target="_blank">https://github.com/AlexanderPro/SmartSystemMenu</a></td></tr><tr><td>19</td><td><a href="https://github.com/belav/csharpier" target="_blank">CSharpier</a></td><td>一款由.NET开源、免费（MIT License）、轻量级的C#语言代码格式化工具，它使用Roslyn来解析你的代码，并根据其自身的规则重新格式化代码。</td><td><a href="https://github.com/belav/csharpier" target="_blank">https://github.com/belav/csharpier</a></td></tr><tr><td>18</td><td><a href="https://github.com/yswenli/WebRedisManager" target="_blank">WebRedisManager</a></td><td>WebRedisManager是一个.NET开源、免费的Redis可视化工具，这是一个支持在浏览器上进行查看管理 Redis的工具（实现Redis的简便管理功能）。</td><td><a href="https://github.com/yswenli/WebRedisManager" target="_blank">https://github.com/yswenli/WebRedisManager</a></td></tr><tr><td>17</td><td><a href="https://github.com/Coolapk-UWP/Coolapk-UWP" target="_blank">Coolapk UWP</a></td><td>一款UWP平台开源的第三方酷安（一个泛科技数码社区）客户端应用。</td><td><a href="https://github.com/Coolapk-UWP/Coolapk-UWP" target="_blank">https://github.com/Coolapk-UWP/Coolapk-UWP</a></td></tr><tr><td>16</td><td><a href="https://github.com/Giorgi/EFCore.Visualizer" target="_blank">EFCore.Visualizer</a></td><td>C#开源的一款EF Core查询计划调试器可视化工具。</td><td><a href="https://github.com/Giorgi/EFCore.Visualizer" target="_blank">https://github.com/Giorgi/EFCore.Visualizer</a></td></tr><tr><td>15</td><td><a href="https://github.com/nor0x/Dots" target="_blank">Dots</a></td><td>Dots 是一款 .NET SDK 管理器，可让您轻松安装、卸载和切换 .NET SDK。它是一款跨平台工具，可在 Windows 和 macOS 上运行，即将支持 Linux。它由 C# 编写，使用 Avalonia 作为 .NET UI 框架。</td><td><a href="https://github.com/nor0x/Dots" target="_blank">https://github.com/nor0x/Dots</a></td></tr><tr><td>14</td><td><a href="https://github.com/bezzad/Downloader" target="_blank">Downloader</a></td><td>快速、跨平台且可靠的多部分下载器，具有适用于 .NET 应用程序的异步进度事件。</td><td><a href="https://github.com/bezzad/Downloader" target="_blank">https://github.com/bezzad/Downloader</a></td></tr><tr><td>13</td><td><a href="https://github.com/reactiveui/Camelotia" target="_blank">Camelotia</a></td><td>Camelotia是一个云存储文件管理器，目前支持Yandex Disk、Google Drive、VK Documents、GitHub、FTP、SFTP和本地文件系统。该应用程序可在Windows、Linux、MacOS、XBox、Surface Hub和HoloLens上运行。</td><td><a href="https://github.com/reactiveui/Camelotia" target="_blank">https://github.com/reactiveui/Camelotia</a></td></tr><tr><td>12</td><td><a href="https://github.com/Code52/DownmarkerWPF" target="_blank">DownmarkerWPF</a></td><td>DownmarkerWPF是一个基于WPF技术的Markdown编辑器。</td><td><a href="https://github.com/Code52/DownmarkerWPF" target="_blank">https://github.com/Code52/DownmarkerWPF</a></td></tr><tr><td>11</td><td><a href="https://github.com/Richasy/Bili.Uwp" target="_blank">Bili.Uwp</a></td><td>哔哩 是一款 哔哩哔哩 的第三方应用，使用 UWP 框架开发，是原生的 Windows 应用，支持 Windows 10/11 桌面系统。</td><td><a href="https://github.com/Richasy/Bili.Uwp" target="_blank">https://github.com/Richasy/Bili.Uwp</a></td></tr><tr><td>10</td><td><a href="https://github.com/RayWangQvQ/BiliBiliToolPro" target="_blank">BiliBiliToolPro</a></td><td>BiliBiliTool 是一个自动执行任务的工具，当我们忘记做某项任务时，它会像一个贴心小助手，按照我们预先吩咐它的命令，在指定频率、时间范围内帮助我们完成计划的任务。</td><td><a href="https://github.com/RayWangQvQ/BiliBiliToolPro" target="_blank">https://github.com/RayWangQvQ/BiliBiliToolPro</a></td></tr><tr><td>9</td><td><a href="https://github.com/Uahh/ToastFish" target="_blank">ToastFish</a></td><td>一个利用Windows通知栏背单词的软件。</td><td><a href="https://github.com/Uahh/ToastFish" target="_blank">https://github.com/Uahh/ToastFish</a></td></tr><tr><td>8</td><td><a href="https://github.com/Accelerider/Accelerider.Windows" target="_blank">Accelerider.Windows</a></td><td>Accelerider.Windows是一个方便、强大的工具，为用户在Windows平台上使用Accelerider提供了便利。</td><td><a href="https://github.com/Accelerider/Accelerider.Windows" target="_blank">https://github.com/Accelerider/Accelerider.Windows</a></td></tr><tr><td>7</td><td><a href="https://github.com/E9C50/KTV" target="_blank">KTV</a></td><td>KTV系统，C#前后台，Android客户端。播放器使用迅雷开源APlayer播放引擎。</td><td><a href="https://github.com/E9C50/KTV" target="_blank">https://github.com/E9C50/KTV</a></td></tr><tr><td>6</td><td><a href="https://github.com/Yu-Core/SwashbucklerDiary" target="_blank">SwashbucklerDiary</a></td><td>SwashbucklerDiary「 侠客日记 」是一个.NET开源、跨平台的本地日记APP。</td><td><a href="https://github.com/Yu-Core/SwashbucklerDiary" target="_blank">https://github.com/Yu-Core/SwashbucklerDiary</a></td></tr><tr><td>5</td><td><a href="https://github.com/944095635/DMSkin-CloudMusic" target="_blank"> DMSkin-CloudMusic</a></td><td>网易云音乐-用WPF来做网易云音乐客户端。</td><td><a href="https://github.com/944095635/DMSkin-CloudMusic" target="_blank">https://github.com/944095635/DMSkin-CloudMusic</a></td></tr><tr><td>4</td><td><a href="https://github.com/flytkgl/PDFQFZ" target="_blank">PDFQFZ</a></td><td>PDF加盖骑缝章的小工具。</td><td><a href="https://github.com/flytkgl/PDFQFZ" target="_blank">https://github.com/flytkgl/PDFQFZ</a></td></tr><tr><td>3</td><td><a href="https://github.com/LorisYounger/VPet" target="_blank">VPet</a></td><td>一款C#开源的虚拟桌宠模拟器，一个开源的桌宠软件可以内置到任何WPF应用程序。</td><td><a href="https://github.com/LorisYounger/VPet" target="_blank">https://github.com/LorisYounger/VPet</a></td></tr><tr><td>2</td><td><a href="https://github.com/Planshit/Tai" target="_blank">Tai</a></td><td>一款.NET开源的在Windows上统计软件使用时长和网站浏览时长工具。</td><td><a href="https://github.com/Planshit/Tai" target="_blank">https://github.com/Planshit/Tai</a></td></tr><tr><td>1</td><td><a href="https://github.com/huiyadanli/RevokeMsgPatcher" target="_blank">RevokeMsgPatcher</a></td><td>一款.NET开源的适用于 Windows 下 PC 版微信/QQ/TIM的防撤回补丁。</td><td><a href="https://github.com/huiyadanli/RevokeMsgPatcher" target="_blank">https://github.com/huiyadanli/RevokeMsgPatcher</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section></section><section><h3>实用SDK&amp;类库<a href="#实用sdk类库"><span>#</span></a></h3><section><h4>C#版微信SDK<a href="#c版微信sdk"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td><a href="https://github.com/xin-lai/Magicodes.Wx.Sdk" target="_blank">Magicodes.Wx.Sdk</a></td><td>最简洁最易于使用的微信Sdk，包括公众号Sdk、小程序Sdk、企业微信Sdk等，以及Abp VNext集成。</td><td><a href="https://github.com/xin-lai/Magicodes.Wx.Sdk" target="_blank">https://github.com/xin-lai/Magicodes.Wx.Sdk</a></td></tr><tr><td>3</td><td><a href="https://github.com/JeffreySu/WeiXinMPSDK" target="_blank">WeiXinMPSDK</a></td><td>微信全平台 SDK Senparc.Weixin for C#，支持 .NET Framework 及 .NET Core、.NET 6.0、.NET 7.0。已支持微信公众号、小程序、小游戏、微信支付、企业微信/企业号、开放平台、JSSDK、微信周边等全平台。</td><td><a href="https://github.com/JeffreySu/WeiXinMPSDK" target="_blank">https://github.com/JeffreySu/WeiXinMPSDK</a></td></tr><tr><td>2</td><td><a href="https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat" target="_blank">SKIT.FlurlHttpClient.Wechat</a></td><td>全网最完整的 C# 版微信 SDK，封装全部已知的微信 API，包含微信公众平台（订阅号+服务号+小程序+小游戏+小商店+视频号）、微信开放平台、微信商户平台（微信支付+微企付）、企业微信、微信广告平台、微信智能对话开放平台等模块，可跨平台。</td><td><a href="https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat" target="_blank">https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat</a></td></tr><tr><td>1</td><td><a href="https://github.com/EasyAbp/Abp.WeChat" target="_blank">Abp.WeChat</a></td><td>Abp 微信 SDK 模块，包含对微信小程序、公众号、企业微信、开放平台、第三方平台等相关接口封装。</td><td><a href="https://github.com/EasyAbp/Abp.WeChat" target="_blank">https://github.com/EasyAbp/Abp.WeChat</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>C#实用工具类库<a href="#c实用工具类库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td><a href="https://github.com/zzzprojects/Z.ExtensionMethods" target="_blank">Z.ExtensionMethods</a></td><td>C#开源实用的工具类库，集成超过1000多种扩展方法增强 .NET Framework 和 .NET Core的使用效率。</td><td><a href="https://github.com/zzzprojects/Z.ExtensionMethods" target="_blank">https://github.com/zzzprojects/Z.ExtensionMethods</a></td></tr><tr><td>2</td><td><a href="https://github.com/ldqk/Masuit.Tools" target="_blank">Masuit.Tools</a></td><td>新手友好的C#万能工具库，码数吐司库，包含一些常用的操作类，大都是静态类，加密解密，反射操作，权重随机筛选算法，分布式短id，表达式树，linq扩展，文件压缩，多线程下载和FTP客户端，硬件信息，字符串扩展方法，日期时间扩展操作，中国农历，大文件拷贝，图像裁剪，验证码，断点续传，集合扩展、Excel导出等常用封装。</td><td><a href="https://github.com/ldqk/Masuit.Tools" target="_blank">https://github.com/ldqk/Masuit.Tools</a></td></tr><tr><td>1</td><td><a href="https://github.com/Jimmey-Jiang/Common.Utility" target="_blank">Common.Utility</a></td><td>比较全面的C#帮助类，日常工作收集，各式各样的几乎都能找到,所有功能性代码都是独立的类，类与类之间没有联系，可以单独引用至项目。</td><td><a href="https://github.com/Jimmey-Jiang/Common.Utility" target="_blank">https://github.com/Jimmey-Jiang/Common.Utility</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET人脸识别库<a href="#net人脸识别库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td><a href="https://github.com/takuya-takeuchi/FaceRecognitionDotNet" target="_blank">FaceRecognitionDotNet</a></td><td>一个.NET开源（MIT License）、免费、跨平台（适用于 Windows、MacOS 和 Linux ）、使用简单的面部识别库（是 face_recognition 的 C# 移植版本）。</td><td><a href="https://github.com/takuya-takeuchi/FaceRecognitionDotNet" target="_blank">https://github.com/takuya-takeuchi/FaceRecognitionDotNet</a></td></tr><tr><td>2</td><td><a href="https://github.com/ViewFaceCore/ViewFaceCore" target="_blank">ViewFaceCore</a></td><td>一个.NET开源的（MIT License）、免费的、跨平台的、使用简单的离线人脸识别库（一个基于 SeetaFace6 的 .NET 人脸识别解决方案）。</td><td><a href="https://github.com/ViewFaceCore/ViewFaceCore" target="_blank">https://github.com/ViewFaceCore/ViewFaceCore</a></td></tr><tr><td>1</td><td><a href="https://github.com/iarray/FaceRecognition" target="_blank">FaceRecognition</a></td><td>一个基于C#的离线人脸识别演示项目。该演示包括人脸检测、人脸对齐和人脸识别功能，基于seetaface库实现。</td><td><a href="https://github.com/iarray/FaceRecognition" target="_blank">https://github.com/iarray/FaceRecognition</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>C#FFmpeg封装库<a href="#cffmpeg封装库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td><a href="https://github.com/cmxl/FFmpeg.NET" target="_blank">FFmpeg.NET</a></td><td>常见 FFmpeg 任务的 .NET 封装程序</td><td><a href="https://github.com/cmxl/FFmpeg.NET" target="_blank">https://github.com/cmxl/FFmpeg.NET</a></td></tr><tr><td>4</td><td><a href="https://github.com/Ruslan-B/FFmpeg.AutoGen" target="_blank">FFmpeg.AutoGen</a></td><td>FFmpeg AutoGen是一个为C#/.NET和Core（Linux、MacOS和Mono）自动生成的不安全绑定库。它提供了与FFmpeg的接口对应的C#代码，使开发者能够在C#/.NET和Core平台上使用FFmpeg的功能。</td><td><a href="https://github.com/Ruslan-B/FFmpeg.AutoGen" target="_blank">https://github.com/Ruslan-B/FFmpeg.AutoGen</a></td></tr><tr><td>3</td><td><a href="https://github.com/rosenbjerg/FFMpegCore" target="_blank">FFMpegCore </a></td><td>是一个基于 .NET Standard 的 FFmpeg 处理库。它提供了一个简单而直观的 API，使开发者能够在 .NET 应用程序中轻松使用 FFmpeg 进行媒体处理任务，如转码、剪辑、合并等。FFMpegCore 具有跨平台支持，可以在 Windows、Linux 和 macOS 等操作系统上运行。</td><td><a href="https://github.com/rosenbjerg/FFMpegCore" target="_blank">https://github.com/rosenbjerg/FFMpegCore</a></td></tr><tr><td>2</td><td><a href="https://github.com/tomaszzmuda/Xabe.FFmpeg" target="_blank">Xabe.FFmpeg </a></td><td>FFmpeg 的.NET 标准包装器。它允许在不了解 FFmpeg 工作原理的情况下处理媒体，并可用于从 dotnet 核心应用程序向 FFmpeg 传递自定义参数。</td><td><a href="https://github.com/tomaszzmuda/Xabe.FFmpeg" target="_blank">https://github.com/tomaszzmuda/Xabe.FFmpeg</a></td></tr><tr><td>1</td><td><a href="https://github.com/sdcb/Sdcb.FFmpeg" target="_blank">Sdcb.FFmpeg </a></td><td>FFmpeg开源C#封装库。</td><td><a href="https://www.cnblogs.com/sdflysha/p/dotnet-conf-china-2022-ffmpeg.html" target="_blank">https://www.cnblogs.com/sdflysha/p/dotnet-conf-china-2022-ffmpeg.html</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET高精度数值计算库<a href="#net高精度数值计算库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/sdcb/Sdcb.Arithmetic" target="_blank">Sdcb.Arithmetic</a></td><td>.NET高精度数值计算库。</td><td><a href="https://www.cnblogs.com/sdflysha/p/20230725-sdcb-arithmetic-intro.html" target="_blank">https://www.cnblogs.com/sdflysha/p/20230725-sdcb-arithmetic-intro.html</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET第三方登录整合库<a href="#net第三方登录整合库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/mrhuo/MrHuo.OAuth" target="_blank">MrHuo.OAuth</a></td><td>.netcore 下最好用的第三方登录组件集合，集成了国内外大部分平台。</td><td><a href="https://github.com/mrhuo/MrHuo.OAuth" target="_blank">https://github.com/mrhuo/MrHuo.OAuth</a></td></tr><tr><td>1</td><td><a href="https://gitee.com/rthinking/CollectiveOAuth" target="_blank">CollectiveOAuth</a></td><td>.Net平台(C#) 史上最全的整合第三方登录的开源库 =&gt; 环境支持 .NET Framework 4.5 ~ 4.6.2 和 .NetCore 3.1。目前已包含Github、Gitee、钉钉、百度、支付宝、微信、企业微信、腾讯云开发者平台(Coding)、OSChina、微博、QQ、Google、Facebook、抖音、领英、小米、微软、今日头条、Teambition、StackOverflow、Pinterest、人人、华为、酷家乐、Gitlab、美团、饿了么、等第三方平台的授权登录。</td><td><a href="https://gitee.com/rthinking/CollectiveOAuth" target="_blank">https://gitee.com/rthinking/CollectiveOAuth</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET UI自动化库<a href="#net-ui自动化库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/FlaUI/FlaUI" target="_blank">FlaUI</a></td><td>FlaUI是一个.Net的UI自动化库，用于自动化测试Windows应用程序（包括Win32、WinForms、WPF、Store Apps等）。它基于Microsoft的原生UI自动化库，并在其周围提供了一层封装。FlaUI几乎包含了UI自动化库中的所有功能，并在有特殊需求（目前尚未覆盖）的情况下提供了原生对象。</td><td><a href="https://github.com/FlaUI/FlaUI" target="_blank">https://github.com/FlaUI/FlaUI</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET图形&amp;图表&amp;表格库<a href="#net图形图表表格库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>10</td><td></td><td></td><td></td></tr><tr><td>9</td><td></td><td></td><td></td></tr><tr><td>8</td><td><a href="https://github.com/oxyplot/oxyplot" target="_blank">OxyPlot</a></td><td>一款.NET开源（MIT License）、免费、跨平台、功能强大的绘图库，支持多平台使用（包括：WPF、UWP、WinForm、Silverlight、Xamarin.iOS、Xamarin.Android、Xamarin.Forms 和 Xamarin.Mac等）。</td><td><a href="https://github.com/oxyplot/oxyplot" target="_blank">https://github.com/oxyplot/oxyplot</a></td></tr><tr><td>7</td><td><a href="https://github.com/Mapsui/Mapsui" target="_blank">Mapsui</a></td><td>一个.NET开源（MIT License）、免费、同时支持多平台框架（MAUI、WPF、Avalonia、Uno、Blazor、WinUI、Eto、.NET Android 和 .NET iOS）地图组件库。</td><td><a href="https://github.com/Mapsui/Mapsui" target="_blank">https://github.com/Mapsui/Mapsui</a></td></tr><tr><td>6</td><td><a href="https://github.com/beto-rodriguez/LiveCharts2" target="_blank">LiveCharts2</a></td><td>LiveCharts2是一个.NET开源、简单、灵活、交互式且功能强大的.NET图表、地图和仪表，现在几乎可以在任何地方运行如：Maui、Uno Platform、Blazor-wasm、WPF、WinForms、Xamarin、Avalonia、WinUI、UWP。</td><td><a href="https://github.com/beto-rodriguez/LiveCharts2" target="_blank">https://github.com/beto-rodriguez/LiveCharts2</a></td></tr><tr><td>5</td><td><a href="https://github.com/dlemstra/Magick.NET" target="_blank">Magick.NET</a></td><td>ImageMagick 是一个功能强大的图像处理库，支持 100 多种主要文件格式（不包括子格式）。借助 Magick.NET，您可以在 C#/VB.NET/.NET Core 应用程序中使用 ImageMagick，而无需在服务器或桌面上安装 ImageMagick。</td><td><a href="https://github.com/dlemstra/Magick.NET" target="_blank">https://github.com/dlemstra/Magick.NET</a></td></tr><tr><td>4</td><td><a href="https://github.com/unvell/ReoGrid" target="_blank">ReoGrid</a></td><td>一个.NET开源（MIT License）、快速、强大、免费的电子表格组件，支持数据格式、冻结、大纲、公式计算、图表、脚本执行等。兼容 Excel 2007 (.xlsx) 格式，支持WinForm、WPF和Android平台。</td><td><a href="https://github.com/unvell/ReoGrid" target="_blank">https://github.com/unvell/ReoGrid</a></td></tr><tr><td>3</td><td><a href="https://github.com/ScottPlot/ScottPlot" target="_blank">ScottPlot</a></td><td>ScottPlot是一个免费、开源（采用MIT许可证）的强大.NET交互式绘图库，能够轻松地实现大型数据集的交互式显示。使用几行代码即可快速创建折线图、柱状图、饼图、散点图等不同类型的图表。</td><td><a href="https://github.com/ScottPlot/ScottPlot" target="_blank">https://github.com/ScottPlot/ScottPlot</a></td></tr><tr><td>2</td><td><a href="https://github.com/SixLabors/ImageSharp" target="_blank">ImageSharp</a></td><td>ImageSharp是一款全新的、功能齐全的、完全管理的、跨平台的2D图形API。ImageSharp旨在简化图像处理，提供了一个极其强大但简洁易用的API。</td><td><a href="https://github.com/SixLabors/ImageSharp" target="_blank">https://github.com/SixLabors/ImageSharp</a></td></tr><tr><td>1</td><td><a href="https://github.com/mono/SkiaSharp" target="_blank">SkiaSharp</a></td><td>SkiaSharp是由Mono团队维护的开源项目，它是基于Google的Skia图形库的.NET跨平台绑定，提供了强大的2D图形绘制和处理功能，适用于多个平台，包括Windows、macOS、Linux、iOS和Android，可用于创建高性能的、可移植的2D图形应用程序。</td><td><a href="https://github.com/mono/SkiaSharp" target="_blank">https://github.com/mono/SkiaSharp</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET二维码类库<a href="#net二维码类库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td><a href="https://github.com/guitarrapc/SkiaSharp.QrCode" target="_blank">SkiaSharp.QrCode</a></td><td>使用SkiaSharp生成二维码的QR码生成器（无需使用System.Drawing）。</td><td><a href="https://github.com/guitarrapc/SkiaSharp.QrCode" target="_blank">https://github.com/guitarrapc/SkiaSharp.QrCode</a></td></tr><tr><td>2</td><td><a href="https://github.com/codebude/QRCoder" target="_blank">QRCoder</a></td><td>QRCoder是一个功能强大且易于使用的.NET类库，专门用于生成二维码，并支持多种输出格式。它提供了简单的API，方便您在.NET应用程序中集成二维码生成功能。</td><td><a href="https://github.com/codebude/QRCoder" target="_blank">https://github.com/codebude/QRCoder</a></td></tr><tr><td>1</td><td><a href="https://github.com/micjahn/ZXing.Net" target="_blank">ZXing.Net</a></td><td>ZXing.NET是ZXing原始基于Java的条码阅读器和生成器库的.NET端口。它提供了在.NET平台上使用ZXing功能的便捷方式，并为开发人员提供了丰富的条码和二维码处理功能。</td><td><a href="https://github.com/micjahn/ZXing.Net" target="_blank">https://github.com/micjahn/ZXing.Net</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET加密解密库<a href="#net加密解密库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/bcgit/bc-csharp" target="_blank">BouncyCastle</a></td><td>BouncyCastle是一款C#版开源、免费的Bouncy Castle密码库，开发人员可以通过该项目在他们的 C# 应用程序中使用 Bouncy Castle 提供的各种密码学功能，从而加强数据的安全性和保护隐私信息。</td><td><a href="https://github.com/bcgit/bc-csharp" target="_blank">https://github.com/bcgit/bc-csharp</a></td></tr><tr><td>1</td><td><a href="https://github.com/myloveCc/NETCore.Encrypt" target="_blank">NETCore.Encrypt</a></td><td>.NET Core加密解密类库，包括AES、DES、RSA、MD5、SHA1、SHA256、SHA384、SHA512等算法。</td><td><a href="https://github.com/myloveCc/NETCore.Encrypt" target="_blank">https://github.com/myloveCc/NETCore.Encrypt</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET支付SDK<a href="#net支付sdk"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>10</td><td></td><td></td><td></td></tr><tr><td>9</td><td></td><td></td><td></td></tr><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td></td><td></td><td></td></tr><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td><a href="https://github.com/xin-lai/Magicodes.Pay" target="_blank">Magicodes.Pay</a></td><td>Magicodes.Pay，是心莱科技团队提供的统一支付库，相关库均使用.NET标准库编写，支持.NET Framework以及.NET Core。目前已提供Abp模块的封装，支持开箱即用。</td><td><a href="https://github.com/xin-lai/Magicodes.Pay" target="_blank">https://github.com/xin-lai/Magicodes.Pay</a></td></tr><tr><td>2</td><td><a href="https://github.com/essensoft/paylink" target="_blank">paylink</a></td><td>一套基于 .NET Core 开发的支付SDK集，它极大简化了API调用及通知的处理流程。</td><td><a href="https://github.com/essensoft/paylink" target="_blank">https://github.com/essensoft/paylink</a></td></tr><tr><td>1</td><td><a href="https://github.com/Varorbc/PaySharp" target="_blank">PaySharp</a></td><td>PaySharp是一个支持多商户多种支付方式的跨平台网关处理类库，使用PaySharp可以简化订单的创建、查询、退款和接收网关返回的支付通知等操作。</td><td><a href="https://github.com/Varorbc/PaySharp" target="_blank">https://github.com/Varorbc/PaySharp</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET Office文件操作库<a href="#net-office文件操作库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>15</td><td></td><td></td><td></td></tr><tr><td>14</td><td></td><td></td><td></td></tr><tr><td>13</td><td></td><td></td><td></td></tr><tr><td>12</td><td><a href="https://github.com/mganss/ExcelMapper" target="_blank">ExcelMapper</a></td><td>用于将 POCO 对象映射到 Excel 文件的库。</td><td><a href="https://github.com/mganss/ExcelMapper" target="_blank">https://github.com/mganss/ExcelMapper</a></td></tr><tr><td>11</td><td><a href="https://github.com/RibbonWinForms/RibbonWinForms" target="_blank">RibbonWinForms</a></td><td>一个适用于.NET WinForms的 Office 功能区控件类库。</td><td><a href="https://github.com/RibbonWinForms/RibbonWinForms" target="_blank">https://github.com/RibbonWinForms/RibbonWinForms</a></td></tr><tr><td>10</td><td><a href="https://github.com/empira/PDFsharp" target="_blank">PDFsharp</a></td><td>PDFsharp 是一个开源 .NET 库，可在 Windows、Linux 和 Mac 下使用 .NET 6 轻松创建和处理 PDF 文档。</td><td><a href="https://github.com/empira/PDFsharp" target="_blank">https://github.com/empira/PDFsharp</a></td></tr><tr><td>9</td><td><a href="https://github.com/QuestPDF/QuestPDF" target="_blank">QuestPDF</a></td><td>QuestPDF 是一个用于生成 PDF 文档的现代开源 .NET 库。QuestPDF 由简洁易用的 C# Fluent API 提供全面的布局引擎。轻松生成 PDF 报告、发票、导出等。</td><td><a href="https://github.com/QuestPDF/QuestPDF" target="_blank">https://github.com/QuestPDF/QuestPDF</a></td></tr><tr><td>8</td><td><a href="https://github.com/itext/itext7-dotnet" target="_blank">itext7-dotnet</a></td><td>iText for .NET 是 iText 库的 .NET 版本，其前身是 iTextSharp。iText 配备了更好的文档引擎、高级和低级编程功能以及创建、编辑和增强 PDF 文档的能力。</td><td><a href="https://github.com/itext/itext7-dotnet" target="_blank">https://github.com/itext/itext7-dotnet</a></td></tr><tr><td>7</td><td><a href="https://github.com/itext/itextsharp" target="_blank">iTextSharp</a></td><td>iTextSharp是一个从JAVA项目iText衍生的.Net版本的开源项目。iText是一个PDF库，可让您创建，移植，检查和维护可移植文档格式（PDF）的文档，从而使您可以轻松地向软件项目添加PDF功能。</td><td><a href="https://github.com/itext/itextsharp" target="_blank">https://github.com/itext/itextsharp</a></td></tr><tr><td>6</td><td><a href="https://github.com/egonl/SharpDocx" target="_blank">SharpDocx</a></td><td>用于创建 Word 文档的轻量级模板引擎。</td><td><a href="https://github.com/egonl/SharpDocx" target="_blank">https://github.com/egonl/SharpDocx</a></td></tr><tr><td>5</td><td><a href="https://github.com/ClosedXML/ClosedXML" target="_blank">ClosedXML</a></td><td>osedXML是一个用于读取、操作和写入Excel 2007+（.xlsx，.xlsm）文件的.NET库。它旨在提供一个直观和用户友好的界面来处理底层的OpenXML API。</td><td><a href="https://github.com/ClosedXML/ClosedXML" target="_blank">https://github.com/ClosedXML/ClosedXML</a></td></tr><tr><td>4</td><td><a href="https://github.com/dotnetcore/Magicodes.IE" target="_blank">Magicodes.IE</a></td><td>导入导出通用库，支持Dto导入导出、模板导出、花式导出以及动态导出，支持Excel、Csv、Word、Pdf和Html。</td><td><a href="https://github.com/dotnetcore/Magicodes.IE" target="_blank">https://github.com/dotnetcore/Magicodes.IE</a></td></tr><tr><td>3</td><td><a href="https://github.com/mini-software/MiniWord" target="_blank">MiniWord</a></td><td>.NET Word模板引擎，藉由Word模板和数据简单、快速生成文件。</td><td><a href="https://github.com/mini-software/MiniWord" target="_blank">https://github.com/mini-software/MiniWord</a></td></tr><tr><td>2</td><td><a href="https://github.com/MiniExcel/MiniExcel" target="_blank">MiniExcel</a></td><td>MiniExcel是一个简单高效的.NET操作Excel工具（处理Excel查、写、填充数据），旨在避免OOM（内存溢出）问题。目前主流框架大多需要将数据全载入到内存方便操作，但这会导致内存消耗问题，MiniExcel 尝试以 Stream 角度写底层算法逻辑，能让原本1000多MB占用降低到几MB，避免内存不够情况。</td><td><a href="https://github.com/MiniExcel/MiniExcel" target="_blank">https://github.com/MiniExcel/MiniExcel</a></td></tr><tr><td>1</td><td><a href="https://github.com/nissl-lab/npoi" target="_blank">npoi</a></td><td>npoi是一个.NET平台下的开源库，用于读写和操作Office文件，提供了便捷的处理Office文件格式的功能，Apache POI移植版本。</td><td><a href="https://github.com/nissl-lab/npoi" target="_blank">https://github.com/nissl-lab/npoi</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET JSON处理库<a href="#net-json处理库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>10</td><td></td><td></td><td></td></tr><tr><td>9</td><td></td><td></td><td></td></tr><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td></td><td></td><td></td></tr><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td><a href="https://github.com/dotnet/runtime/tree/main/src/libraries/System.Text.Json" target="_blank">System.Text.Json</a></td><td>System.Text.Json是 .NET Core 3.0 及以上版本中内置的 JSON 序列化和反序列化库。</td><td><a href="https://github.com/dotnet/runtime/tree/main/src/libraries/System.Text.Json" target="_blank">https://github.com/dotnet/runtime/tree/main/src/libraries/System.Text.Json</a></td></tr><tr><td>4</td><td><a href="https://github.com/JamesNK/Newtonsoft.Json" target="_blank">Newtonsoft.Json</a></td><td>Newtonsoft.Json是一个功能强大且灵活的.NET JSON序列化和反序列化库，用于在.NET应用程序中处理JSON数据。</td><td><a href="https://github.com/JamesNK/Newtonsoft.Json" target="_blank">https://github.com/JamesNK/Newtonsoft.Json</a></td></tr><tr><td>3</td><td><a href="https://github.com/ServiceStack/ServiceStack.Text" target="_blank">ServiceStack.Text</a></td><td>.NET中最快的JSON、JSV和CSV文本序列化器。</td><td><a href="https://github.com/ServiceStack/ServiceStack.Text" target="_blank">https://github.com/ServiceStack/ServiceStack.Text</a></td></tr><tr><td>2</td><td><a href="https://github.com/kevin-montrose/Jil" target="_blank">Jil</a></td><td>一个快速的JSON（反）序列化器，基于Sigil构建，采用了一些有点疯狂的优化技巧。</td><td><a href="https://github.com/kevin-montrose/Jil" target="_blank">https://github.com/kevin-montrose/Jil</a></td></tr><tr><td>1</td><td><a href="https://github.com/neuecc/Utf8Json" target="_blank">Utf8Json</a></td><td>适用于 C#（NET、.NET Core、Unity、Xamarin）的绝对最快且零分配的 JSON 序列化器。</td><td><a href="https://github.com/neuecc/Utf8Json" target="_blank">https://github.com/neuecc/Utf8Json</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET对象映射库<a href="#net对象映射库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>10</td><td></td><td></td><td></td></tr><tr><td>9</td><td></td><td></td><td></td></tr><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td></td><td></td><td></td></tr><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td><a href="https://github.com/AutoMapper/AutoMapper" target="_blank">AutoMapper</a></td><td>AutoMapper是一个简单易用的.NET对象映射库，用于快速、方便地进行对象之间的转换和映射，极大的简化了开发人员在处理对象映射时的工作量。</td><td><a href="https://github.com/AutoMapper/AutoMapper" target="_blank">https://github.com/AutoMapper/AutoMapper</a></td></tr><tr><td>4</td><td><a href="https://github.com/MapsterMapper/Mapster" target="_blank">Mapster</a></td><td>Mapster是一个快速、高性能、灵活且易于使用的对象映射库，用于在.NET应用程序中进行对象之间的转换和映射操作。</td><td><a href="https://github.com/MapsterMapper/Mapster" target="_blank">https://github.com/MapsterMapper/Mapster</a></td></tr><tr><td>3</td><td><a href="https://github.com/riok/mapperly" target="_blank">Mapperly</a></td><td>一个.NET开源的对象映射器，无运行时反射，由于 Mapperly 在构建时创建映射代码，因此运行时的开销最小。更好的是，生成的代码完全可读，使您可以轻松验证生成的映射代码。</td><td><a href="https://github.com/riok/mapperly" target="_blank">https://github.com/riok/mapperly</a></td></tr><tr><td>2</td><td><a href="https://github.com/MetSystem/EmitMapper" target="_blank">EmitMapper</a></td><td>一个.NET开源、强大的可定制工具，用于将实体相互映射。实体可以是普通对象、DataReaders、SQL命令或其他任何你需要的内容。该工具通过Emit库进行运行时代码生成。它非常适用于处理DTO对象、数据访问层等。</td><td><a href="https://github.com/MetSystem/EmitMapper" target="_blank">https://github.com/MetSystem/EmitMapper</a></td></tr><tr><td>1</td><td><a href="https://github.com/TinyMapper/TinyMapper" target="_blank">TinyMapper</a></td><td>一个快速的 .NET 对象映射器。</td><td><a href="https://github.com/TinyMapper/TinyMapper" target="_blank">https://github.com/TinyMapper/TinyMapper</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET Redis客户端驱动库<a href="#net-redis客户端驱动库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>10</td><td></td><td></td><td></td></tr><tr><td>9</td><td></td><td></td><td></td></tr><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td></td><td></td><td></td></tr><tr><td>6</td><td><a href="https://github.com/NewLifeX/NewLife.Redis" target="_blank">NewLife.Redis</a></td><td>NewLife.Redis是一个Redis客户端组件，以高性能处理大数据实时计算为目标。支持.NETCore/.NET4.0/.NET4.5，为大数据与消息队列而特别优化，线上单应用日均100亿调用量。</td><td><a href="https://github.com/NewLifeX/NewLife.Redis" target="_blank">https://github.com/NewLifeX/NewLife.Redis</a></td></tr><tr><td>5</td><td><a href="https://github.com/2881099/csredis" target="_blank">csredis</a></td><td>.NET Core或.NET Framework 4.0+ Redis客户端，用于Redis、Redis Sentinel（2.8）和Cluster。包括同步和异步客户端。</td><td><a href="https://github.com/2881099/csredis" target="_blank">https://github.com/2881099/csredis</a></td></tr><tr><td>4</td><td><a href="https://github.com/2881099/FreeRedis" target="_blank">FreeRedis</a></td><td>基于.NET的Redis客户端，支持 .NET Core 2.1+、.NET Framework 4.0+、Xamarin以及 AOT。它支持集群、哨兵、主从、发布订阅、Lua脚本、管道、事务、流、客户端缓存以及连接池等功能。</td><td><a href="https://github.com/2881099/FreeRedis" target="_blank">https://github.com/2881099/FreeRedis</a></td></tr><tr><td>3</td><td><a href="https://github.com/StackExchange/StackExchange.Redis" target="_blank">StackExchange.Redis</a></td><td>StackExchange.Redis是一个基于.NET的高性能Redis客户端，提供了完整的Redis数据库功能支持，并且具有多节点支持、异步编程模型、Redis集群支持等特性，使得与Redis数据库的交互更加灵活、高效。</td><td><a href="https://github.com/StackExchange/StackExchange.Redis" target="_blank">https://github.com/StackExchange/StackExchange.Redis</a></td></tr><tr><td>2</td><td><a href="https://github.com/beetlex-io/BeetleX.Redis" target="_blank">BeetleX.Redis</a></td><td>一个用于.NET Core的高性能异步/非阻塞Redis客户端组件，默认数据格式化器Json、Protobuf和MessagePack，支持SSL。</td><td><a href="https://github.com/beetlex-io/BeetleX.Redis" target="_blank">https://github.com/beetlex-io/BeetleX.Redis</a></td></tr><tr><td>1</td><td><a href="https://github.com/ServiceStack/ServiceStack.Redis" target="_blank">ServiceStack.Redis</a></td><td>ServiceStack.Redis是一个.NET开发的简单、高性能且功能丰富的Redis客户端，它提供了对POCOs和复杂类型的原生支持，并提供了高级抽象，同时支持原生的同步和异步API。</td><td><a href="https://docs.servicestack.net/redis/" target="_blank">https://docs.servicestack.net/redis/</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET的OCR工具类库<a href="#net的ocr工具类库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>10</td><td></td><td></td><td></td></tr><tr><td>9</td><td></td><td></td><td></td></tr><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td></td><td></td><td></td></tr><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/sdcb/PaddleSharp" target="_blank">PaddleSharp</a></td><td>百度飞桨PaddleOCR .NET调用库，PaddleInference C API 提供的 .NET 包装，支持 Windows(x64) ，基于NVIDIA Cuda 10.2+ 的 GPU  和 Linux(Ubuntu-22.04 x64)。</td><td><a href="https://github.com/sdcb/PaddleSharp" target="_blank">https://github.com/sdcb/PaddleSharp</a></td></tr><tr><td>1</td><td><a href="https://gitee.com/raoyutian/paddle-ocrsharp" target="_blank">PaddleOCRSharp</a></td><td>PaddleOCRSharp 是一个基于百度飞桨PaddleOCR的.NET版本OCR工具类库。项目核心组件PaddleOCR.dll,由C++编写，根据百度飞桨PaddleOCR的C++代码修改并优化而成。目前已经支持C++、.NET、Python、Golang、Rust等开发语言的直接API接口调用。项目包含文本识别、文本检测、表格识别功能。本项目针对小图识别不准的情况下做了优化，比飞桨原代码识别准确率有所提高。包含总模型仅8.6M的超轻量级中文OCR，单模型支持中英文数字组合识别、竖排文本识别、长文本识别。同时支持中英文、纯英文以及多种语言文本检测识别。</td><td><a href="https://gitee.com/raoyutian/paddle-ocrsharp" target="_blank">https://gitee.com/raoyutian/paddle-ocrsharp</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>敏感词检测组件库<a href="#敏感词检测组件库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/toolgood/ToolGood.Words" target="_blank">ToolGood.Words</a></td><td>一款高性能敏感词(非法词/脏字)检测过滤组件，附带繁体简体互换，支持全角半角互换，汉字转拼音，模糊搜索等功能。</td><td><a href="https://github.com/toolgood/ToolGood.Words" target="_blank">https://github.com/toolgood/ToolGood.Words</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>C#拼音字母转化类库<a href="#c拼音字母转化类库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://gitee.com/hyjiacan/Pinyin4Net" target="_blank">Pinyin4NET</a></td><td>.net(core)使用的汉字转拼音库(含姓名拼音独立接口)。提供了简单的调用接口和通过拼音查询汉字的接口。</td><td><a href="https://gitee.com/hyjiacan/Pinyin4Net" target="_blank">https://gitee.com/hyjiacan/Pinyin4Net</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET枚举工具类库<a href="#net枚举工具类库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/TylerBrinkley/Enums.NET" target="_blank">Enums.NET</a></td><td>Enums.NET 是一个高性能、类型安全的 .NET 枚举工具库。</td><td><a href="https://github.com/TylerBrinkley/Enums.NET" target="_blank">https://github.com/TylerBrinkley/Enums.NET</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET电子邮件处理库<a href="#net电子邮件处理库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td><a href="https://github.com/milkshakesoftware/PreMailer.Net" target="_blank">PreMailer.Net </a></td><td>PreMailer.Net 是一个用于电子邮件的C#库，它将样式表转换为内联样式属性，以增强与各种电子邮件客户端的兼容性。</td><td><a href="https://github.com/milkshakesoftware/PreMailer.Net" target="_blank">https://github.com/milkshakesoftware/PreMailer.Net</a></td></tr><tr><td>2</td><td><a href="https://github.com/jstedfast/MailKit" target="_blank">MailKit</a></td><td>MailKit 是一个跨平台的 .NET 邮件处理库，提供强大的 API，用于发送、接收和处理电子邮件。</td><td><a href="https://github.com/jstedfast/MailKit" target="_blank">https://github.com/jstedfast/MailKit</a></td></tr><tr><td>1</td><td><a href="https://github.com/lukencode/FluentEmail" target="_blank">FluentEmail</a></td><td>FluentEmail 是一个用于 .NET 和 .NET Core 的电子邮件发送库，它提供了简单易用的 API 来发送电子邮件。该项目支持使用 Razor 模板来创建电子邮件内容，并可以通过 SendGrid、MailGun、SMTP 等多种方式进行发送。</td><td><a href="https://github.com/lukencode/FluentEmail" target="_blank">https://github.com/lukencode/FluentEmail</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET中文分词类库<a href="#net中文分词类库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/anderscui/jieba.NET" target="_blank">jieba.NET</a></td><td>jieba中文分词的.NET版本类库（支持.NET Framework与.NET Core）。</td><td><a href="https://github.com/anderscui/jieba.NET" target="_blank">https://github.com/anderscui/jieba.NET</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET模拟库<a href="#net模拟库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td><a href="https://github.com/devlooped/moq" target="_blank">moq</a></td><td>Moq（读作 “Mock-you “或 “Mock”）是唯一一个从零开始开发的.NET模拟库，它充分利用了.NET Linq表达式树和lambda表达式的优势，使其成为目前最高效、类型安全和重构友好的模拟库。它还支持模拟接口和类。它的 API 非常简单直接，不需要任何有关模拟概念的知识或经验。</td><td><a href="https://github.com/devlooped/moq" target="_blank">https://github.com/devlooped/moq</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>.NET分布式ID生成库<a href="#net分布式id生成库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/yitter/idgenerator" target="_blank">IdGenerator</a></td><td>IdGenerator是一个全面的分布式主键ID生成器，使用的是优化的雪花算法（SnowFlake）雪花漂移算法，在缩短ID长度的同时，具备极高瞬时并发处理能力（50W/0.1s）。</td><td><a href="https://github.com/yitter/idgenerator" target="_blank">https://github.com/yitter/idgenerator</a></td></tr><tr><td>1</td><td><a href="https://github.com/stulzq/snowflake-net" target="_blank">snowflake-net</a></td><td>Twitter的分布式全局唯一ID算法，雪花（snowflake）算法。支持.NET Core 2.0。</td><td><a href="https://github.com/stulzq/snowflake-net" target="_blank">https://github.com/stulzq/snowflake-net</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>EF/EF Core扩展类库<a href="#efef-core扩展类库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td><a href="https://github.com/win7user10/Laraue.EfCoreTriggers" target="_blank">EfCoreTriggers</a></td><td>EfCoreTriggers是使用 EFCore 模型构建器编写本机 SQL 触发器的库。触发器会自动转换为 sql 并添加到迁移中。</td><td><a href="https://github.com/win7user10/Laraue.EfCoreTriggers" target="_blank">https://github.com/win7user10/Laraue.EfCoreTriggers</a></td></tr><tr><td>3</td><td><a href="https://github.com/TanvirArjel/EFCore.GenericRepository" target="_blank">EF Core Generic Repository</a></td><td>该库是EF Core ORM的通用仓储库实现，旨在简化开发人员为每个.NET Core和.NET项目编写仓储层的工作。通过使用这个库，开发人员可以更轻松地管理数据访问层，提高开发效率。</td><td><a href="https://github.com/TanvirArjel/EFCore.GenericRepository" target="_blank">https://github.com/TanvirArjel/EFCore.GenericRepository</a></td></tr><tr><td>2</td><td><a href="https://github.com/verdie-g/StoredProcedureEFCore" target="_blank">StoredProcedureEFCore</a></td><td>使用Entity Framework Core执行存储过程。</td><td><a href="https://github.com/verdie-g/StoredProcedureEFCore" target="_blank">https://github.com/verdie-g/StoredProcedureEFCore</a></td></tr><tr><td>1</td><td><a href="https://github.com/dotnetcore/sharding-core" target="_blank">ShardingCore</a></td><td>一款ef-core下高性能、轻量级针对分表分库读写分离的解决方案，具有零依赖、零学习成本、零业务代码入侵。</td><td><a href="https://github.com/dotnetcore/sharding-core" target="_blank">https://github.com/dotnetcore/sharding-core</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>弹性和瞬态故障处理库<a href="#弹性和瞬态故障处理库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td></td><td></td></tr><tr><td>1</td><td></td><td></td><td></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>其他第三方SDK&amp;类库<a href="#其他第三方sdk类库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>12</td><td></td><td></td><td></td></tr><tr><td>11</td><td></td><td></td><td></td></tr><tr><td>10</td><td><a href="https://github.com/spectreconsole/spectre.console" target="_blank">Spectre.Console</a></td><td>一个.NET开源且免费的类库帮你轻松的创建漂亮、美观的.NET控制台应用程序。</td><td><a href="https://github.com/spectreconsole/spectre.console" target="_blank">https://github.com/spectreconsole/spectre.console</a></td></tr><tr><td>9</td><td><a href="https://github.com/dotnet/Docker.DotNet" target="_blank">Docker.DotNet</a></td><td>Docker API 的 .NET (C#) 客户端库。</td><td><a href="https://github.com/dotnet/Docker.DotNet" target="_blank">https://github.com/dotnet/Docker.DotNet</a></td></tr><tr><td>8</td><td><a href="https://gitee.com/dotnetchina/TimeCrontab" target="_blank">TimeCrontab</a></td><td>一个 .NET 全能 Cron 表达式解析类库，支持 Cron 所有特性。</td><td><a href="https://gitee.com/dotnetchina/TimeCrontab" target="_blank">https://gitee.com/dotnetchina/TimeCrontab</a></td></tr><tr><td>7</td><td><a href="https://github.com/TNG/ArchUnitNET" target="_blank">ArchUnitNET</a></td><td>一个 C# 架构测试库，用于在 C# 中指定和断言架构规则，以进行自动测试。</td><td><a href="https://github.com/TNG/ArchUnitNET" target="_blank">https://github.com/TNG/ArchUnitNET</a></td></tr><tr><td>6</td><td><a href="https://github.com/alipay/alipay-sdk-net-all" target="_blank">alipay-sdk-net-all</a></td><td>Alipay SDK for .NET，SDK可以自动帮您满足能力调用过程中所需的证书校验、加签、验签、发送HTTP请求等非功能性要求。</td><td><a href="https://github.com/alipay/alipay-sdk-net-all" target="_blank">https://github.com/alipay/alipay-sdk-net-all</a></td></tr><tr><td>5</td><td><a href="https://github.com/dotNetTreasury/sentry-dotnet" target="_blank">sentry-dotnet</a></td><td>Sentry SDK for .NET。</td><td><a href="https://github.com/dotNetTreasury/sentry-dotnet" target="_blank">https://github.com/dotNetTreasury/sentry-dotnet</a></td></tr><tr><td>4</td><td><a href="https://github.com/Azure/azure-sdk-for-net" target="_blank">Azure SDK for .NET</a></td><td>Azure SDK for .NET是一组用于.NET开发人员的库和工具，可帮助他们轻松地在Azure云中构建、部署和管理应用程序。该项目为开发人员提供了访问Azure服务所需的一切功能、API和工具，包括对云中常见任务的支持，如虚拟机、存储、网络、应用程序服务、容器等。此项目的主要目的是简化.NET开发人员与Azure云交互的过程，并提高其效率。通过使用Azure SDK for .NET，开发人员可以更快速、更轻松地将应用程序部署到Azure云中，从而实现更快的上线时间和更高的生产力。</td><td><a href="https://github.com/Azure/azure-sdk-for-net" target="_blank">https://github.com/Azure/azure-sdk-for-net</a></td></tr><tr><td>3</td><td><a href="https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.ByteDance" target="_blank">SKIT.FlurlHttpClient.ByteDance</a></td><td>可能是全网唯一的 C# 版字节跳动 SDK，封装全部已知的字节跳动 API，包含字节小程序开放平台、抖音开放平台、抖店开放平台、巨量引擎开放平台、TikTok Developer、TikTok Shop Open Platform 等模块，可跨平台，持续随官方更新。</td><td><a href="https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.ByteDance" target="_blank">https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.ByteDance</a></td></tr><tr><td>2</td><td><a href="https://github.com/niltor/open-pdd-net-sdk" target="_blank">open-pdd-net-sdk</a></td><td>C#拼多多开放平台SDK。</td><td><a href="https://github.com/niltor/open-pdd-net-sdk" target="_blank">https://github.com/niltor/open-pdd-net-sdk</a></td></tr><tr><td>1</td><td><a href="https://github.com/aliyun/aliyun-oss-csharp-sdk" target="_blank">aliyun-oss-csharp-sdk</a></td><td>C# 阿里云 OSS SDK。</td><td><a href="https://github.com/aliyun/aliyun-oss-csharp-sdk" target="_blank">https://github.com/aliyun/aliyun-oss-csharp-sdk</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section></section><section><h3>界面&amp;控件&amp;UI库<a href="#界面控件ui库"><span>#</span></a></h3><section><h4>Blazor UI库<a href="#blazor-ui库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>16</td><td></td><td></td><td></td></tr><tr><td>15</td><td></td><td></td><td></td></tr><tr><td>14</td><td></td><td></td><td></td></tr><tr><td>13</td><td><a href="https://github.com/erossini/BlazorChartjs" target="_blank">BlazorChartjs</a></td><td>BlazorChartjs是一个在Blazor中使用Chart.js的库（支持Blazor WebAssembly和Blazor Server两种模式），它提供了简单易用的组件来帮助开发者快速集成数据可视化图表到他们的 Blazor 应用程序中。</td><td><a href="https://github.com/erossini/BlazorChartjs" target="_blank">https://github.com/erossini/BlazorChartjs</a></td></tr><tr><td>12</td><td><a href="https://github.com/mariusmuntean/ChartJs.Blazor" target="_blank">ChartJs.Blazor</a></td><td>ChartJs.Blazor 是一个基于C#和Blazor开发的前端开源图表库，它把ChartJs引入到了Blazor中, 并提供了开箱即用的实现，并且支持了 Client 和 Server 两种模式。</td><td><a href="https://github.com/mariusmuntean/ChartJs.Blazor" target="_blank">https://github.com/mariusmuntean/ChartJs.Blazor</a></td></tr><tr><td>11</td><td><a href="https://github.com/apexcharts/Blazor-ApexCharts" target="_blank">Blazor-ApexCharts</a></td><td>基于ApexCharts.js封装的C#开源免费的Blazor图表库。</td><td><a href="https://github.com/apexcharts/Blazor-ApexCharts" target="_blank">https://github.com/apexcharts/Blazor-ApexCharts</a></td></tr><tr><td>10</td><td><a href="https://github.com/vikramlearning/blazorbootstrap" target="_blank">BlazorBootstrap</a></td><td>企业级Blazor Bootstrap组件库，基于Blazor和Bootstrap CSS框架构建。</td><td><a href="https://github.com/vikramlearning/blazorbootstrap" target="_blank">https://github.com/vikramlearning/blazorbootstrap</a></td></tr><tr><td>9</td><td><a href="https://github.com/ant-design-blazor/ant-design-blazor" target="_blank">Ant Design Blazor</a></td><td>Ant Design Blazor是一套基于Ant Design和 Blazor的企业级组件库（喜欢Ant Design风格的同学推荐使用）。</td><td><a href="https://antblazor.com/zh-CN/docs/introduce" target="_blank">https://antblazor.com/zh-CN/docs/introduce</a></td></tr><tr><td>8</td><td><a href="https://github.com/SamProf/MatBlazor" target="_blank">MatBlazor</a></td><td>MatBlazor是一套基于Material Design规范实现的Blazor和Razor通用组件库。</td><td><a href="https://github.com/SamProf/MatBlazor" target="_blank">https://github.com/SamProf/MatBlazor</a></td></tr><tr><td>7</td><td><a href="https://gitee.com/LongbowEnterprise/BootstrapBlazor" target="_blank">BootstrapBlazor</a></td><td>BootstrapBlazor是一套基于 Bootstrap 和 Blazor 的企业级组件库，可以认为是 Bootstrap 项目的 Blazor 版实现。基于 Bootstrap 样式库精心打造，并且额外增加了 100 多种常用的组件，为您快速开发项目带来非一般的感觉（喜欢Bootstrap风格的同学推荐使用）。</td><td><a href="https://gitee.com/LongbowEnterprise/BootstrapBlazor" target="_blank">https://gitee.com/LongbowEnterprise/BootstrapBlazor</a></td></tr><tr><td>6</td><td><a href="https://github.com/MudBlazor/MudBlazor" target="_blank">MudBlazor</a></td><td>MudBlazor是一个基于Material Design的Blazor组件框架，注重易用性和清晰的结构。它非常适合想要快速构建Web应用程序的 .NET 开发人员，无需费力地处理 CSS 和 JavaScript。由于 MudBlazor 完全使用C#编写，因此您可以自由地调整、修复或扩展该框架。文档中有大量示例代码，使理解和学习 MudBlazor 非常容易。</td><td><a href="https://mudblazor.com/docs/overview" target="_blank">https://mudblazor.com/docs/overview</a></td></tr><tr><td>5</td><td><a href="https://github.com/Megabit/Blazorise" target="_blank">Blazorise</a></td><td>Blazorise 是用于Blazor的 UI 组件库，支持使用Bootstrap、Tailwind、Bulma、Ant Design 和 Material 等 CSS 框架，可用于构建响应式的单页 Web 应用程序。</td><td><a href="https://blazorise.com/docs" target="_blank">https://blazorise.com/docs</a></td></tr><tr><td>4</td><td><a href="https://github.com/microsoft/fluentui-blazor" target="_blank">Microsoft Fluent UI Blazor</a></td><td>Microsoft Fluent UI Blazor是一个基于Blazor的组件库，提供了一系列的UI组件以及Fluent UI的设计系统。该库可以帮助开发人员快速构建现代化的 Web 应用程序，并且与 Blazor 技术相结合，可以实现高效而灵活的单页应用程序开发。</td><td><a href="https://www.fluentui-blazor.net/" target="_blank">https://www.fluentui-blazor.net/</a></td></tr><tr><td>3</td><td><a href="https://github.com/radzenhq/radzen-blazor" target="_blank">Radzen Blazor</a></td><td>Radzen Blazor 是一个包含70多个免费的原生 Blazor UI 组件的集合，其中包括 DataGrid、Scheduler、Charts 等功能强大的组件，并提供了丰富的主题样式，包括 Material Design 和 FluentUI。可以将 Radzen Blazor 视为一个用于构建 Blazor 应用程序的 UI 框架，它提供了一系列预构建的组件和工具，帮助开发人员快速搭建和定制自己的应用程序界面。</td><td><a href="https://github.com/radzenhq/radzen-blazor" target="_blank">https://github.com/radzenhq/radzen-blazor</a></td></tr><tr><td>2</td><td><a href="https://github.com/masastack/MASA.Blazor" target="_blank">MASA.Blazor</a></td><td>基于Material设计规范和BlazorComponent的交互能力提供标准的基础组件库。提供如布局、弹框标准、Loading、全局异常处理等标准场景的预置组件。从更多实际场景出发，满足更多用户和场景的需求，最大的减少开发者的时间成本。缩短开发周期提高开发效率。</td><td><a href="https://docs.masastack.com/blazor/getting-started/installation" target="_blank">https://docs.masastack.com/blazor/getting-started/installation</a></td></tr><tr><td>1</td><td><a href="https://github.com/chanan/BlazorStrap" target="_blank">BlazorStrap</a></td><td>BlazorStrap是一个基于 Bootstrap 的 Blazor 的 UI 组件库，BlazorStrap的组件也支持响应式布局、主题定制以及多语言支持等功能，可以帮助开发者快速搭建出美观、易用的 Web 应用程序。</td><td><a href="https://getbootstrap.com/docs/5.1/getting-started/introduction/" target="_blank">https://getbootstrap.com/docs/5.1/getting-started/introduction/</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>WPF UI库<a href="#wpf-ui库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>16</td><td></td><td></td><td></td></tr><tr><td>15</td><td></td><td></td><td></td></tr><tr><td>14</td><td></td><td></td><td></td></tr><tr><td>13</td><td><a href="https://github.com/Kinnara/ModernWpf" target="_blank">ModernWpf</a></td><td>适用于 WPF 应用程序的现代样式和控件。</td><td><a href="https://github.com/Kinnara/ModernWpf" target="_blank">https://github.com/Kinnara/ModernWpf</a></td></tr><tr><td>12</td><td><a href="https://github.com/TanyaPristupova/WpfOfficeTheme" target="_blank">WpfOfficeTheme</a></td><td>Office风格的WPF主题。</td><td><a href="https://github.com/TanyaPristupova/WpfOfficeTheme" target="_blank">https://github.com/TanyaPristupova/WpfOfficeTheme</a></td></tr><tr><td>11</td><td><a href="https://github.com/lepoco/wpfui" target="_blank">WPF UI</a></td><td>WPF UI 是一个为 WPF 框架提供 Fluent 设计体验的项目。它提供直观的设计、主题、导航和全新的沉浸式控件，全部都是原生且无缝地集成在一起。</td><td><a href="https://github.com/lepoco/wpfui" target="_blank">https://github.com/lepoco/wpfui</a></td></tr><tr><td>10</td><td><a href="https://github.com/sourcechord/FluentWPF" target="_blank">FluentWPF</a></td><td>基于Fluent Design设计风格的WPF UI界面库。</td><td><a href="https://github.com/sourcechord/FluentWPF" target="_blank">https://github.com/sourcechord/FluentWPF</a></td></tr><tr><td>9</td><td><a href="https://github.com/benruehl/adonis-ui" target="_blank">Adonis UI</a></td><td>为WPF应用程序提供的轻量级UI工具包，提供经典且增强的窗口视觉效果。</td><td><a href="https://github.com/benruehl/adonis-ui" target="_blank">https://github.com/benruehl/adonis-ui</a></td></tr><tr><td>8</td><td><a href="https://github.com/Layui-WPF-Team/Layui-WPF" target="_blank">LayUI-WPF</a></td><td>一个WPF版的LayUI前端UI样式库，该控件库参考了Web版本的LayUI风格，利用该控件库可以完成现代化UI客户端程序，让你的客户端看起来更加简洁丰富又不失美感。</td><td><a href="https://github.com/Layui-WPF-Team/Layui-WPF" target="_blank">https://github.com/Layui-WPF-Team/Layui-WPF</a></td></tr><tr><td>7</td><td><a href="https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit" target="_blank">MaterialDesignInXamlToolkit</a></td><td>一个开源、易于使用、强大的 WPF UI 控件库，旨在帮助开发人员在 C# 和 VB.Net 中实现 Google 的 Material Design 风格的用户界面。该框架提供了一组丰富的控件、样式和效果，使开发人员能够轻松创建现代化、具有吸引力的应用程序。</td><td><a href="http://materialdesigninxaml.net" target="_blank">http://materialdesigninxaml.net</a></td></tr><tr><td>6</td><td><a href="https://github.com/MahApps/MahApps.Metro" target="_blank">MahApps.Metro</a></td><td>MahApps.Metro 是一个开源的 WPF UI 框架，提供了现代化、平滑和美观的控件和样式，帮助开发人员轻松创建具有现代感的 Windows 桌面应用程序。</td><td><a href="https://github.com/MahApps/MahApps.Metro" target="_blank">https://github.com/MahApps/MahApps.Metro</a></td></tr><tr><td>5</td><td><a href="https://gitee.com/panuon/PanuonUI.Silver" target="_blank">PanuonUI.Silver</a></td><td>Panuon.UI的优化版本。一个漂亮的、使用样式与附加属性的WPF UI控件库。</td><td><a href="https://gitee.com/panuon/PanuonUI.Silver" target="_blank">https://gitee.com/panuon/PanuonUI.Silver</a></td></tr><tr><td>4</td><td><a href="https://github.com/944095635/DMSkin" target="_blank">DMSkin</a></td><td>DMSkin WPF 样式 UI 框架 、WPF Borderless Window 、 Custom Controls &amp; Styles 、 MVVM Support。</td><td><a href="https://github.com/944095635/DMSkin" target="_blank">https://github.com/944095635/DMSkin</a></td></tr><tr><td>3</td><td><a href="https://github.com/handyOrg/HandyControl" target="_blank">HandyControl</a></td><td>HandyControl是一套WPF控件库，它几乎重写了所有原生样式，同时包含80余款自定义控件（正逐步增加）。</td><td><a href="https://github.com/handyOrg/HandyControl" target="_blank">https://github.com/handyOrg/HandyControl</a></td></tr><tr><td>2</td><td><a href="https://github.com/Panuon/Panuon.WPF.UI" target="_blank">Panuon.WPF.UI</a></td><td>Panuon.WPF.UI 是一个开源的WPF UI 控件库，它提供了丰富的可重用的UI控件和样式，简化了WPF应用程序的开发过程。</td><td><a href="https://github.com/Panuon/Panuon.WPF.UI" target="_blank">https://github.com/Panuon/Panuon.WPF.UI</a></td></tr><tr><td>1</td><td><a href="https://github.com/aduskin/AduSkin" target="_blank">AduSkin</a></td><td>一款简单漂亮的WPF UI，融合多个开源框架组件，为个人定制的UI，可供学者参考和使用。</td><td><a href="https://github.com/aduskin/AduSkin" target="_blank">https://github.com/aduskin/AduSkin</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>WinForm UI库<a href="#winform-ui库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>10</td><td></td><td></td><td></td></tr><tr><td>9</td><td></td><td></td><td></td></tr><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td><a href="https://github.com/IgnaceMaes/MaterialSkin" target="_blank">MaterialSkin</a></td><td>一个基于Google 的 Material Design 风格开源、免费的.NET WinForms UI控件库。</td><td><a href="https://github.com/IgnaceMaes/MaterialSkin" target="_blank">https://github.com/IgnaceMaes/MaterialSkin</a></td></tr><tr><td>6</td><td><a href="https://github.com/RobinPerris/DarkUI" target="_blank">DarkUI</a></td><td>这是一个为.NET WinForms开发的深色主题控件和停靠功能库，旨在帮助开发者创建具有现代和专业外观的应用程序界面。</td><td><a href="https://github.com/RobinPerris/DarkUI" target="_blank">https://github.com/RobinPerris/DarkUI</a></td></tr><tr><td>5</td><td><a href="https://gitee.com/antdui/AntdUI" target="_blank">AntdUI</a></td><td>一款基于Ant Design设计语言、开源（Apache License）的WinForm UI界面库。</td><td><a href="https://gitee.com/antdui/AntdUI" target="_blank">https://gitee.com/antdui/AntdUI</a></td></tr><tr><td>4</td><td><a href="https://github.com/Taiizor/ReaLTaiizor" target="_blank">ReaLTaiizor</a></td><td>ReaLTaiizor是一个开源免费的.NET WinForms控件库，它提供了广泛的组件和丰富的主题选项（用户友好、注重设计），让用户可以轻松创建美观、专业的桌面应用程序。</td><td><a href="https://github.com/Taiizor/ReaLTaiizor" target="_blank">https://github.com/Taiizor/ReaLTaiizor</a></td></tr><tr><td>3</td><td><a href="https://github.com/kwwwvagaa/NetWinformControl" target="_blank">HZHControls</a></td><td>.NET WinForm自定义控件，对触屏具有更好的操作支持，项目是基于FrameWork4.0，完全原生控件开发，没有使用任何第三方控件，你可以放心的用在你的项目中。</td><td><a href="https://github.com/kwwwvagaa/NetWinformControl" target="_blank">https://github.com/kwwwvagaa/NetWinformControl</a></td></tr><tr><td>2</td><td><a href="https://github.com/yhuse/SunnyUI" target="_blank">SunnyUI</a></td><td>SunnyUI.Net, 基于.Net 4.0+、.Net 6 框架的 C# WinForm 开源控件库、工具类库、扩展类库、多页面开发框架。</td><td><a href="https://github.com/yhuse/SunnyUI" target="_blank">https://github.com/yhuse/SunnyUI</a></td></tr><tr><td>1</td><td><a href="https://github.com/XuanchenLin/NanUI" target="_blank">NanUI</a></td><td>NanUI是一个开源、免费（MIT License）的 .NET 项目，它适用于希望使用HTML5、CSS3和JavaScript等前端技术来构建Windows窗体应用用户界面的.NET/.NET Core开发人员。</td><td><a href="https://github.com/XuanchenLin/NanUI" target="_blank">https://github.com/XuanchenLin/NanUI</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>Avalonia UI库<a href="#avalonia-ui库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>10</td><td></td><td></td><td></td></tr><tr><td>9</td><td></td><td></td><td></td></tr><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td></td><td></td><td></td></tr><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td><a href="https://github.com/wieslawsoltes/ColorPicker" target="_blank">ColorPicker</a></td><td>Avalonia ColorPicker 控件。</td><td><a href="https://github.com/wieslawsoltes/ColorPicker" target="_blank">https://github.com/wieslawsoltes/ColorPicker</a></td></tr><tr><td>4</td><td><a href="https://github.com/flarive/Neumorphism.Avalonia" target="_blank">Neumorphism.Avalonia</a></td><td>AvaloniaUI 框架易于使用且可定制的 Neumorphism Design UI主题库。</td><td><a href="https://github.com/flarive/Neumorphism.Avalonia" target="_blank">https://github.com/flarive/Neumorphism.Avalonia</a></td></tr><tr><td>3</td><td><a href="https://github.com/kikipoulet/SukiUI" target="_blank">SukiUI</a></td><td>C# Avalonia开源、免费的桌面UI库。</td><td><a href="https://github.com/kikipoulet/SukiUI" target="_blank">https://github.com/kikipoulet/SukiUI</a></td></tr><tr><td>2</td><td><a href="https://github.com/irihitech/Ursa.Avalonia" target="_blank">Ursa.Avalonia</a></td><td>Ursa 是一个 UI 库，用于使用 Avalonia UI 构建跨平台 UI。</td><td><a href="https://github.com/irihitech/Ursa.Avalonia" target="_blank">https://github.com/irihitech/Ursa.Avalonia</a></td></tr><tr><td>1</td><td><a href="https://github.com/PieroCastillo/Aura.UI" target="_blank">Aura.UI</a></td><td>提供了大量的Avalonia UI控件的库。</td><td><a href="https://github.com/PieroCastillo/Aura.UI" target="_blank">https://github.com/PieroCastillo/Aura.UI</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>MAUI UI库<a href="#maui-ui库"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>10</td><td></td><td></td><td></td></tr><tr><td>9</td><td></td><td></td><td></td></tr><tr><td>8</td><td></td><td></td><td></td></tr><tr><td>7</td><td></td><td></td><td></td></tr><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td><a href="https://github.com/RadekVyM/SimpleToolkit" target="_blank">SimpleToolkit</a></td><td>SimpleToolkit是一个.NET MAUI库，其中包含辅助工具和简单易用、完全可自定义的控件，比如SimpleShell - 自定义Shell实现，允许你创建独特的导航体验。</td><td><a href="https://github.com/RadekVyM/SimpleToolkit" target="_blank">https://github.com/RadekVyM/SimpleToolkit</a></td></tr><tr><td>4</td><td><a href="https://github.com/Redth/Maui.VirtualListView" target="_blank">Maui.VirtualListView</a></td><td>一个为 .NET MAUI 创建虚拟化 ListView 控件的实验，通过不添加太多花哨功能并使用适配器模式数据源来支持简单、快速、多模板、不均匀项目大小的列表。</td><td><a href="https://github.com/Redth/Maui.VirtualListView" target="_blank">https://github.com/Redth/Maui.VirtualListView</a></td></tr><tr><td>3</td><td><a href="https://github.com/yurkinh/Plugin.Maui.Calendar" target="_blank">Plugin.Maui.Calendar</a></td><td>Plugin.Maui.Calendar 是一个.NET MAUI 版本的 XF 日历插件，它是 lilcodelab 的 Xamarin.Forms 日历插件的一个移植版本。</td><td><a href="https://github.com/yurkinh/Plugin.Maui.Calendar" target="_blank">https://github.com/yurkinh/Plugin.Maui.Calendar</a></td></tr><tr><td>2</td><td><a href="https://github.com/FreakyAli/Maui.FreakyEffects" target="_blank">Maui.FreakyEffects</a></td><td>FreakyEffects 是一个为 .NET MAUI 提供的效果工具包，它提供一组效果和实用工具，用于构建现代移动应用程序。</td><td><a href="https://github.com/FreakyAli/Maui.FreakyEffects" target="_blank">https://github.com/FreakyAli/Maui.FreakyEffects</a></td></tr><tr><td>1</td><td><a href="https://github.com/enisn/UraniumUI" target="_blank">UraniumUI</a></td><td>Uranium是一个.NET MAUI开源免费的UI工具包。它提供了一组用于构建现代应用程序的控件和实用程序，它构建在.NET MAUI基础架构之上，并提供一组控件和布局来构建现代UI。它还提供了用于在其上构建自定义控件和主题的基础设施。</td><td><a href="https://github.com/enisn/UraniumUI" target="_blank">https://github.com/enisn/UraniumUI</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section></section><section><h3>程序设计基础知识库<a href="#程序设计基础知识库"><span>#</span></a></h3><section><h4>设计模式<a href="#设计模式"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/Coder-EdisonZhou/DesignPattern.Samples.CSharp" target="_blank">DesignPattern.Samples.CSharp</a></td><td>23种面向对象设计模式示例代码（C#实现）。</td><td><a href="https://github.com/Coder-EdisonZhou/DesignPattern.Samples.CSharp" target="_blank">https://github.com/Coder-EdisonZhou/DesignPattern.Samples.CSharp</a></td></tr><tr><td>1</td><td><a href="https://github.com/sheng-jie/Design-Pattern" target="_blank">Design-Pattern</a></td><td>设计模式 C# 版（ .NET 6）。</td><td><a href="https://github.com/sheng-jie/Design-Pattern" target="_blank">https://github.com/sheng-jie/Design-Pattern</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section><section><h4>数据结构与算法<a href="#数据结构与算法"><span>#</span></a></h4>

<table><thead><tr><th>✍</th><th>项目名称和地址</th><th>项目简介</th><th>项目详细介绍（文档、文章、源码地址）</th></tr></thead><tbody><tr><td>6</td><td></td><td></td><td></td></tr><tr><td>5</td><td></td><td></td><td></td></tr><tr><td>4</td><td></td><td></td><td></td></tr><tr><td>3</td><td></td><td></td><td></td></tr><tr><td>2</td><td><a href="https://github.com/TheAlgorithms/C-Sharp" target="_blank">TheAlgorithms/C-Sharp</a></td><td>一个C#实现的各种算法集合，这些算法涵盖了计算机科学、数学和统计学、数据科学、机器学习、工程等多个领域。这些实现及其相关文档旨在为教育工作者和学生提供学习资源。因此，可能会找到针对同一目标使用不同算法策略和优化的多种实现。</td><td><a href="https://github.com/TheAlgorithms/C-Sharp" target="_blank">https://github.com/TheAlgorithms/C-Sharp</a></td></tr><tr><td>1</td><td><a href="https://github.com/krahets/hello-algo" target="_blank">Hello算法</a></td><td>一个支持C#的开源免费、新手友好的数据结构与算法入门教程,动画图解、一键运行的数据结构与算法教程。</td><td><a href="https://github.com/krahets/hello-algo" target="_blank">https://github.com/krahets/hello-algo</a></td></tr></tbody></table><p><a href="https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md#%E9%A1%B9%E7%9B%AE%E5%88%86%E7%B1%BB%E5%96%84%E7%94%A8ctrlf" target="_blank">🔝项目分类</a></p></section></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/ec90412d/</id>
      <title type="text">【Linux】常用命令</title>
      <published>2024-05-25T08:31:13.000Z</published>
      <updated>2024-05-25T08:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/ec90412d/"/>
      <summary type="text">本文档《【Linux】常用命令》详细列出了Linux系统中常用的命令及其用法，涵盖了从基本命令、关机操作、文件和目录管理、文件搜索、文件系统的挂载与卸载、磁盘空间管理、文件权限设置、文件的特殊属性、打包和压缩文件、RPM包管理、YUM软件包升级器、DEB包管理、查看文件内容、文本处理、字符设置和文件格式转换等操作。</summary>
      <content type="html"><![CDATA[<ol>
<li>
<section><h2>基本命令<a href="#基本命令"><span>#</span></a></h2></section>
</li>
</ol>
<hr />
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>uname</span><span> </span><span>-m</span><span> </span><span>显示机器的处理器架构</span></div></div><div><div><div>2</div></div><div><span>uname</span><span> </span><span>-r</span><span> </span><span>显示正在使用的内核版本</span></div></div><div><div><div>3</div></div><div><span>dmidecode</span><span> </span><span>-q</span><span> </span><span>显示硬件系统部件</span></div></div><div><div><div>4</div></div><div><span>(</span><span>SMBIOS</span><span> </span><span>/</span><span> </span><span>DMI</span><span>) </span><span>hdparm</span><span> </span><span>-i</span><span> </span><span>/dev/hda</span><span> </span><span>罗列一个磁盘的架构特性</span></div></div><div><div><div>5</div></div><div><span>hdparm</span><span> </span><span>-tT</span><span> </span><span>/dev/sda</span><span> </span><span>在磁盘上执行测试性读取操作系统信息</span></div></div><div><div><div>6</div></div><div><span>arch</span><span> </span><span>显示机器的处理器架构</span></div></div><div><div><div>7</div></div><div><span>uname</span><span> </span><span>-m</span><span> </span><span>显示机器的处理器架构</span></div></div><div><div><div>8</div></div><div><span>uname</span><span> </span><span>-r</span><span> </span><span>显示正在使用的内核版本</span></div></div><div><div><div>9</div></div><div><span>dmidecode</span><span> </span><span>-q</span><span> </span><span>显示硬件系统部件</span><span> </span><span>-</span><span> (SMBIOS </span><span>/</span><span> </span><span>DMI</span><span>)</span></div></div><div><div><div>10</div></div><div><span>hdparm</span><span> </span><span>-i</span><span> </span><span>/dev/hda</span><span> </span><span>罗列一个磁盘的架构特性</span></div></div><div><div><div>11</div></div><div><span>hdparm</span><span> </span><span>-tT</span><span> </span><span>/dev/sda</span><span> </span><span>在磁盘上执行测试性读取操作</span></div></div><div><div><div>12</div></div><div><span>cat</span><span> </span><span>/proc/cpuinfo</span><span> </span><span>显示CPU</span><span> </span><span>info的信息</span></div></div><div><div><div>13</div></div><div><span>cat</span><span> </span><span>/proc/interrupts</span><span> </span><span>显示中断</span></div></div><div><div><div>14</div></div><div><span>cat</span><span> </span><span>/proc/meminfo</span><span> </span><span>校验内存使用</span></div></div><div><div><div>15</div></div><div><span>cat</span><span> </span><span>/proc/swaps</span><span> </span><span>显示哪些swap被使用</span></div></div><div><div><div>16</div></div><div><span>cat</span><span> </span><span>/proc/version</span><span> </span><span>显示内核的版本</span></div></div><div><div><div>17</div></div><div><span>cat</span><span> </span><span>/proc/net/dev</span><span> </span><span>显示网络适配器及统计</span></div></div><div><div><div>18</div></div><div><span>cat</span><span> </span><span>/proc/mounts</span><span> </span><span>显示已加载的文件系统</span></div></div><div><div><div>19</div></div><div><span>lspci</span><span> </span><span>-tv</span><span> </span><span>罗列</span><span> </span><span>PCI</span><span> </span><span>设备</span></div></div><div><div><div>20</div></div><div><span>lsusb</span><span> </span><span>-tv</span><span> </span><span>显示</span><span> </span><span>USB</span><span> </span><span>设备</span></div></div><div><div><div>21</div></div><div><span>date</span><span> </span><span>显示系统日期</span></div></div><div><div><div>22</div></div><div><span>cal</span><span> </span><span>2007</span><span> </span><span>显示2007年的日历表</span></div></div><div><div><div>23</div></div><div><span>date</span><span> </span><span>041217002007.00</span><span> </span><span>设置日期和时间</span><span> </span><span>-</span><span> </span><span>月日时分年.秒</span></div></div><div><div><div>24</div></div><div><span>clock</span><span> </span><span>-w</span><span> </span><span>将时间修改保存到</span><span> </span><span>BIOS</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>

<ol>
<li>
<section><h2>关机<a href="#关机"><span>#</span></a></h2></section>
</li>
</ol>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>shutdown</span><span> </span><span>-h</span><span> </span><span>now</span><span> </span><span>关闭系统</span><span>(</span><span>1</span><span>)</span></div></div><div><div><div>2</div></div><div><span>init</span><span> </span><span>0</span><span> </span><span>关闭系统</span><span>(</span><span>2</span><span>)</span></div></div><div><div><div>3</div></div><div><span>telinit</span><span> </span><span>0</span><span> </span><span>关闭系统</span><span>(</span><span>3</span><span>)</span></div></div><div><div><div>4</div></div><div><span>shutdown</span><span> </span><span>-h</span><span> </span><span>hours:minutes</span><span> &amp; </span><span>按预定时间关闭系统</span></div></div><div><div><div>5</div></div><div><span>shutdown</span><span> </span><span>-c</span><span> </span><span>取消按预定时间关闭系统</span></div></div><div><div><div>6</div></div><div><span>shutdown</span><span> </span><span>-r</span><span> </span><span>now</span><span> </span><span>重启</span><span>(</span><span>1</span><span>)</span></div></div><div><div><div>7</div></div><div><span>reboot</span><span> </span><span>重启</span><span>(</span><span>2</span><span>)</span></div></div><div><div><div>8</div></div><div><span>logout 注销</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ol>
<li>
<section><h2>文件和目录<a href="#文件和目录"><span>#</span></a></h2></section>
</li>
</ol>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/home</span><span> </span><span>进入</span><span> </span><span>'/ home'</span><span> </span><span>目录'</span></div></div><div><div><div>2</div></div><div><span>cd .. 返回上一级目录</span></div></div><div><div><div>3</div></div><div><span>cd ../.. 返回上两级目录</span></div></div><div><div><div>4</div></div><div><span>cd 进入个人的主目录</span></div></div><div><div><div>5</div></div><div><span>cd ~user1 进入个人的主目录</span></div></div><div><div><div>6</div></div><div><span>cd - 返回上次所在的目录</span></div></div><div><div><div>7</div></div><div><span>pwd 显示工作路径</span></div></div><div><div><div>8</div></div><div><span>ls 查看目录中的文件</span></div></div><div><div><div>9</div></div><div><span>ls -F 查看目录中的文件</span></div></div><div><div><div>10</div></div><div><span>ls -l 显示文件和目录的详细资料</span></div></div><div><div><div>11</div></div><div><span>ls -a 显示隐藏文件</span></div></div><div><div><div>12</div></div><div><span>ls *[0-9]* 显示包含数字的文件名和目录名</span></div></div><div><div><div>13</div></div><div><span>tree 显示文件和目录由根目录开始的树形结构(1)</span></div></div><div><div><div>14</div></div><div><span>lstree 显示文件和目录由根目录开始的树形结构(2)</span></div></div><div><div><div>15</div></div><div><span>mkdir dir1 创建一个叫做 'dir1' 的目录'</span></div></div><div><div><div>16</div></div><div><span>mkdir</span><span> </span><span>dir1</span><span> </span><span>dir2</span><span> </span><span>同时创建两个目录</span></div></div><div><div><div>17</div></div><div><span>mkdir</span><span> </span><span>-p</span><span> </span><span>/tmp/dir1/dir2</span><span> </span><span>创建一个目录树</span></div></div><div><div><div>18</div></div><div><span>rm</span><span> </span><span>-f</span><span> </span><span>file1</span><span> </span><span>删除一个叫做</span><span> </span><span>'file1'</span><span> </span><span>的文件'</span></div></div><div><div><div>19</div></div><div><span>rmdir dir1 删除一个叫做 'dir1' 的目录'</span></div></div><div><div><div>20</div></div><div><span>rm</span><span> </span><span>-rf</span><span> </span><span>dir1</span><span> </span><span>删除一个叫做</span><span> </span><span>'dir1'</span><span> </span><span>的目录并同时删除其内容</span></div></div><div><div><div>21</div></div><div><span>rm</span><span> </span><span>-rf</span><span> </span><span>dir1</span><span> </span><span>dir2</span><span> </span><span>同时删除两个目录及它们的内容</span></div></div><div><div><div>22</div></div><div><span>mv</span><span> </span><span>dir1</span><span> </span><span>new_dir</span><span> </span><span>重命名/移动</span><span> </span><span>一个目录</span></div></div><div><div><div>23</div></div><div><span>cp</span><span> </span><span>file1</span><span> </span><span>file2</span><span> </span><span>复制一个文件</span></div></div><div><div><div>24</div></div><div><span>cp</span><span> </span><span>dir/</span><span>*</span><span> </span><span>.</span><span> </span><span>复制一个目录下的所有文件到当前工作目录</span></div></div><div><div><div>25</div></div><div><span>cp</span><span> </span><span>-a</span><span> </span><span>/tmp/dir1</span><span> </span><span>.</span><span> </span><span>复制一个目录到当前工作目录</span></div></div><div><div><div>26</div></div><div><span>cp</span><span> </span><span>-a</span><span> </span><span>dir1</span><span> </span><span>dir2</span><span> </span><span>复制一个目录</span></div></div><div><div><div>27</div></div><div><span>ln</span><span> </span><span>-s</span><span> </span><span>file1</span><span> </span><span>lnk1</span><span> </span><span>创建一个指向文件或目录的软链接</span></div></div><div><div><div>28</div></div><div><span>ln</span><span> </span><span>file1</span><span> </span><span>lnk1</span><span> </span><span>创建一个指向文件或目录的物理链接</span></div></div><div><div><div>29</div></div><div><span>touch</span><span> </span><span>-t</span><span> </span><span>0712250000</span><span> </span><span>file1</span><span> </span><span>修改一个文件或目录的时间戳</span><span> </span><span>-</span><span> (YYMMDDhhmm)</span></div></div><div><div><div>30</div></div><div><span>file</span><span> </span><span>file1</span><span> </span><span>outputs</span><span> </span><span>the</span><span> </span><span>mime</span><span> </span><span>type</span><span> </span><span>of</span><span> </span><span>the</span><span> </span><span>file</span><span> </span><span>as</span><span> </span><span>text</span></div></div><div><div><div>31</div></div><div><span>iconv</span><span> </span><span>-l</span><span> </span><span>列出已知的编码</span></div></div><div><div><div>32</div></div><div><span>iconv</span><span> </span><span>-f</span><span> </span><span>fromEncoding</span><span> </span><span>-t</span><span> </span><span>toEncoding</span><span> </span><span>inputFile</span><span> &gt; </span><span>outputFile</span><span> </span><span>creates</span><span> </span><span>a</span><span> </span><span>new</span><span> </span><span>from</span><span> </span><span>the</span><span> </span><span>given</span><span> </span><span>input</span><span> </span><span>file</span><span> </span><span>by</span><span> </span><span>assuming</span><span> </span><span>it</span><span> </span><span>is</span><span> </span><span>encoded</span><span> </span><span>in</span><span> </span><span>fromEncoding</span><span> </span><span>and</span><span> </span><span>converting</span><span> </span><span>it</span><span> </span><span>to</span><span> </span><span>toEncoding.</span></div></div><div><div><div>33</div></div><div><span>find</span><span> </span><span>.</span><span> </span><span>-maxdepth</span><span> </span><span>1</span><span> </span><span>-name</span><span> </span><span>*</span><span>.jpg</span><span> </span><span>-print</span><span> </span><span>-exec</span><span> </span><span>convert</span><span> </span><span>"{}"</span><span> </span><span>-resize</span><span> </span><span>80x60</span><span> </span><span>"thumbs/{}"</span><span> </span><span>\;</span><span> </span><span>batch</span><span> </span><span>resize</span><span> </span><span>files</span><span> </span><span>in</span><span> </span><span>the</span><span> </span><span>current</span><span> </span><span>directory</span><span> </span><span>and</span><span> </span><span>send</span><span> </span><span>them</span><span> </span><span>to</span><span> </span><span>a</span><span> </span><span>thumbnails</span><span> </span><span>directory</span><span> (requires </span><span>convert</span><span> </span><span>from</span><span> </span><span>Imagemagick</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<ol>
<li>
<section><h2>文件搜索<a href="#文件搜索"><span>#</span></a></h2></section>
</li>
</ol>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>find</span><span> </span><span>/</span><span> </span><span>-name</span><span> </span><span>file1</span><span> </span><span>从</span><span> </span><span>'/'</span><span> </span><span>开始进入根文件系统搜索文件和目录</span></div></div><div><div><div>2</div></div><div><span>find</span><span> </span><span>/</span><span> </span><span>-user</span><span> </span><span>user1</span><span> </span><span>搜索属于用户</span><span> </span><span>'user1'</span><span> </span><span>的文件和目录</span></div></div><div><div><div>3</div></div><div><span>find</span><span> </span><span>/home/user1</span><span> </span><span>-name</span><span> </span><span>\*</span><span>.bin</span><span> </span><span>在目录</span><span> </span><span>'/ home/user1'</span><span> </span><span>中搜索带有'.bin'</span><span> </span><span>结尾的文件</span></div></div><div><div><div>4</div></div><div><span>find</span><span> </span><span>/usr/bin</span><span> </span><span>-type</span><span> </span><span>f</span><span> </span><span>-atime</span><span> </span><span>+100</span><span> </span><span>搜索在过去100天内未被使用过的执行文件</span></div></div><div><div><div>5</div></div><div><span>find</span><span> </span><span>/usr/bin</span><span> </span><span>-type</span><span> </span><span>f</span><span> </span><span>-mtime</span><span> </span><span>-10</span><span> </span><span>搜索在10天内被创建或者修改过的文件</span></div></div><div><div><div>6</div></div><div><span>find</span><span> </span><span>/</span><span> </span><span>-name</span><span> </span><span>\*</span><span>.rpm</span><span> </span><span>-exec</span><span> </span><span>chmod</span><span> </span><span>755</span><span> </span><span>'{}'</span><span> </span><span>\;</span><span> </span><span>搜索以</span><span> </span><span>'.rpm'</span><span> </span><span>结尾的文件并定义其权限</span></div></div><div><div><div>7</div></div><div><span>find</span><span> </span><span>/</span><span> </span><span>-xdev</span><span> </span><span>-name</span><span> </span><span>\*</span><span>.rpm</span><span> </span><span>搜索以</span><span> </span><span>'.rpm'</span><span> </span><span>结尾的文件，忽略光驱、捷盘等可移动设备</span></div></div><div><div><div>8</div></div><div><span>locate</span><span> </span><span>\*</span><span>.ps</span><span> </span><span>寻找以</span><span> </span><span>'.ps'</span><span> </span><span>结尾的文件</span><span> </span><span>-</span><span> </span><span>先运行</span><span> </span><span>'updatedb'</span><span> </span><span>命令</span></div></div><div><div><div>9</div></div><div><span>whereis</span><span> </span><span>halt</span><span> </span><span>显示一个二进制文件、源码或man的位置</span></div></div><div><div><div>10</div></div><div><span>which</span><span> </span><span>halt</span><span> </span><span>显示一个二进制文件或可执行文件的完整路径</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ol>
<li>
<section><h2>挂载一个文件系统<a href="#挂载一个文件系统"><span>#</span></a></h2></section>
</li>
</ol>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>mount</span><span> </span><span>/dev/hda2</span><span> </span><span>/mnt/hda2</span><span> </span><span>挂载一个叫做hda2的盘</span><span> </span><span>-</span><span> </span><span>确定目录</span><span> </span><span>'/ mnt/hda2'</span><span> </span><span>已经存在</span></div></div><div><div><div>2</div></div><div><span>umount</span><span> </span><span>/dev/hda2</span><span> </span><span>卸载一个叫做hda2的盘</span><span> </span><span>-</span><span> </span><span>先从挂载点</span><span> </span><span>'/ mnt/hda2'</span><span> </span><span>退出</span></div></div><div><div><div>3</div></div><div><span>fuser</span><span> </span><span>-km</span><span> </span><span>/mnt/hda2</span><span> </span><span>当设备繁忙时强制卸载</span></div></div><div><div><div>4</div></div><div><span>umount</span><span> </span><span>-n</span><span> </span><span>/mnt/hda2</span><span> </span><span>运行卸载操作而不写入</span><span> </span><span>/etc/mtab</span><span> </span><span>文件-</span><span> </span><span>当文件为只读或当磁盘写满时非常有用</span></div></div><div><div><div>5</div></div><div><span>mount</span><span> </span><span>/dev/fd0</span><span> </span><span>/mnt/floppy</span><span> </span><span>挂载一个软盘</span></div></div><div><div><div>6</div></div><div><span>mount</span><span> </span><span>/dev/cdrom</span><span> </span><span>/mnt/cdrom</span><span> </span><span>挂载一个cdrom或dvdrom</span></div></div><div><div><div>7</div></div><div><span>mount</span><span> </span><span>/dev/hdc</span><span> </span><span>/mnt/cdrecorder</span><span> </span><span>挂载一个cdrw或dvdrom</span></div></div><div><div><div>8</div></div><div><span>mount</span><span> </span><span>/dev/hdb</span><span> </span><span>/mnt/cdrecorder</span><span> </span><span>挂载一个cdrw或dvdrom</span></div></div><div><div><div>9</div></div><div><span>mount</span><span> </span><span>-o</span><span> </span><span>loop</span><span> </span><span>file.iso</span><span> </span><span>/mnt/cdrom</span><span> </span><span>挂载一个文件或ISO镜像文件</span></div></div><div><div><div>10</div></div><div><span>mount</span><span> </span><span>-t</span><span> </span><span>vfat</span><span> </span><span>/dev/hda5</span><span> </span><span>/mnt/hda5</span><span> </span><span>挂载一个Windows</span><span> </span><span>FAT32文件系统</span></div></div><div><div><div>11</div></div><div><span>mount</span><span> </span><span>/dev/sda1</span><span> </span><span>/mnt/usbdisk</span><span> </span><span>挂载一个usb</span><span> </span><span>捷盘或闪存设备</span></div></div><div><div><div>12</div></div><div><span>mount</span><span> </span><span>-t</span><span> </span><span>smbfs</span><span> </span><span>-o</span><span> </span><span>username=user,password=pass</span><span> </span><span>//WinClient/share</span><span> </span><span>/mnt/share</span><span> </span><span>挂载一个windows网络共享</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ol>
<li>
<section><h2>磁盘空间<a href="#磁盘空间"><span>#</span></a></h2></section>
</li>
</ol>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>df</span><span> </span><span>-h</span><span> </span><span>显示已经挂载的分区列表</span></div></div><div><div><div>2</div></div><div><span>ls</span><span> </span><span>-lSr</span><span> |</span><span>more</span><span> </span><span>以尺寸大小排列文件和目录</span></div></div><div><div><div>3</div></div><div><span>du</span><span> </span><span>-sh</span><span> </span><span>dir1</span><span> </span><span>估算目录</span><span> </span><span>'dir1'</span><span> </span><span>已经使用的磁盘空间'</span></div></div><div><div><div>4</div></div><div><span>du -sk * | sort -rn 以容量大小为依据依次显示文件和目录的大小</span></div></div><div><div><div>5</div></div><div><span>rpm -q -a --qf '%10{SIZE}t%{NAME}n' | sort -k1,1n 以大小为依据依次显示已安装的rpm包所使用的空间 (fedora, redhat类系统)</span></div></div><div><div><div>6</div></div><div><span>dpkg-query -W -f='</span><span><span>${</span><span>Installed-Size</span></span><span>;</span><span><span>10</span><span>}</span></span><span>t</span><span><span>${</span><span>Package</span><span>}</span></span><span>n' | sort -k1,1n 以大小为依据显示已安装的deb包所使用的空间 (ubuntu, debian类系统)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<hr />
<ol>
<li>
<section><h2>用户和群组<a href="#用户和群组"><span>#</span></a></h2></section>
</li>
</ol>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>groupadd</span><span> </span><span>group_name</span><span> </span><span>创建一个新用户组</span></div></div><div><div><div>2</div></div><div><span>groupdel</span><span> </span><span>group_name</span><span> </span><span>删除一个用户组</span></div></div><div><div><div>3</div></div><div><span>groupmod</span><span> </span><span>-n</span><span> </span><span>new_group_name</span><span> </span><span>old_group_name</span><span> </span><span>重命名一个用户组</span></div></div><div><div><div>4</div></div><div><span>useradd</span><span> </span><span>-c</span><span> </span><span>"Name Surname "</span><span> </span><span>-g</span><span> </span><span>admin</span><span> </span><span>-d</span><span> </span><span>/home/user1</span><span> </span><span>-s</span><span> </span><span>/bin/bash</span><span> </span><span>user1</span><span> </span><span>创建一个属于</span><span> </span><span>"admin"</span><span> </span><span>用户组的用户</span></div></div><div><div><div>5</div></div><div><span>useradd</span><span> </span><span>user1</span><span> </span><span>创建一个新用户</span></div></div><div><div><div>6</div></div><div><span>userdel</span><span> </span><span>-r</span><span> </span><span>user1</span><span> </span><span>删除一个用户</span><span> ( </span><span>'-r'</span><span> </span><span>排除主目录</span><span>)</span></div></div><div><div><div>7</div></div><div><span>usermod</span><span> </span><span>-c</span><span> </span><span>"User FTP"</span><span> </span><span>-g</span><span> </span><span>system</span><span> </span><span>-d</span><span> </span><span>/ftp/user1</span><span> </span><span>-s</span><span> </span><span>/bin/nologin</span><span> </span><span>user1</span><span> </span><span>修改用户属性</span></div></div><div><div><div>8</div></div><div><span>passwd</span><span> </span><span>修改口令</span></div></div><div><div><div>9</div></div><div><span>passwd</span><span> </span><span>user1</span><span> </span><span>修改一个用户的口令</span><span> (只允许root执行)</span></div></div><div><div><div>10</div></div><div><span>chage</span><span> </span><span>-E</span><span> </span><span>2005-12-31</span><span> </span><span>user1</span><span> </span><span>设置用户口令的失效期限</span></div></div><div><div><div>11</div></div><div><span>pwck</span><span> </span><span>检查</span><span> </span><span>'/etc/passwd'</span><span> </span><span>的文件格式和语法修正以及存在的用户</span></div></div><div><div><div>12</div></div><div><span>grpck</span><span> </span><span>检查</span><span> </span><span>'/etc/passwd'</span><span> </span><span>的文件格式和语法修正以及存在的群组</span></div></div><div><div><div>13</div></div><div><span>newgrp</span><span> </span><span>group_name</span><span> </span><span>登陆进一个新的群组以改变新创建文件的预设群组</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ol>
<li>
<section><h2>文件的权限<a href="#文件的权限"><span>#</span></a></h2></section>
</li>
</ol>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ls</span><span> </span><span>-lh</span><span> </span><span>显示权限</span></div></div><div><div><div>2</div></div><div><span>ls</span><span> </span><span>/tmp</span><span> | </span><span>pr</span><span> </span><span>-T5</span><span> </span><span>-W</span><span>$COLUMNS</span><span> </span><span>将终端划分成5栏显示</span></div></div><div><div><div>3</div></div><div><span>chmod</span><span> </span><span>ugo+rwx</span><span> </span><span>directory1</span><span> </span><span>设置目录的所有人</span><span>(</span><span>u</span><span>)</span><span>、群组</span><span>(</span><span>g</span><span>)</span><span>以及其他人</span><span>(</span><span>o</span><span>)</span><span>以读（r</span><span> </span><span>）、写</span><span>(</span><span>w</span><span>)</span><span>和执行</span><span>(</span><span>x</span><span>)</span><span>的权限</span></div></div><div><div><div>4</div></div><div><span>chmod</span><span> </span><span>go-rwx</span><span> </span><span>directory1</span><span> </span><span>删除群组</span><span>(</span><span>g</span><span>)</span><span>与其他人</span><span>(</span><span>o</span><span>)</span><span>对目录的读写执行权限</span></div></div><div><div><div>5</div></div><div><span>chown</span><span> </span><span>user1</span><span> </span><span>file1</span><span> </span><span>改变一个文件的所有人属性</span></div></div><div><div><div>6</div></div><div><span>chown</span><span> </span><span>-R</span><span> </span><span>user1</span><span> </span><span>directory1</span><span> </span><span>改变一个目录的所有人属性并同时改变改目录下所有文件的属性</span></div></div><div><div><div>7</div></div><div><span>chgrp</span><span> </span><span>group1</span><span> </span><span>file1</span><span> </span><span>改变文件的群组</span></div></div><div><div><div>8</div></div><div><span>chown</span><span> </span><span>user1:group1</span><span> </span><span>file1</span><span> </span><span>改变一个文件的所有人和群组属性</span></div></div><div><div><div>9</div></div><div><span>find</span><span> </span><span>/</span><span> </span><span>-perm</span><span> </span><span>-u+s</span><span> </span><span>罗列一个系统中所有使用了SUID控制的文件</span></div></div><div><div><div>10</div></div><div><span>chmod</span><span> </span><span>u+s</span><span> </span><span>/bin/file1</span><span> </span><span>设置一个二进制文件的</span><span> </span><span>SUID</span><span> </span><span>位</span><span> </span><span>-</span><span> </span><span>运行该文件的用户也被赋予和所有者同样的权限</span></div></div><div><div><div>11</div></div><div><span>chmod</span><span> </span><span>u-s</span><span> </span><span>/bin/file1</span><span> </span><span>禁用一个二进制文件的</span><span> </span><span>SUID位</span></div></div><div><div><div>12</div></div><div><span>chmod</span><span> </span><span>g+s</span><span> </span><span>/home/public</span><span> </span><span>设置一个目录的SGID</span><span> </span><span>位</span><span> </span><span>-</span><span> </span><span>类似SUID</span><span> </span><span>，不过这是针对目录的</span></div></div><div><div><div>13</div></div><div><span>chmod</span><span> </span><span>g-s</span><span> </span><span>/home/public</span><span> </span><span>禁用一个目录的</span><span> </span><span>SGID</span><span> </span><span>位</span></div></div><div><div><div>14</div></div><div><span>chmod</span><span> </span><span>o+t</span><span> </span><span>/home/public</span><span> </span><span>设置一个文件的</span><span> </span><span>STIKY</span><span> </span><span>位</span><span> </span><span>-</span><span> </span><span>只允许合法所有人删除文件</span></div></div><div><div><div>15</div></div><div><span>chmod</span><span> </span><span>o-t</span><span> </span><span>/home/public</span><span> </span><span>禁用一个目录的</span><span> </span><span>STIKY</span><span> </span><span>位</span></div></div><div><div><div>16</div></div><div><span>chmod</span><span> </span><span>+x</span><span> </span><span>文件路径</span><span> </span><span>为所有者、所属组和其他用户添加执行的权限</span></div></div><div><div><div>17</div></div><div><span>chmod</span><span> </span><span>-x</span><span> </span><span>文件路径</span><span> </span><span>为所有者、所属组和其他用户删除执行的权限</span></div></div><div><div><div>18</div></div><div><span>chmod</span><span> </span><span>u+x</span><span> </span><span>文件路径</span><span> </span><span>为所有者添加执行的权限</span></div></div><div><div><div>19</div></div><div><span>chmod</span><span> </span><span>g+x</span><span> </span><span>文件路径</span><span> </span><span>为所属组添加执行的权限</span></div></div><div><div><div>20</div></div><div><span>chmod</span><span> </span><span>o+x</span><span> </span><span>文件路径</span><span> </span><span>为其他用户添加执行的权限</span></div></div><div><div><div>21</div></div><div><span>chmod</span><span> </span><span>ug+x</span><span> </span><span>文件路径</span><span> </span><span>为所有者、所属组添加执行的权限</span></div></div><div><div><div>22</div></div><div><span>chmod</span><span> </span><span>=wx</span><span> </span><span>文件路径</span><span> </span><span>为所有者、所属组和其他用户添加写、执行的权限，取消读权限</span></div></div><div><div><div>23</div></div><div><span>chmod</span><span> </span><span>ug=wx</span><span> </span><span>文件路径</span><span> </span><span>为所有者、所属组添加写、执行的权限，取消读权限</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<ol>
<li>
<section><h2>文件的特殊属性<a href="#文件的特殊属性"><span>#</span></a></h2></section>
</li>
</ol>
<blockquote><p>使用 “+” 设置权限，使用 “-” 用于取消</p></blockquote>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>chattr</span><span> </span><span>+a</span><span> </span><span>file1</span><span> </span><span>只允许以追加方式读写文件</span></div></div><div><div><div>2</div></div><div><span>chattr</span><span> </span><span>+c</span><span> </span><span>file1</span><span> </span><span>允许这个文件能被内核自动压缩/解压</span></div></div><div><div><div>3</div></div><div><span>chattr</span><span> </span><span>+d</span><span> </span><span>file1</span><span> </span><span>在进行文件系统备份时，dump程序将忽略这个文件</span></div></div><div><div><div>4</div></div><div><span>chattr</span><span> </span><span>+i</span><span> </span><span>file1</span><span> </span><span>设置成不可变的文件，不能被删除、修改、重命名或者链接</span></div></div><div><div><div>5</div></div><div><span>chattr</span><span> </span><span>+s</span><span> </span><span>file1</span><span> </span><span>允许一个文件被安全地删除</span></div></div><div><div><div>6</div></div><div><span>chattr</span><span> </span><span>+S</span><span> </span><span>file1</span><span> </span><span>一旦应用程序对这个文件执行了写操作，使系统立刻把修改的结果写到磁盘</span></div></div><div><div><div>7</div></div><div><span>chattr</span><span> </span><span>+u</span><span> </span><span>file1</span><span> </span><span>若文件被删除，系统会允许你在以后恢复这个被删除的文件</span></div></div><div><div><div>8</div></div><div><span>lsattr</span><span> </span><span>显示特殊的属性</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ol>
<li>
<section><h2>打包和压缩文件<a href="#打包和压缩文件"><span>#</span></a></h2></section>
</li>
</ol>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>bunzip2</span><span> </span><span>file1.bz2</span><span> </span><span>解压一个叫做</span><span> </span><span>'file1.bz2'的文件</span></div></div><div><div><div>2</div></div><div><span>bzip2</span><span> </span><span>file1</span><span> </span><span>压缩一个叫做</span><span> </span><span>'file1'</span><span> </span><span>的文件</span></div></div><div><div><div>3</div></div><div><span>gunzip</span><span> </span><span>file1.gz</span><span> </span><span>解压一个叫做</span><span> </span><span>'file1.gz'的文件</span></div></div><div><div><div>4</div></div><div><span>gzip</span><span> </span><span>file1</span><span> </span><span>压缩一个叫做</span><span> </span><span>'file1'的文件</span></div></div><div><div><div>5</div></div><div><span>gzip</span><span> </span><span>-9</span><span> </span><span>file1</span><span> </span><span>最大程度压缩</span></div></div><div><div><div>6</div></div><div><span>rar</span><span> </span><span>a</span><span> </span><span>file1.rar</span><span> </span><span>test_file</span><span> </span><span>创建一个叫做</span><span> </span><span>'file1.rar'</span><span> </span><span>的包</span></div></div><div><div><div>7</div></div><div><span>rar</span><span> </span><span>a</span><span> </span><span>file1.rar</span><span> </span><span>file1</span><span> </span><span>file2</span><span> </span><span>dir1</span><span> </span><span>同时压缩</span><span> </span><span>'file1',</span><span> </span><span>'file2'</span><span> </span><span>以及目录</span><span> </span><span>'dir1'</span></div></div><div><div><div>8</div></div><div><span>rar</span><span> </span><span>x</span><span> </span><span>file1.rar</span><span> </span><span>解压rar包</span></div></div><div><div><div>9</div></div><div><span>unrar</span><span> </span><span>x</span><span> </span><span>file1.rar</span><span> </span><span>解压rar包</span></div></div><div><div><div>10</div></div><div><span>tar</span><span> </span><span>-cvf</span><span> </span><span>archive.tar</span><span> </span><span>file1</span><span> </span><span>创建一个非压缩的</span><span> </span><span>tarball</span></div></div><div><div><div>11</div></div><div><span>tar</span><span> </span><span>-cvf</span><span> </span><span>archive.tar</span><span> </span><span>file1</span><span> </span><span>file2</span><span> </span><span>dir1</span><span> </span><span>创建一个包含了</span><span> </span><span>'file1',</span><span> </span><span>'file2'</span><span> </span><span>以及</span><span> </span><span>'dir1'的档案文件</span></div></div><div><div><div>12</div></div><div><span>tar</span><span> </span><span>-tf</span><span> </span><span>archive.tar</span><span> </span><span>显示一个包中的内容</span></div></div><div><div><div>13</div></div><div><span>tar</span><span> </span><span>-xvf</span><span> </span><span>archive.tar</span><span> </span><span>释放一个包</span></div></div><div><div><div>14</div></div><div><span>tar</span><span> </span><span>-xvf</span><span> </span><span>archive.tar</span><span> </span><span>-C</span><span> </span><span>/tmp</span><span> </span><span>将压缩包释放到</span><span> </span><span>/tmp目录下</span></div></div><div><div><div>15</div></div><div><span>tar</span><span> </span><span>-cvfj</span><span> </span><span>archive.tar.bz2</span><span> </span><span>dir1</span><span> </span><span>创建一个bzip2格式的压缩包</span></div></div><div><div><div>16</div></div><div><span>tar</span><span> </span><span>-xvfj</span><span> </span><span>archive.tar.bz2</span><span> </span><span>解压一个bzip2格式的压缩包</span></div></div><div><div><div>17</div></div><div><span>tar</span><span> </span><span>-cvfz</span><span> </span><span>archive.tar.gz</span><span> </span><span>dir1</span><span> </span><span>创建一个gzip格式的压缩包</span></div></div><div><div><div>18</div></div><div><span>tar</span><span> </span><span>-xvfz</span><span> </span><span>archive.tar.gz</span><span> </span><span>解压一个gzip格式的压缩包</span></div></div><div><div><div>19</div></div><div><span>zip</span><span> </span><span>file1.zip</span><span> </span><span>file1</span><span> </span><span>创建一个zip格式的压缩包</span></div></div><div><div><div>20</div></div><div><span>zip</span><span> </span><span>-r</span><span> </span><span>file1.zip</span><span> </span><span>file1</span><span> </span><span>file2</span><span> </span><span>dir1</span><span> </span><span>将几个文件和目录同时压缩成一个zip格式的压缩包</span></div></div><div><div><div>21</div></div><div><span>unzip</span><span> </span><span>file1.zip</span><span> </span><span>解压一个zip格式压缩包</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<ol>
<li>
<section><h2>RPM 包<a href="#rpm-包"><span>#</span></a></h2></section>
</li>
</ol>
<ul>
<li>（Fedora, Redhat及类似系统）</li>
</ul>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>rpm</span><span> </span><span>-ivh</span><span> </span><span>package.rpm</span><span> </span><span>安装一个rpm包</span></div></div><div><div><div>2</div></div><div><span>rpm</span><span> </span><span>-ivh</span><span> </span><span>--nodeeps</span><span> </span><span>package.rpm</span><span> </span><span>安装一个rpm包而忽略依赖关系警告</span></div></div><div><div><div>3</div></div><div><span>rpm</span><span> </span><span>-U</span><span> </span><span>package.rpm</span><span> </span><span>更新一个rpm包但不改变其配置文件</span></div></div><div><div><div>4</div></div><div><span>rpm</span><span> </span><span>-F</span><span> </span><span>package.rpm</span><span> </span><span>更新一个确定已经安装的rpm包</span></div></div><div><div><div>5</div></div><div><span>rpm</span><span> </span><span>-e</span><span> </span><span>package_name.rpm</span><span> </span><span>删除一个rpm包</span></div></div><div><div><div>6</div></div><div><span>rpm</span><span> </span><span>-qa</span><span> </span><span>显示系统中所有已经安装的rpm包</span></div></div><div><div><div>7</div></div><div><span>rpm</span><span> </span><span>-qa</span><span> | </span><span>grep</span><span> </span><span>httpd</span><span> </span><span>显示所有名称中包含</span><span> </span><span>"httpd"</span><span> </span><span>字样的rpm包</span></div></div><div><div><div>8</div></div><div><span>rpm</span><span> </span><span>-qi</span><span> </span><span>package_name</span><span> </span><span>获取一个已安装包的特殊信息</span></div></div><div><div><div>9</div></div><div><span>rpm</span><span> </span><span>-qg</span><span> </span><span>"System Environment/Daemons"</span><span> </span><span>显示一个组件的rpm包</span></div></div><div><div><div>10</div></div><div><span>rpm</span><span> </span><span>-ql</span><span> </span><span>package_name</span><span> </span><span>显示一个已经安装的rpm包提供的文件列表</span></div></div><div><div><div>11</div></div><div><span>rpm</span><span> </span><span>-qc</span><span> </span><span>package_name</span><span> </span><span>显示一个已经安装的rpm包提供的配置文件列表</span></div></div><div><div><div>12</div></div><div><span>rpm</span><span> </span><span>-q</span><span> </span><span>package_name</span><span> </span><span>--whatrequires</span><span> </span><span>显示与一个rpm包存在依赖关系的列表</span></div></div><div><div><div>13</div></div><div><span>rpm</span><span> </span><span>-q</span><span> </span><span>package_name</span><span> </span><span>--whatprovides</span><span> </span><span>显示一个rpm包所占的体积</span></div></div><div><div><div>14</div></div><div><span>rpm</span><span> </span><span>-q</span><span> </span><span>package_name</span><span> </span><span>--scripts</span><span> </span><span>显示在安装/删除期间所执行的脚本l</span></div></div><div><div><div>15</div></div><div><span>rpm</span><span> </span><span>-q</span><span> </span><span>package_name</span><span> </span><span>--changelog</span><span> </span><span>显示一个rpm包的修改历史</span></div></div><div><div><div>16</div></div><div><span>rpm</span><span> </span><span>-qf</span><span> </span><span>/etc/httpd/conf/httpd.conf</span><span> </span><span>确认所给的文件由哪个rpm包所提供</span></div></div><div><div><div>17</div></div><div><span>rpm</span><span> </span><span>-qp</span><span> </span><span>package.rpm</span><span> </span><span>-l</span><span> </span><span>显示由一个尚未安装的rpm包提供的文件列表</span></div></div><div><div><div>18</div></div><div><span>rpm</span><span> </span><span>--import</span><span> </span><span>/media/cdrom/RPM-GPG-KEY</span><span> </span><span>导入公钥数字证书</span></div></div><div><div><div>19</div></div><div><span>rpm</span><span> </span><span>--checksig</span><span> </span><span>package.rpm</span><span> </span><span>确认一个rpm包的完整性</span></div></div><div><div><div>20</div></div><div><span>rpm</span><span> </span><span>-qa</span><span> </span><span>gpg-pubkey</span><span> </span><span>确认已安装的所有rpm包的完整性</span></div></div><div><div><div>21</div></div><div><span>rpm</span><span> </span><span>-V</span><span> </span><span>package_name</span><span> </span><span>检查文件尺寸、</span><span> </span><span>许可、类型、所有者、群组、MD5检查以及最后修改时间</span></div></div><div><div><div>22</div></div><div><span>rpm</span><span> </span><span>-Va</span><span> </span><span>检查系统中所有已安装的rpm包-</span><span> </span><span>小心使用</span></div></div><div><div><div>23</div></div><div><span>rpm</span><span> </span><span>-Vp</span><span> </span><span>package.rpm</span><span> </span><span>确认一个rpm包还未安装</span></div></div><div><div><div>24</div></div><div><span>rpm2cpio</span><span> </span><span>package.rpm</span><span> | </span><span>cpio</span><span> </span><span>--extract</span><span> </span><span>--make-directories</span><span> </span><span>*</span><span>bin</span><span>*</span><span> </span><span>从一个rpm包运行可执行文件</span></div></div><div><div><div>25</div></div><div><span>rpm</span><span> </span><span>-ivh</span><span> </span><span>/usr/src/redhat/RPMS/`</span><span>arch</span><span>`</span><span>/package.rpm</span><span> </span><span>从一个rpm源码安装一个构建好的包</span></div></div><div><div><div>26</div></div><div><span>rpmbuild</span><span> </span><span>--rebuild</span><span> </span><span>package_name.src.rpm</span><span> </span><span>从一个rpm源码构建一个</span><span> </span><span>rpm</span><span> </span><span>包</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<ol>
<li>
<section><h2>YUM 软件包升级器<a href="#yum-软件包升级器"><span>#</span></a></h2></section>
</li>
</ol>
<ul>
<li>（Fedora, RedHat及类似系统）</li>
</ul>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>yum</span><span> </span><span>install</span><span> </span><span>package_name</span><span> </span><span>下载并安装一个rpm包</span></div></div><div><div><div>2</div></div><div><span>yum</span><span> </span><span>localinstall</span><span> </span><span>package_name.rpm</span><span> </span><span>将安装一个rpm包，使用你自己的软件仓库为你解决所有依赖关系</span></div></div><div><div><div>3</div></div><div><span>yum</span><span> </span><span>update</span><span> </span><span>package_name.rpm</span><span> </span><span>更新当前系统中所有安装的rpm包</span></div></div><div><div><div>4</div></div><div><span>yum</span><span> </span><span>update</span><span> </span><span>package_name</span><span> </span><span>更新一个rpm包</span></div></div><div><div><div>5</div></div><div><span>yum</span><span> </span><span>remove</span><span> </span><span>package_name</span><span> </span><span>删除一个rpm包</span></div></div><div><div><div>6</div></div><div><span>yum</span><span> </span><span>list</span><span> </span><span>列出当前系统中安装的所有包</span></div></div><div><div><div>7</div></div><div><span>yum</span><span> </span><span>search</span><span> </span><span>package_name</span><span> </span><span>在rpm仓库中搜寻软件包</span></div></div><div><div><div>8</div></div><div><span>yum</span><span> </span><span>clean</span><span> </span><span>packages</span><span> </span><span>清理rpm缓存删除下载的包</span></div></div><div><div><div>9</div></div><div><span>yum</span><span> </span><span>clean</span><span> </span><span>headers</span><span> </span><span>删除所有头文件</span></div></div><div><div><div>10</div></div><div><span>yum</span><span> </span><span>clean</span><span> </span><span>all</span><span> </span><span>删除所有缓存的包和头文件</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ol>
<li>
<section><h2>DEB 包<a href="#deb-包"><span>#</span></a></h2></section>
</li>
</ol>
<p>(Debian, Ubuntu 以及类似系统)</p>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>dpkg</span><span> </span><span>-i</span><span> </span><span>package.deb</span><span> </span><span>安装/更新一个</span><span> </span><span>deb</span><span> </span><span>包</span></div></div><div><div><div>2</div></div><div><span>dpkg</span><span> </span><span>-r</span><span> </span><span>package_name</span><span> </span><span>从系统删除一个</span><span> </span><span>deb</span><span> </span><span>包</span></div></div><div><div><div>3</div></div><div><span>dpkg</span><span> </span><span>-l</span><span> </span><span>显示系统中所有已经安装的</span><span> </span><span>deb</span><span> </span><span>包</span></div></div><div><div><div>4</div></div><div><span>dpkg</span><span> </span><span>-l</span><span> | </span><span>grep</span><span> </span><span>httpd</span><span> </span><span>显示所有名称中包含</span><span> </span><span>"httpd"</span><span> </span><span>字样的deb包</span></div></div><div><div><div>5</div></div><div><span>dpkg</span><span> </span><span>-s</span><span> </span><span>package_name</span><span> </span><span>获得已经安装在系统中一个特殊包的信息</span></div></div><div><div><div>6</div></div><div><span>dpkg</span><span> </span><span>-L</span><span> </span><span>package_name</span><span> </span><span>显示系统中已经安装的一个deb包所提供的文件列表</span></div></div><div><div><div>7</div></div><div><span>dpkg</span><span> </span><span>--contents</span><span> </span><span>package.deb</span><span> </span><span>显示尚未安装的一个包所提供的文件列表</span></div></div><div><div><div>8</div></div><div><span>dpkg</span><span> </span><span>-S</span><span> </span><span>/bin/ping</span><span> </span><span>确认所给的文件由哪个deb包提供</span></div></div><div><div><div>9</div></div><div><span>APT</span><span> </span><span>软件工具</span><span> (Debian, </span><span>Ubuntu</span><span> </span><span>以及类似系统</span><span>)</span></div></div><div><div><div>10</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>package_name</span><span> </span><span>安装/更新一个</span><span> </span><span>deb</span><span> </span><span>包</span></div></div><div><div><div>11</div></div><div><span>apt-cdrom</span><span> </span><span>install</span><span> </span><span>package_name</span><span> </span><span>从光盘安装/更新一个</span><span> </span><span>deb</span><span> </span><span>包</span></div></div><div><div><div>12</div></div><div><span>apt-get</span><span> </span><span>update</span><span> </span><span>升级列表中的软件包</span></div></div><div><div><div>13</div></div><div><span>apt-get</span><span> </span><span>upgrade</span><span> </span><span>升级所有已安装的软件</span></div></div><div><div><div>14</div></div><div><span>apt-get</span><span> </span><span>remove</span><span> </span><span>package_name</span><span> </span><span>从系统删除一个deb包</span></div></div><div><div><div>15</div></div><div><span>apt-get</span><span> </span><span>check</span><span> </span><span>确认依赖的软件仓库正确</span></div></div><div><div><div>16</div></div><div><span>apt-get</span><span> </span><span>clean</span><span> </span><span>从下载的软件包中清理缓存</span></div></div><div><div><div>17</div></div><div><span>apt-cache</span><span> </span><span>search</span><span> </span><span>searched-package</span><span> </span><span>返回包含所要搜索字符串的软件包名称</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<ol>
<li>
<section><h2>查看文件内容<a href="#查看文件内容"><span>#</span></a></h2></section>
</li>
</ol>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>cat file1 从第一个字节开始正向查看文件的内容</span></div></div><div><div><div>2</div></div><div><span>tac file1 从最后一行开始反向查看一个文件的内容</span></div></div><div><div><div>3</div></div><div><span>more file1 查看一个长文件的内容</span></div></div><div><div><div>4</div></div><div><span>less file1 类似于 'more' 命令，但是它允许在文件中和正向操作一样的反向操作</span></div></div><div><div><div>5</div></div><div><span>head -2 file1 查看一个文件的前两行</span></div></div><div><div><div>6</div></div><div><span>tail -2 file1 查看一个文件的最后两行</span></div></div><div><div><div>7</div></div><div><span>tail -f /var/log/messages 实时查看被添加到一个文件中的内容</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<hr />
<ol>
<li>
<section><h2>文本处理<a href="#文本处理"><span>#</span></a></h2></section>
</li>
</ol>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cat</span><span> </span><span>file1</span><span> </span><span>file2</span><span> </span><span>...</span><span> | </span><span>command</span><span> &lt;&gt; </span><span>file1_in.txt_or_file1_out.txt</span><span> </span><span>general</span><span> </span><span>syntax</span><span> </span><span>for</span><span> </span><span>text</span><span> </span><span>manipulation</span><span> </span><span>using</span><span> </span><span>PIPE,</span><span> </span><span>STDIN</span><span> </span><span>and</span><span> </span><span>STDOUT</span></div></div><div><div><div>2</div></div><div><span>cat</span><span> </span><span>file1</span><span> | </span><span>command</span><span>( </span><span>sed,</span><span> </span><span>grep,</span><span> </span><span>awk,</span><span> </span><span>grep,</span><span> </span><span>etc...</span><span>) &gt; result.txt 合并一个文件的详细说明文本，并将简介写入一个新文件中</span></div></div><div><div><div>3</div></div><div><span>cat</span><span> </span><span>file1</span><span> | </span><span>command</span><span>( </span><span>sed,</span><span> </span><span>grep,</span><span> </span><span>awk,</span><span> </span><span>grep,</span><span> </span><span>etc...</span><span>) &gt;&gt; result.txt 合并一个文件的详细说明文本，并将简介写入一个已有的文件中</span></div></div><div><div><div>4</div></div><div><span>grep</span><span> </span><span>Aug</span><span> </span><span>/var/log/messages</span><span> </span><span>在文件</span><span> </span><span>'/var/log/messages'中查找关键词"Aug"</span></div></div><div><div><div>5</div></div><div><span>grep</span><span> </span><span>^Aug</span><span> </span><span>/var/log/messages</span><span> </span><span>在文件</span><span> </span><span>'/var/log/messages'中查找以"Aug"开始的词汇</span></div></div><div><div><div>6</div></div><div><span>grep</span><span> [0-9] /var/log/messages 选择 </span><span>'/var/log/messages'</span><span> 文件中所有包含数字的行</span></div></div><div><div><div>7</div></div><div><span>grep</span><span> </span><span>Aug</span><span> </span><span>-R</span><span> </span><span>/var/log/</span><span>*</span><span> </span><span>在目录</span><span> </span><span>'/var/log'</span><span> </span><span>及随后的目录中搜索字符串"Aug"</span></div></div><div><div><div>8</div></div><div><span>sed</span><span> </span><span>'s/stringa1/stringa2/g'</span><span> </span><span>example.txt</span><span> </span><span>将example.txt文件中的</span><span> </span><span>"string1"</span><span> </span><span>替换成</span><span> </span><span>"string2"</span></div></div><div><div><div>9</div></div><div><span>sed</span><span> </span><span>'/^$/d'</span><span> </span><span>example.txt</span><span> </span><span>从example.txt文件中删除所有空白行</span></div></div><div><div><div>10</div></div><div><span>sed</span><span> </span><span>'/ *#/d; /^$/d'</span><span> </span><span>example.txt</span><span> </span><span>从example.txt文件中删除所有注释和空白行</span></div></div><div><div><div>11</div></div><div><span>echo</span><span> </span><span>'esempio'</span><span> | </span><span>tr</span><span> </span><span>'[:lower:]'</span><span> </span><span>'[:upper:]'</span><span> </span><span>合并上下单元格内容</span></div></div><div><div><div>12</div></div><div><span>sed</span><span> </span><span>-e</span><span> </span><span>'1d'</span><span> </span><span>result.txt</span><span> </span><span>从文件example.txt</span><span> </span><span>中排除第一行</span></div></div><div><div><div>13</div></div><div><span>sed</span><span> </span><span>-n</span><span> </span><span>'/stringa1/p'</span><span> </span><span>查看只包含词汇</span><span> </span><span>"string1"的行</span></div></div><div><div><div>14</div></div><div><span>sed</span><span> </span><span>-e</span><span> </span><span>'s/ *$//'</span><span> </span><span>example.txt</span><span> </span><span>删除每一行最后的空白字符</span></div></div><div><div><div>15</div></div><div><span>sed</span><span> </span><span>-e</span><span> </span><span>'s/stringa1//g'</span><span> </span><span>example.txt</span><span> </span><span>从文档中只删除词汇</span><span> </span><span>"string1"</span><span> </span><span>并保留剩余全部</span></div></div><div><div><div>16</div></div><div><span>sed</span><span> </span><span>-n</span><span> </span><span>'1,5p;5q'</span><span> </span><span>example.txt</span><span> </span><span>查看从第一行到第5行内容</span></div></div><div><div><div>17</div></div><div><span>sed</span><span> </span><span>-n</span><span> </span><span>'5p;5q'</span><span> </span><span>example.txt</span><span> </span><span>查看第5行</span></div></div><div><div><div>18</div></div><div><span>sed</span><span> </span><span>-e</span><span> </span><span>'s/00*/0/g'</span><span> </span><span>example.txt</span><span> </span><span>用单个零替换多个零</span></div></div><div><div><div>19</div></div><div><span>cat</span><span> </span><span>-n</span><span> </span><span>file1</span><span> </span><span>标示文件的行数</span></div></div><div><div><div>20</div></div><div><span>cat</span><span> </span><span>example.txt</span><span> | </span><span>awk</span><span> </span><span>'NR%2==1'</span><span> </span><span>删除example.txt文件中的所有偶数行</span></div></div><div><div><div>21</div></div><div><span>echo</span><span> </span><span>a</span><span> </span><span>b</span><span> </span><span>c</span><span> | </span><span>awk</span><span> </span><span>'{print $1}'</span><span> </span><span>查看一行第一栏</span></div></div><div><div><div>22</div></div><div><span>echo</span><span> </span><span>a</span><span> </span><span>b</span><span> </span><span>c</span><span> | </span><span>awk</span><span> </span><span>'{print $1,$3}'</span><span> </span><span>查看一行的第一和第三栏</span></div></div><div><div><div>23</div></div><div><span>paste</span><span> </span><span>file1</span><span> </span><span>file2</span><span> </span><span>合并两个文件或两栏的内容</span></div></div><div><div><div>24</div></div><div><span>paste</span><span> </span><span>-d</span><span> </span><span>'+'</span><span> </span><span>file1</span><span> </span><span>file2</span><span> </span><span>合并两个文件或两栏的内容，中间用"+"区分</span></div></div><div><div><div>25</div></div><div><span>sort</span><span> </span><span>file1</span><span> </span><span>file2</span><span> </span><span>排序两个文件的内容</span></div></div><div><div><div>26</div></div><div><span>sort</span><span> </span><span>file1</span><span> </span><span>file2</span><span> | </span><span>uniq</span><span> </span><span>取出两个文件的并集</span><span>(</span><span>重复的行只保留一份</span><span>)</span></div></div><div><div><div>27</div></div><div><span>sort</span><span> </span><span>file1</span><span> </span><span>file2</span><span> | </span><span>uniq</span><span> </span><span>-u</span><span> </span><span>删除交集，留下其他的行</span></div></div><div><div><div>28</div></div><div><span>sort</span><span> </span><span>file1</span><span> </span><span>file2</span><span> | </span><span>uniq</span><span> </span><span>-d</span><span> </span><span>取出两个文件的交集</span><span>(</span><span>只留下同时存在于两个文件中的文件</span><span>)</span></div></div><div><div><div>29</div></div><div><span>comm</span><span> </span><span>-1</span><span> </span><span>file1</span><span> </span><span>file2</span><span> </span><span>比较两个文件的内容只删除</span><span> </span><span>'file1'</span><span> </span><span>所包含的内容</span></div></div><div><div><div>30</div></div><div><span>comm</span><span> </span><span>-2</span><span> </span><span>file1</span><span> </span><span>file2</span><span> </span><span>比较两个文件的内容只删除</span><span> </span><span>'file2'</span><span> </span><span>所包含的内容</span></div></div><div><div><div>31</div></div><div><span>comm</span><span> </span><span>-3</span><span> </span><span>file1</span><span> </span><span>file2</span><span> </span><span>比较两个文件的内容只删除两个文件共有的部分</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<ol>
<li>
<section><h2>字符设置和文件格式转换<a href="#字符设置和文件格式转换"><span>#</span></a></h2></section>
</li>
</ol>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>dos2unix</span><span> </span><span>filedos.txt</span><span> </span><span>fileunix.txt</span><span> </span><span>将一个文本文件的格式从MSDOS转换成UNIX</span></div></div><div><div><div>2</div></div><div><span>unix2dos</span><span> </span><span>fileunix.txt</span><span> </span><span>filedos.txt</span><span> </span><span>将一个文本文件的格式从UNIX转换成MSDOS</span></div></div><div><div><div>3</div></div><div><span>recode</span><span> </span><span>..HTML</span><span> &lt; </span><span>page.txt</span><span> &gt; </span><span>page.html</span><span> </span><span>将一个文本文件转换成html</span></div></div><div><div><div>4</div></div><div><span>recode</span><span> </span><span>-l</span><span> | </span><span>more</span><span> </span><span>显示所有允许的转换格式</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<hr />
<ol>
<li>
<section><h2>文件系统分析<a href="#文件系统分析"><span>#</span></a></h2></section>
</li>
</ol>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>badblocks</span><span> </span><span>-v</span><span> </span><span>/dev/hda1</span><span> </span><span>检查磁盘hda1上的坏磁块</span></div></div><div><div><div>2</div></div><div><span>fsck</span><span> </span><span>/dev/hda1</span><span> </span><span>修复/检查hda1磁盘上linux文件系统的完整性</span></div></div><div><div><div>3</div></div><div><span>fsck.ext2</span><span> </span><span>/dev/hda1</span><span> </span><span>修复/检查hda1磁盘上ext2文件系统的完整性</span></div></div><div><div><div>4</div></div><div><span>e2fsck</span><span> </span><span>/dev/hda1</span><span> </span><span>修复/检查hda1磁盘上ext2文件系统的完整性</span></div></div><div><div><div>5</div></div><div><span>e2fsck</span><span> </span><span>-j</span><span> </span><span>/dev/hda1</span><span> </span><span>修复/检查hda1磁盘上ext3文件系统的完整性</span></div></div><div><div><div>6</div></div><div><span>fsck.ext3</span><span> </span><span>/dev/hda1</span><span> </span><span>修复/检查hda1磁盘上ext3文件系统的完整性</span></div></div><div><div><div>7</div></div><div><span>fsck.vfat</span><span> </span><span>/dev/hda1</span><span> </span><span>修复/检查hda1磁盘上fat文件系统的完整性</span></div></div><div><div><div>8</div></div><div><span>fsck.msdos</span><span> </span><span>/dev/hda1</span><span> </span><span>修复/检查hda1磁盘上dos文件系统的完整性</span></div></div><div><div><div>9</div></div><div><span>dosfsck</span><span> </span><span>/dev/hda1</span><span> </span><span>修复/检查hda1磁盘上dos文件系统的完整性</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ol>
<li>
<section><h2>初始化一个文件系统<a href="#初始化一个文件系统"><span>#</span></a></h2></section>
</li>
</ol>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>mkfs</span><span> </span><span>/dev/hda1</span><span> </span><span>在hda1分区创建一个文件系统</span></div></div><div><div><div>2</div></div><div><span>mke2fs</span><span> </span><span>/dev/hda1</span><span> </span><span>在hda1分区创建一个linux</span><span> </span><span>ext2的文件系统</span></div></div><div><div><div>3</div></div><div><span>mke2fs</span><span> </span><span>-j</span><span> </span><span>/dev/hda1</span><span> </span><span>在hda1分区创建一个linux</span><span> </span><span>ext3</span><span>(</span><span>日志型</span><span>)</span><span>的文件系统</span></div></div><div><div><div>4</div></div><div><span>mkfs</span><span> </span><span>-t</span><span> </span><span>vfat</span><span> </span><span>32</span><span> </span><span>-F</span><span> </span><span>/dev/hda1</span><span> </span><span>创建一个</span><span> </span><span>FAT32</span><span> </span><span>文件系统</span></div></div><div><div><div>5</div></div><div><span>fdformat</span><span> </span><span>-n</span><span> </span><span>/dev/fd0</span><span> </span><span>格式化一个软盘</span></div></div><div><div><div>6</div></div><div><span>mkswap</span><span> </span><span>/dev/hda3</span><span> </span><span>创建一个swap文件系统</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ol>
<li>
<section><h2>SWAP文件系统<a href="#swap文件系统"><span>#</span></a></h2></section>
</li>
</ol>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>mkswap</span><span> </span><span>/dev/hda3</span><span> </span><span>创建一个swap文件系统</span></div></div><div><div><div>2</div></div><div><span>swapon</span><span> </span><span>/dev/hda3</span><span> </span><span>启用一个新的swap文件系统</span></div></div><div><div><div>3</div></div><div><span>swapon</span><span> </span><span>/dev/hda2</span><span> </span><span>/dev/hdb3</span><span> </span><span>启用两个swap分区</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ol>
<li>
<section><h2>备份<a href="#备份"><span>#</span></a></h2></section>
</li>
</ol>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>dump</span><span> </span><span>-0aj</span><span> </span><span>-f</span><span> </span><span>/tmp/home0.bak</span><span> </span><span>/home</span><span> </span><span>制作一个</span><span> </span><span>'/home'</span><span> </span><span>目录的完整备份</span></div></div><div><div><div>2</div></div><div><span>dump</span><span> </span><span>-1aj</span><span> </span><span>-f</span><span> </span><span>/tmp/home0.bak</span><span> </span><span>/home</span><span> </span><span>制作一个</span><span> </span><span>'/home'</span><span> </span><span>目录的交互式备份</span></div></div><div><div><div>3</div></div><div><span>restore</span><span> </span><span>-if</span><span> </span><span>/tmp/home0.bak</span><span> </span><span>还原一个交互式备份</span></div></div><div><div><div>4</div></div><div><span>rsync</span><span> </span><span>-rogpav</span><span> </span><span>--delete</span><span> </span><span>/home</span><span> </span><span>/tmp</span><span> </span><span>同步两边的目录</span></div></div><div><div><div>5</div></div><div><span>rsync</span><span> </span><span>-rogpav</span><span> </span><span>-e</span><span> </span><span>ssh</span><span> </span><span>--delete</span><span> </span><span>/home</span><span> </span><span>ip_address:/tmp</span><span> </span><span>通过SSH通道rsync</span></div></div><div><div><div>6</div></div><div><span>rsync</span><span> </span><span>-az</span><span> </span><span>-e</span><span> </span><span>ssh</span><span> </span><span>--delete</span><span> </span><span>ip_addr:/home/public</span><span> </span><span>/home/local</span><span> </span><span>通过ssh和压缩将一个远程目录同步到本地目录</span></div></div><div><div><div>7</div></div><div><span>rsync</span><span> </span><span>-az</span><span> </span><span>-e</span><span> </span><span>ssh</span><span> </span><span>--delete</span><span> </span><span>/home/local</span><span> </span><span>ip_addr:/home/public</span><span> </span><span>通过ssh和压缩将本地目录同步到远程目录</span></div></div><div><div><div>8</div></div><div><span>dd</span><span> </span><span>bs=1M</span><span> </span><span>if=/dev/hda</span><span> | </span><span>gzip</span><span> | </span><span>ssh</span><span> </span><span>user@ip_addr</span><span> </span><span>'dd of=hda.gz'</span><span> </span><span>通过ssh在远程主机上执行一次备份本地磁盘的操作</span></div></div><div><div><div>9</div></div><div><span>dd</span><span> </span><span>if=/dev/sda</span><span> </span><span>of=/tmp/file1</span><span> </span><span>备份磁盘内容到一个文件</span></div></div><div><div><div>10</div></div><div><span>tar</span><span> </span><span>-Puf</span><span> </span><span>backup.tar</span><span> </span><span>/home/user</span><span> </span><span>执行一次对</span><span> </span><span>'/home/user'</span><span> </span><span>目录的交互式备份操作</span></div></div><div><div><div>11</div></div><div><span>( </span><span>cd</span><span> </span><span>/tmp/local/</span><span> &amp;&amp; </span><span>tar</span><span> </span><span>c</span><span> </span><span>.</span><span> ) | </span><span>ssh</span><span> </span><span>-C</span><span> </span><span>user@ip_addr</span><span> </span><span>'cd /home/share/ &amp;&amp; tar x -p'</span><span> </span><span>通过ssh在远程目录中复制一个目录内容</span></div></div><div><div><div>12</div></div><div><span>( </span><span>tar</span><span> </span><span>c</span><span> </span><span>/home</span><span> ) | </span><span>ssh</span><span> </span><span>-C</span><span> </span><span>user@ip_addr</span><span> </span><span>'cd /home/backup-home &amp;&amp; tar x -p'</span><span> </span><span>通过ssh在远程目录中复制一个本地目录</span></div></div><div><div><div>13</div></div><div><span>tar</span><span> </span><span>cf</span><span> </span><span>-</span><span> </span><span>.</span><span> | (</span><span>cd</span><span> </span><span>/tmp/backup</span><span> ; </span><span>tar</span><span> </span><span>xf</span><span> </span><span>-</span><span> ) </span><span>本地将一个目录复制到另一个地方，保留原有权限及链接</span></div></div><div><div><div>14</div></div><div><span>find</span><span> </span><span>/home/user1</span><span> </span><span>-name</span><span> </span><span>'*.txt'</span><span> | </span><span>xargs</span><span> </span><span>cp</span><span> </span><span>-av</span><span> </span><span>--target-directory=/home/backup/</span><span> </span><span>--parents</span><span> </span><span>从一个目录查找并复制所有以</span><span> </span><span>'.txt'</span><span> </span><span>结尾的文件到另一个目录</span></div></div><div><div><div>15</div></div><div><span>find</span><span> </span><span>/var/log</span><span> </span><span>-name</span><span> </span><span>'*.log'</span><span> | </span><span>tar</span><span> </span><span>cv</span><span> </span><span>--files-from=-</span><span> | </span><span>bzip2</span><span> &gt; </span><span>log.tar.bz2</span><span> </span><span>查找所有以</span><span> </span><span>'.log'</span><span> </span><span>结尾的文件并做成一个bzip包</span></div></div><div><div><div>16</div></div><div><span>dd</span><span> </span><span>if=/dev/hda</span><span> </span><span>of=/dev/fd0</span><span> </span><span>bs=</span><span>512</span><span> </span><span>count=</span><span>1</span><span> </span><span>做一个将</span><span> </span><span>MBR</span><span> (Master </span><span>Boot</span><span> </span><span>Record</span><span>)内容复制到软盘的动作</span></div></div><div><div><div>17</div></div><div><span>dd</span><span> </span><span>if=/dev/fd0</span><span> </span><span>of=/dev/hda</span><span> </span><span>bs=</span><span>512</span><span> </span><span>count=</span><span>1</span><span> </span><span>从已经保存到软盘的备份中恢复MBR内容</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<ol>
<li>
<section><h2>光盘<a href="#光盘"><span>#</span></a></h2></section>
</li>
</ol>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cdrecord</span><span> </span><span>-v</span><span> </span><span>gracetime=</span><span>2</span><span> </span><span>dev=/dev/cdrom</span><span> </span><span>-eject</span><span> </span><span>blank=fast</span><span> </span><span>-force</span><span> </span><span>清空一个可复写的光盘内容</span></div></div><div><div><div>2</div></div><div><span>mkisofs</span><span> </span><span>/dev/cdrom</span><span> &gt; </span><span>cd.iso</span><span> </span><span>在磁盘上创建一个光盘的iso镜像文件</span></div></div><div><div><div>3</div></div><div><span>mkisofs</span><span> </span><span>/dev/cdrom</span><span> | </span><span>gzip</span><span> &gt; </span><span>cd_iso.gz</span><span> </span><span>在磁盘上创建一个压缩了的光盘iso镜像文件</span></div></div><div><div><div>4</div></div><div><span>mkisofs</span><span> </span><span>-J</span><span> </span><span>-allow-leading-dots</span><span> </span><span>-R</span><span> </span><span>-V</span><span> </span><span>"Label CD"</span><span> </span><span>-iso-level</span><span> </span><span>4</span><span> </span><span>-o</span><span> </span><span>./cd.iso</span><span> </span><span>data_cd</span><span> </span><span>创建一个目录的iso镜像文件</span></div></div><div><div><div>5</div></div><div><span>cdrecord</span><span> </span><span>-v</span><span> </span><span>dev=/dev/cdrom</span><span> </span><span>cd.iso</span><span> </span><span>刻录一个ISO镜像文件</span></div></div><div><div><div>6</div></div><div><span>gzip</span><span> </span><span>-dc</span><span> </span><span>cd_iso.gz</span><span> | </span><span>cdrecord</span><span> </span><span>dev=/dev/cdrom</span><span> </span><span>-</span><span> </span><span>刻录一个压缩了的ISO镜像文件</span></div></div><div><div><div>7</div></div><div><span>mount</span><span> </span><span>-o</span><span> </span><span>loop</span><span> </span><span>cd.iso</span><span> </span><span>/mnt/iso</span><span> </span><span>挂载一个ISO镜像文件</span></div></div><div><div><div>8</div></div><div><span>cd-paranoia</span><span> </span><span>-B</span><span> </span><span>从一个CD光盘转录音轨到</span><span> </span><span>wav</span><span> </span><span>文件中</span></div></div><div><div><div>9</div></div><div><span>cd-paranoia</span><span> </span><span>--</span><span> </span><span>"-3"</span><span> </span><span>从一个CD光盘转录音轨到</span><span> </span><span>wav</span><span> </span><span>文件中（参数-3）</span></div></div><div><div><div>10</div></div><div><span>cdrecord</span><span> </span><span>--scanbus</span><span> </span><span>扫描总线以识别scsi通道</span></div></div><div><div><div>11</div></div><div><span>dd</span><span> </span><span>if=/dev/hdc</span><span> | </span><span>md5sum</span><span> </span><span>校验一个设备的md5sum编码，例如一张</span><span> </span><span>CD</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ol>
<li>
<section><h2>网络<a href="#网络"><span>#</span></a></h2><p>（以太网和WIFI无线）</p></section>
</li>
</ol>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ifconfig</span><span> </span><span>eth0</span><span> </span><span>显示一个以太网卡的配置</span></div></div><div><div><div>2</div></div><div><span>ifup</span><span> </span><span>eth0</span><span> </span><span>启用一个</span><span> </span><span>'eth0'</span><span> </span><span>网络设备</span></div></div><div><div><div>3</div></div><div><span>ifdown</span><span> </span><span>eth0</span><span> </span><span>禁用一个</span><span> </span><span>'eth0'</span><span> </span><span>网络设备</span></div></div><div><div><div>4</div></div><div><span>ifconfig</span><span> </span><span>eth0</span><span> </span><span>192.168.1.1</span><span> </span><span>netmask</span><span> </span><span>255.255.255.0</span><span> </span><span>控制IP地址</span></div></div><div><div><div>5</div></div><div><span>ifconfig</span><span> </span><span>eth0</span><span> </span><span>promisc</span><span> </span><span>设置</span><span> </span><span>'eth0'</span><span> </span><span>成混杂模式以嗅探数据包</span><span> (sniffing)</span></div></div><div><div><div>6</div></div><div><span>dhclient</span><span> </span><span>eth0</span><span> </span><span>以dhcp模式启用</span><span> </span><span>'eth0'</span></div></div><div><div><div>7</div></div><div><span>route</span><span> </span><span>-n</span><span> </span><span>show</span><span> </span><span>routing</span><span> </span><span>table</span></div></div><div><div><div>8</div></div><div><span>route</span><span> </span><span>add</span><span> </span><span>-net</span><span> </span><span>0/0</span><span> </span><span>gw</span><span> </span><span>IP_Gateway</span><span> </span><span>configura</span><span> </span><span>default</span><span> </span><span>gateway</span></div></div><div><div><div>9</div></div><div><span>route</span><span> </span><span>add</span><span> </span><span>-net</span><span> </span><span>192.168.0.0</span><span> </span><span>netmask</span><span> </span><span>255.255.0.0</span><span> </span><span>gw</span><span> </span><span>192.168.1.1</span><span> </span><span>configure</span><span> </span><span>static</span><span> </span><span>route</span><span> </span><span>to</span><span> </span><span>reach</span><span> </span><span>network</span><span> </span><span>'192.168.0.0/16'</span></div></div><div><div><div>10</div></div><div><span>route</span><span> </span><span>del</span><span> </span><span>0/0</span><span> </span><span>gw</span><span> </span><span>IP_gateway</span><span> </span><span>remove</span><span> </span><span>static</span><span> </span><span>route</span></div></div><div><div><div>11</div></div><div><span>echo</span><span> </span><span>"1"</span><span> &gt; </span><span>/proc/sys/net/ipv4/ip_forward</span><span> </span><span>activate</span><span> </span><span>ip</span><span> </span><span>routing</span></div></div><div><div><div>12</div></div><div><span>hostname</span><span> </span><span>show</span><span> </span><span>hostname</span><span> </span><span>of</span><span> </span><span>system</span></div></div><div><div><div>13</div></div><div><span>host</span><span> </span><span>www.example.com</span><span> </span><span>lookup</span><span> </span><span>hostname</span><span> </span><span>to</span><span> </span><span>resolve</span><span> </span><span>name</span><span> </span><span>to</span><span> </span><span>ip</span><span> </span><span>address</span><span> </span><span>and</span><span> </span><span>viceversa</span><span>(</span><span>1</span><span>)</span></div></div><div><div><div>14</div></div><div><span>nslookup</span><span> </span><span>www.example.com</span><span> </span><span>lookup</span><span> </span><span>hostname</span><span> </span><span>to</span><span> </span><span>resolve</span><span> </span><span>name</span><span> </span><span>to</span><span> </span><span>ip</span><span> </span><span>address</span><span> </span><span>and</span><span> </span><span>viceversa</span><span>(</span><span>2</span><span>)</span></div></div><div><div><div>15</div></div><div><span>ip</span><span> </span><span>link</span><span> </span><span>show</span><span> </span><span>show</span><span> </span><span>link</span><span> </span><span>status</span><span> </span><span>of</span><span> </span><span>all</span><span> </span><span>interfaces</span></div></div><div><div><div>16</div></div><div><span>mii-tool</span><span> </span><span>eth0</span><span> </span><span>show</span><span> </span><span>link</span><span> </span><span>status</span><span> </span><span>of</span><span> </span><span>'eth0'</span></div></div><div><div><div>17</div></div><div><span>ethtool</span><span> </span><span>eth0</span><span> </span><span>show</span><span> </span><span>statistics</span><span> </span><span>of</span><span> </span><span>network</span><span> </span><span>card</span><span> </span><span>'eth0'</span></div></div><div><div><div>18</div></div><div><span>netstat</span><span> </span><span>-tup</span><span> </span><span>show</span><span> </span><span>all</span><span> </span><span>active</span><span> </span><span>network</span><span> </span><span>connections</span><span> </span><span>and</span><span> </span><span>their</span><span> </span><span>PID</span></div></div><div><div><div>19</div></div><div><span>netstat</span><span> </span><span>-tupl</span><span> </span><span>show</span><span> </span><span>all</span><span> </span><span>network</span><span> </span><span>services</span><span> </span><span>listening</span><span> </span><span>on</span><span> </span><span>the</span><span> </span><span>system</span><span> </span><span>and</span><span> </span><span>their</span><span> </span><span>PID</span></div></div><div><div><div>20</div></div><div><span>tcpdump</span><span> </span><span>tcp</span><span> </span><span>port</span><span> </span><span>80</span><span> </span><span>show</span><span> </span><span>all</span><span> </span><span>HTTP</span><span> </span><span>traffic</span></div></div><div><div><div>21</div></div><div><span>iwlist</span><span> </span><span>scan</span><span> </span><span>show</span><span> </span><span>wireless</span><span> </span><span>networks</span></div></div><div><div><div>22</div></div><div><span>iwconfig</span><span> </span><span>eth1</span><span> </span><span>show</span><span> </span><span>configuration</span><span> </span><span>of</span><span> </span><span>a</span><span> </span><span>wireless</span><span> </span><span>network</span><span> </span><span>card</span></div></div><div><div><div>23</div></div><div><span>hostname</span><span> </span><span>show</span><span> </span><span>hostname</span></div></div><div><div><div>24</div></div><div><span>host</span><span> </span><span>www.example.com</span><span> </span><span>lookup</span><span> </span><span>hostname</span><span> </span><span>to</span><span> </span><span>resolve</span><span> </span><span>name</span><span> </span><span>to</span><span> </span><span>ip</span><span> </span><span>address</span><span> </span><span>and</span><span> </span><span>viceversa</span></div></div><div><div><div>25</div></div><div><span>nslookup</span><span> </span><span>www.example.com</span><span> </span><span>lookup</span><span> </span><span>hostname</span><span> </span><span>to</span><span> </span><span>resolve</span><span> </span><span>name</span><span> </span><span>to</span><span> </span><span>ip</span><span> </span><span>address</span><span> </span><span>and</span><span> </span><span>viceversa</span></div></div><div><div><div>26</div></div><div><span>whois</span><span> </span><span>www.example.com</span><span> </span><span>lookup</span><span> </span><span>on</span><span> </span><span>Whois</span><span> </span><span>database</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<ol>
<li>
<section><h2>列出目录内容<a href="#列出目录内容"><span>#</span></a></h2></section>
</li>
</ol>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ls</span><span> </span><span>-a：显示所有文件（包括隐藏文件）；</span></div></div><div><div><div>2</div></div><div><span>ls</span><span> </span><span>-l：显示详细信息；</span></div></div><div><div><div>3</div></div><div><span>ls</span><span> </span><span>-R：递归显示子目录结构；</span></div></div><div><div><div>4</div></div><div><span>ls</span><span> </span><span>-ld：显示目录和链接信息；</span></div></div><div><div><div>5</div></div><div><span>ctrl+r：历史记录中所搜命令（输入命令中的任意一个字符）；</span></div></div><div><div><div>6</div></div><div><span>Linux中以.开头的文件是隐藏文件；</span></div></div><div><div><div>7</div></div><div><span>pwd</span><span>:显示当前目录</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ol>
<li>
<section><h2>查看文件的类型<a href="#查看文件的类型"><span>#</span></a></h2></section>
</li>
</ol>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>file:查看文件的类型</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ol>
<li>
<section><h2>复制文件目录等操作<a href="#复制文件目录等操作"><span>#</span></a></h2></section>
</li>
</ol>
<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>1、cp：复制文件和目录 cp源文件（文件夹）目标文件（文件夹）</span></div></div><div><div><div>2</div></div><div><span>常用参数：-r:递归复制整个目录树；-v：显示详细信息；复制文件夹时要在cp命令后面加一个-r参数：如：cp -r 源文件夹 目标文件夹</span></div></div><div><div><div>3</div></div><div><span>2、touch+文件名：当文件不存在的时候，创建相应的文件；当文件存在的时候，修改文件的创建时间。欢迎关注我们，公号终码一生。功能：生成一个空文件或修改文件的存取/修改的时间记录值。touch * ：将当前下的文件时间修改为系统的当前时间</span></div></div><div><div><div>4</div></div><div><span>touch –d 20040210 test：将test文件的日期改为20040210</span></div></div><div><div><div>5</div></div><div><span>touch abc ：若abc文件存在，则修改为系统的当前时间；若不存在，则生成一个为当前时间的空文件</span></div></div><div><div><div>6</div></div><div><span>3、mv 文件 目标目录：移动或重命名文件或目录（如果指定文件名，则可以重命名文件）。可以将文件及目录移到另一目录下，或更改文件及目录的名称。格式为：mv [参数]&lt;源文件或目录&gt; &lt;目标文件或目录&gt;</span></div></div><div><div><div>7</div></div><div><span>mva.txt ../：将a.txt文件移动上层目录</span></div></div><div><div><div>8</div></div><div><span>mv a.txt b.txt：将a.txt改名为b.txt</span></div></div><div><div><div>9</div></div><div><span>mvdir2 ../：将dir2目录上移一层</span></div></div><div><div><div>10</div></div><div><span>4、rm：删除文件；常用参数：-i：交互式 -r：递归的删除包括目录中的所有内容</span></div></div><div><div><div>11</div></div><div><span>5、mkdir +文件夹名称：创建文件夹；6、rm -r +文件夹名称：删除文件夹（空文件夹和非空文件夹都可删除）</span></div></div><div><div><div>12</div></div><div><span>rmdir 文件夹名称：删除文件夹（只能删除空文件夹）</span></div></div><div><div><div>13</div></div><div><span>7、mkdir -p dir1/dir2 ：在当前目录下创建dir1目录，并在dir1目录下创建dir2目录， 也就是连续创建两个目录（dir1/和dir1/dir2）</span></div></div><div><div><div>14</div></div><div><span>8、rmdir –p dir1/dir2：删除dir1下的dir2目录，若dir1目录为空也删除它</span></div></div><div><div><div>15</div></div><div><span>9、rm * ：删除当前目录下的所有文件</span></div></div><div><div><div>16</div></div><div><span>10、-f参数：强迫删除文件 rm –f *.txt：强迫删除所有以后缀名为txt文件</span></div></div><div><div><div>17</div></div><div><span>11、-i参数：删除文件时询问</span></div></div><div><div><div>18</div></div><div><span>rm –i * ：删除当前目录下的所有文件会有如下提示：rm:backup:is a directory 遇到目录会略过</span></div></div><div><div><div>19</div></div><div><span>rm: remove ‘myfiles.txt’ ? Y</span></div></div><div><div><div>20</div></div><div><span>删除文件时会询问,可按Y或N键表示允许或拒绝删除文件</span></div></div><div><div><div>21</div></div><div><span>12、-r参数：递归删除（连子目录一同删除，这是一个相当常用的参数）</span></div></div><div><div><div>22</div></div><div><span>rm -r test ：删除test目录（含test目录下所有文件和子目录）</span></div></div><div><div><div>23</div></div><div><span>rm -r *：删除所有文件（含当前目录所有文件、所有子目录和子目录下的文件） 一般在删除目录时r和f一起用，避免麻烦</span></div></div><div><div><div>24</div></div><div><span>rm -rf test ：强行删除、不加询问</span></div></div><div><div><div>25</div></div><div><span>13、grep：功能：在文件中搜索匹配的字符并进行输出</span></div></div><div><div><div>26</div></div><div><span>格式：grep[参数] &lt;要找的字串&gt; &lt;要寻找字 串的源文件&gt;</span></div></div><div><div><div>27</div></div><div><span>greplinux test.txt：搜索test.txt文件中字符串linux并输出</span></div></div><div><div><div>28</div></div><div><span>14、ln命令</span></div></div><div><div><div>29</div></div><div><span>功能：在文件和目录之间建立链接</span></div></div><div><div><div>30</div></div><div><span>格式：ln [参数] &lt;源文件或目录&gt; &lt;目标文件或目录&gt;</span></div></div><div><div><div>31</div></div><div><span>链接分“软链接”和“硬链接”</span></div></div><div><div><div>32</div></div><div><span>1.软链接:</span></div></div><div><div><div>33</div></div><div><span>ln–s /usr/share/do doc ：创建一个链接文件doc,并指向目录/usr/share/do</span></div></div><div><div><div>34</div></div><div><span>2.硬链接:</span></div></div><div><div><div>35</div></div><div><span>ln /usr/share/test hard：创建一个硬链接文件hard，这时对于test文件对应 的存储区域来说，又多了一个文件指向它</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<ol>
<li>
<section><h2>系统常用命令<a href="#系统常用命令"><span>#</span></a></h2></section>
</li>
</ol>
<ul>
<li>
<section><h3>显示命令<a href="#显示命令"><span>#</span></a></h3></section>
</li>
</ul>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>date:查看或设置当前系统的时间：格式化显示时间：+%Y--%m--%d；date</span><span> </span><span>-s:设置当前系统的时间</span></div></div><div><div><div>2</div></div><div><span>hwclock(clock</span><span>)：显示硬件时钟时间(</span><span>需要管理员权限</span><span>)；cal：查看日历</span></div></div><div><div><div>3</div></div><div><span>格式cal</span><span> [参数] 月年</span></div></div><div><div><div>4</div></div><div><span>cal：显示当月的日历</span><span> </span><span>cal4</span><span> </span><span>2004</span><span> </span><span>：显示2004年4月的日历</span></div></div><div><div><div>5</div></div><div><span>cal-</span><span> </span><span>y</span><span> </span><span>2003：显示2003年的日历</span></div></div><div><div><div>6</div></div><div><span>uptime：查看系统运行时间</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ul>
<li>
<section><h3>输出查看命令<a href="#输出查看命令"><span>#</span></a></h3></section>
</li>
</ul>
<div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>echo</span><span>：显示输入的内容</span><span> </span><span>追加文件echo</span><span> </span><span>"liuyazhuang"</span><span> &gt;&gt; </span><span>liuyazhuang.txt</span></div></div><div><div><div>2</div></div><div><span>cat：显示文件内容,也可以将数个文件合并成一个文件。格式：格式：cat[参数]&lt;文件名&gt;</span></div></div><div><div><div>3</div></div><div><span>cat</span><span> </span><span>test.txt：显示test.txt文件内容</span></div></div><div><div><div>4</div></div><div><span>cat</span><span> </span><span>test.txt</span><span> | </span><span>more</span><span> </span><span>：逐页显示test.txt文件中的内容</span></div></div><div><div><div>5</div></div><div><span>cat</span><span> </span><span>test.txt</span><span> &gt;&gt; </span><span>test1.txt</span><span> </span><span>：将test.txt的内容附加到test1.txt文件之后</span></div></div><div><div><div>6</div></div><div><span>cat</span><span> </span><span>test.txt</span><span> </span><span>test2.txt</span><span> &gt;</span><span>readme.txt</span><span> </span><span>:</span><span> </span><span>将test.txt和test2.txt文件合并成readme.txt</span><span> </span><span>文件</span></div></div><div><div><div>7</div></div><div><span>head:显示文件的头几行（默认10行）</span><span> </span><span>-n:指定显示的行数格式：head</span><span> </span><span>-n</span><span> </span><span>文件名</span></div></div><div><div><div>8</div></div><div><span>tail：显示文件的末尾几行（默认10行）-n：指定显示的行数</span><span> </span><span>-f：追踪显示文件更新</span><span> </span><span>（一般用于查看日志，命令不会退出，而是持续显示新加入的内容）</span></div></div><div><div><div>9</div></div><div><span>格式：格式：tail[参数]&lt;文件名&gt;</span></div></div><div><div><div>10</div></div><div><span>tail-10</span><span> </span><span>/etc/passwd</span><span> </span><span>：显示/etc/passwd/文件的倒数10行内容</span></div></div><div><div><div>11</div></div><div><span>tail+10</span><span> </span><span>/etc/passwd</span><span> </span><span>：显示/etc/passwd/文件从第10行开始到末尾的内容</span></div></div><div><div><div>12</div></div><div><span>more：用于翻页显示文件内容（只能向下翻页）</span></div></div><div><div><div>13</div></div><div><span>more命令是一般用于要显示的内容会超过一个画面长度的情况。为了避免画</span><span> </span><span>面显示时瞬间就闪过去，用户可以使用more命令，让画面在显示满一页时暂停，此时可按空格健继续显示下一个画面，或按Q键停止显示。ls</span><span> </span><span>-al</span><span> |</span><span>more：以长格形式显示etc目录下的文件列表，显示满一个画面便暂停，可</span><span> </span><span>按空格键继续显示下一画面，或按Q键跳离</span></div></div><div><div><div>14</div></div><div><span>less：翻页显示文件内容（带上下翻页）按下上键分页，按q退出、‘</span></div></div><div><div><div>15</div></div><div><span>less命令的用法与more命令类似，也可以用来浏览超过一页的文件。所不同</span><span> </span><span>的是less</span><span> </span><span>命令除了可以按空格键向下显示文件外，还可以利用上下键来卷动文件。当要结束浏览时，只要在less命令的提示符“：”下按Q键即可。ls</span><span> </span><span>-al</span><span> | </span><span>less：以长格形式列出/etc目录中所有的内容。用户可按上下键浏览或按Q键跳离</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<ul>
<li>
<section><h3>查看硬件信息<a href="#查看硬件信息"><span>#</span></a></h3></section>
</li>
</ul>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Ispci：查看PCI设备 -v：查看详细信息</span></div></div><div><div><div>2</div></div><div><span>Isusb：查看USB设备 -v：查看详细信息</span></div></div><div><div><div>3</div></div><div><span>Ismod：查看加载的模块(驱动)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ul>
<li>
<section><h3>归档、压缩<a href="#归档压缩"><span>#</span></a></h3></section>
</li>
</ul>
<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>zip:压缩文件 zip liuyazhuang.zip myfile 格式为：“zip 压缩后的zip文件文件名”</span></div></div><div><div><div>2</div></div><div><span>unzip：解压文件 unzip liuyazhuang.zip</span></div></div><div><div><div>3</div></div><div><span>gzip：压缩文件 gzip 文件名</span></div></div><div><div><div>4</div></div><div><span>tar：归档文件</span></div></div><div><div><div>5</div></div><div><span>tar -cvf out.tar liuyazhuang 打包一个归档（将文件"liuyazhuang"打包成一个归档）</span></div></div><div><div><div>6</div></div><div><span>tar -xvf liuyazhuang.tar 释放一个归档（释放liuyazhuang.tar归档）</span></div></div><div><div><div>7</div></div><div><span>tar -cvzf backup.tar.gz/etc</span></div></div><div><div><div>8</div></div><div><span>-z参数将归档后的归档文件进行gzip压缩以减少大小。-c：创建一个新tar文件</span></div></div><div><div><div>9</div></div><div><span>-v：显示运行过程的信息</span></div></div><div><div><div>10</div></div><div><span>-f：指定文件名</span></div></div><div><div><div>11</div></div><div><span>-z：调用gzip压缩命令进行压缩</span></div></div><div><div><div>12</div></div><div><span>-t：查看压缩文件的内容</span></div></div><div><div><div>13</div></div><div><span>-x：解开tar文件</span></div></div><div><div><div>14</div></div><div><span>tar -cvf test.tar *：将所有文件打包成test.tar,扩展名.tar需自行加上</span></div></div><div><div><div>15</div></div><div><span>tar -zcvf test.tar.gz *：将所有文件打包成test.tar,再用gzip命令压缩</span></div></div><div><div><div>16</div></div><div><span>tar -tf test.tar ：查看test.tar文件中包括了哪些文件</span></div></div><div><div><div>17</div></div><div><span>tar -xvf test.tar 将test.tar解开</span></div></div><div><div><div>18</div></div><div><span>tar -zxvf foo.tar.gz 解压缩</span></div></div><div><div><div>19</div></div><div><span>gzip各gunzip命令</span></div></div><div><div><div>20</div></div><div><span>gziptest.txt ：压缩文件时，不需要任何参数</span></div></div><div><div><div>21</div></div><div><span>gizp–l test.txt.gz：显示压缩率</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<ul>
<li>
<section><h3>查找<a href="#查找"><span>#</span></a></h3></section>
</li>
</ul>
<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>locate：快速查找文件、文件夹：locate keyword</span></div></div><div><div><div>2</div></div><div><span>此命令需要预先建立数据库，数据库默认每天更新一次，可用updatedb命令手工建立、更新数据库。欢迎关注我们，公号终码一生。find查找位置查找参数</span></div></div><div><div><div>3</div></div><div><span>如：find . -name *liuyazhuang* 查找当前目录下名称中含有"liuyazhuang"的文件</span></div></div><div><div><div>4</div></div><div><span>find / -name *.conf 查找根目录下（整个硬盘）下后缀为.conf的文件</span></div></div><div><div><div>5</div></div><div><span>find / -perm 777 查找所有权限是777的文件</span></div></div><div><div><div>6</div></div><div><span>find / -type d 返回根目录下所有的目录</span></div></div><div><div><div>7</div></div><div><span>find . -name "a*"-exec ls -l {} \;</span></div></div><div><div><div>8</div></div><div><span>find功能：用来寻找文件或目录。格式：find [&lt;路径&gt;] [匹配条件]</span></div></div><div><div><div>9</div></div><div><span>find / -name httpd.conf 搜索系统根目录下名为httpd.conf的文件</span></div></div><div><div><div>10</div></div><div><span>7、ctrl+c :终止当前的命令</span></div></div><div><div><div>11</div></div><div><span>8、who或w命令</span></div></div><div><div><div>12</div></div><div><span>功能：查看当前系统中有哪些用户登录</span></div></div><div><div><div>13</div></div><div><span>格式：who/w[参数]</span></div></div><div><div><div>14</div></div><div><span>9、dmesg命令 功能：显示系统诊断信息、操作系统版本号、物理内存的大小以及其它信息</span></div></div><div><div><div>15</div></div><div><span>10、df命令 功能：用于查看文件系统的各个分区的占用情况</span></div></div><div><div><div>16</div></div><div><span>11、du命令</span></div></div><div><div><div>17</div></div><div><span>功能：查看某个目录中各级子目录所使用的硬盘空间数</span></div></div><div><div><div>18</div></div><div><span>格式：du [参数] &lt;目录名&gt;</span></div></div><div><div><div>19</div></div><div><span>12、free命令</span></div></div><div><div><div>20</div></div><div><span>功能：用于查看系统内存，虚拟内存（交换空间）的大小占用情况</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<ol>
<li>
<section><h2>VIM<a href="#vim"><span>#</span></a></h2></section>
</li>
</ol>
<p>VIM 是一款功能强大的命令行文本编辑器，在 Linux 中通过 vim 命令可以启动 vim编辑器。</p>
<p>一般使用 vim + 目标文件路径的形式使用vim。</p>
<p>如果目标文件存在，则 vim 打开目标文件，如果目标文件不存在，则 vim 新建并打开该文件。</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>:q：退出vim编辑器</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ul>
<li>
<p>vim拥有三种模式</p>
<ul>
<li>
<section><h3>命令模式（常规模式）<a href="#命令模式常规模式"><span>#</span></a></h3><blockquote><p>vim启动后，默认进入命令模式，任何模式都可以通过esc键回到命令模式（可以多按几次），命令模式下可以键入不同的命令完成选择、复制、粘贴、撤销等操作。</p></blockquote><blockquote><p>命名模式常用命令如下：</p></blockquote><ul>
<li>i：在光标前插入文本；</li>
</ul><ul>
<li>
<p>o：在当前行的下面插入新行；</p>
</li>
<li>
<p>dd：删除整行；</p>
</li>
<li>
<p>yy：将当前行的内容放入缓冲区（复制当前行）</p>
</li>
<li>
<p>n+yy：将n行的内容放入缓冲区（复制n行）</p>
</li>
<li>
<p>p：将缓冲区中的文本放入光标后（粘贴）</p>
</li>
<li>
<p>u：撤销上一个操作</p>
</li>
<li>
<p>r：替换当前字符</p>
</li>
<li>
<p>/：查找关键字</p>
</li>
</ul></section>
</li>
<li>
<section><h3>插入模式<a href="#插入模式"><span>#</span></a></h3><blockquote><p>在命令模式下按 “ i “键，即可进入插入模式，在插入模式可以输入编辑文本内容，使用esc键可以返回命令模式。</p></blockquote></section>
</li>
<li>
<section><h3>ex模式<a href="#ex模式"><span>#</span></a></h3><blockquote><p>在命令模式中按” : “键可以进入ex模式，光标会移动到底部，在这里可以保存修改或退出vim。</p></blockquote><p>ex模式常用命令如下：</p><ul>
<li>
<p> 保存当前的修改</p>
</li>
<li>
<p><q></q> 退出</p>
</li>
<li>
<p><q></q>! 强制退出，保存修改</p>
</li>
<li>
<p> 保存并退出，相当于</p>
</li>
<li>
<p> number 显示行号</p>
</li>
<li>
<p>:! 系统命令 执行一个系统命令并显示结果</p>
</li>
<li>
<p> 切换到命令行，使用ctrl+d切换回vim</p>
</li>
</ul></section>
</li>
</ul>
</li>
</ul>
<ol>
<li>
<section><h2>软件包管理命令(RPM)<a href="#软件包管理命令rpm"><span>#</span></a></h2></section>
</li>
</ol>
<ul>
<li>
<section><h3>软件包的安装<a href="#软件包的安装"><span>#</span></a></h3></section>
</li>
</ul>
<p>​	使用RPM命令的安装模式可以将软件包内所有的组件放到系统中的正确路径，安装软件包的命令是：<code>rpm –ivh wu-ftpd-2.6.2-8.i386.rpm</code></p>
<p>​	i：作用rpm的安装模式，v: 校验文件信息，h: 以＃号显示安装进度。</p>
<ul>
<li>
<section><h3>软件包的删除<a href="#软件包的删除"><span>#</span></a></h3></section>
</li>
</ul>
<p>​	删除模式会将指定软件包的内容全部删除，但并不包括已更改过的配置文件，删除RPM软件包的命令如下：<code>rpm -e wu-ftpd</code></p>
<p><strong>注意：这里必须使用软件名“<code>wu-ftpd</code>”或”<code>wu-ftpd-2.6.2-8</code>而不是使用当初安装时的软件包名<code>.wu-ftpd-2.6.2-8.i386.rpm</code></strong></p>
<ul>
<li>
<section><h3>软件包升级<a href="#软件包升级"><span>#</span></a></h3></section>
</li>
</ul>
<p>​	升级模式会安装用户所指定的更新版本，并删除已安装在系统中的相同软件包，升级软件包命令如下：<code>rpm -Uvh wu-ftpd-2.6.2-8.i386.rpm -Uvh：升级参数</code></p>
<ul>
<li>
<section><h3>软件包更新<a href="#软件包更新"><span>#</span></a></h3></section>
</li>
</ul>
<p>​	更新模式下，rpm命令会检查在命令行中所指定的软件包是否比系统中原有的软件 包更新。如果情况属实，rpm命令会自动更新指定的软件包；反之，若系统中并没有指定软件包的较旧版本，rpm命令并不会安装此软件包。而在升级模式下，不管系统中是否有较旧的版本，rpm命令都会安装指定的软件包。</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>rpm</span><span> </span><span>–Fvhwu-ftpd-2.6.2-8.i386.rpm</span><span> </span><span>-Fvh：更新参数</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ul>
<li>
<section><h3>软件包查询<a href="#软件包查询"><span>#</span></a></h3></section>
</li>
</ul>
<p>​	若要获取RPM软件包的相关信息，可以使用查询模式。使用-q参数可查询一个已 安装的软件包的内容</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>rpm –q wu-ftpd</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>查询软件包所安装的位置：<code>rpm –ql package-name</code></p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>rpm –ql xv (l参数：显示文件列表)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ol>
<li>
<section><h2>示例操作<a href="#示例操作"><span>#</span></a></h2><ol>
<li>
<section><h3>tar 压缩/解压<a href="#tar-压缩解压"><span>#</span></a></h3><ul>
<li>-c: 建立压缩档案</li>
<li>-x：解压</li>
<li>-t：查看内容</li>
<li>-r：向压缩归档文件末尾追加文件</li>
<li>-u：更新原压缩包中的文件</li>
</ul><blockquote><p>这五个是独立的命令，压缩解压都要用到其中一个，可以和别的命令连用但只能用其中一个。下面的参数是根据需要在压缩或解压档案时可选的。</p></blockquote><ul>
<li>-z：有gzip属性的</li>
<li>-j：有bz2属性的</li>
<li>-Z：有compress属性的</li>
<li>-v：显示所有过程</li>
<li>-O：将文件解开到标准输出</li>
</ul><blockquote><p>下面的参数-f是必须的</p></blockquote><ul>
<li>-f: 使用档案名字，切记，这个参数是最后一个参数，后面只能接档案名。</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># tar -cf all.tar *.jpg</span></div></div><div><div><div>2</div></div><div><span>这条命令是将所有.jpg的文件打成一个名为all.tar的包。-c是表示产生新的包，-f指定包的文件名。</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># tar -rf all.tar *.gif</span></div></div><div><div><div>5</div></div><div><span>这条命令是将所有.gif的文件增加到all.tar的包里面去。-r是表示增加文件的意思。</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># tar -uf all.tar logo.gif</span></div></div><div><div><div>8</div></div><div><span>这条命令是更新原来tar包all.tar中logo.gif文件，-u是表示更新文件的意思。</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># tar -tf all.tar</span></div></div><div><div><div>11</div></div><div><span>这条命令是列出all.tar包中所有文件，-t是列出文件的意思</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># tar -xf all.tar</span></div></div><div><div><div>14</div></div><div><span>这条命令是解出all.tar包中所有文件，-t是解开的意思</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>压缩</span></div></div><div><div><div>2</div></div><div><span>tar</span><span> </span><span>-cvf</span><span> </span><span>jpg.tar</span><span> </span><span>*</span><span>.jpg</span><span> </span><span>//将目录里所有jpg文件打包成tar.jpg</span></div></div><div><div><div>3</div></div><div><span>tar</span><span> </span><span>-czf</span><span> </span><span>jpg.tar.gz</span><span> </span><span>*</span><span>.jpg</span><span>   </span><span>//将目录里所有jpg文件打包成jpg.tar后，并且将其用gzip压缩，生成一个gzip压缩过的包，命名为jpg.tar.gz</span></div></div><div><div><div>4</div></div><div><span> </span><span>tar</span><span> </span><span>-cjf</span><span> </span><span>jpg.tar.bz2</span><span> </span><span>*</span><span>.jpg</span><span> </span><span>//将目录里所有jpg文件打包成jpg.tar后，并且将其用bzip2压缩，生成一个bzip2压缩过的包，命名为jpg.tar.bz2</span></div></div><div><div><div>5</div></div><div><span>tar</span><span> </span><span>-cZf</span><span> </span><span>jpg.tar.Z</span><span> </span><span>*</span><span>.jpg</span><span>   </span><span>//将目录里所有jpg文件打包成jpg.tar后，并且将其用compress压缩，生成一个umcompress压缩过的包，命名为jpg.tar.Z</span></div></div><div><div><div>6</div></div><div><span>rar</span><span> </span><span>a</span><span> </span><span>jpg.rar</span><span> </span><span>*</span><span>.jpg</span><span> </span><span>//rar格式的压缩，需要先下载rar</span><span> </span><span>for</span><span> </span><span>linux</span></div></div><div><div><div>7</div></div><div><span>zip</span><span> </span><span>jpg.zip</span><span> </span><span>*</span><span>.jpg</span><span> </span><span>//zip格式的压缩，需要先下载zip</span><span> </span><span>for</span><span> </span><span>linux</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>解压</span></div></div><div><div><div>10</div></div><div><span>tar</span><span> </span><span>-xvf</span><span> </span><span>file.tar</span><span> </span><span>//解压</span><span> </span><span>tar包</span></div></div><div><div><div>11</div></div><div><span>tar</span><span> </span><span>-xzvf</span><span> </span><span>file.tar.gz</span><span> </span><span>//解压tar.gz</span></div></div><div><div><div>12</div></div><div><span>tar</span><span> </span><span>-xjvf</span><span> </span><span>file.tar.bz2</span><span>   </span><span>//解压</span><span> </span><span>tar.bz2</span></div></div><div><div><div>13</div></div><div><span>tar</span><span> </span><span>-xZvf</span><span> </span><span>file.tar.Z</span><span>   </span><span>//解压tar.Z</span></div></div><div><div><div>14</div></div><div><span>unrar</span><span> </span><span>e</span><span> </span><span>file.rar</span><span> </span><span>//解压rar</span></div></div><div><div><div>15</div></div><div><span>1、把文件解压到当前目录下</span></div></div><div><div><div>16</div></div><div><span>unzip</span><span> </span><span>file.zip</span><span> </span><span>//解压zip</span></div></div><div><div><div>17</div></div><div><span>2、如果要把文件解压到指定的目录下，需要用到-d参数。</span></div></div><div><div><div>18</div></div><div><span>unzip</span><span> </span><span>-d</span><span> </span><span>/temp</span><span> </span><span>test.zip</span></div></div><div><div><div>19</div></div><div><span>3、解压的时候，有时候不想覆盖已经存在的文件，那么可以加上-n参数</span></div></div><div><div><div>20</div></div><div><span>unzip</span><span> </span><span>-n</span><span> </span><span>test.zip</span></div></div><div><div><div>21</div></div><div><span>unzip</span><span> </span><span>-n</span><span> </span><span>-d</span><span> </span><span>/temp</span><span> </span><span>test.zip</span></div></div><div><div><div>22</div></div><div><span>4、只看一下zip压缩包中包含哪些文件，不进行解压缩</span></div></div><div><div><div>23</div></div><div><span>unzip</span><span> </span><span>-l</span><span> </span><span>test.zip</span></div></div><div><div><div>24</div></div><div><span>5、查看显示的文件列表还包含压缩比率</span></div></div><div><div><div>25</div></div><div><span>unzip</span><span> </span><span>-v</span><span> </span><span>test.zip</span></div></div><div><div><div>26</div></div><div><span>6、检查zip文件是否损坏</span></div></div><div><div><div>27</div></div><div><span>unzip</span><span> </span><span>-t</span><span> </span><span>test.zip</span></div></div><div><div><div>28</div></div><div><span>7、将压缩文件test.zip在指定目录tmp下解压缩，如果已有相同的文件存在，要求unzip命令覆盖原先的文件</span></div></div><div><div><div>29</div></div><div><span>unzip</span><span> </span><span>-o</span><span> </span><span>test.zip</span><span> </span><span>-d</span><span> </span><span>/tmp/</span></div></div><div><div><div>30</div></div><div>
</div></div><div><div><div>31</div></div><div><span>总结</span></div></div><div><div><div>32</div></div><div><span>1、*.tar</span><span> </span><span>用</span><span> </span><span>tar</span><span> </span><span>-xvf</span><span> </span><span>解压</span></div></div><div><div><div>33</div></div><div><span>2、*.gz</span><span> </span><span>用</span><span> </span><span>gzip</span><span> </span><span>-d或者gunzip</span><span> </span><span>解压</span></div></div><div><div><div>34</div></div><div><span>3、*.tar.gz和*.tgz</span><span> </span><span>用</span><span> </span><span>tar</span><span> </span><span>-xzf</span><span> </span><span>解压</span></div></div><div><div><div>35</div></div><div><span>4、*.bz2</span><span> </span><span>用</span><span> </span><span>bzip2</span><span> </span><span>-d或者用bunzip2</span><span> </span><span>解压</span></div></div><div><div><div>36</div></div><div><span>5、*.tar.bz2用tar</span><span> </span><span>-xjf</span><span> </span><span>解压</span></div></div><div><div><div>37</div></div><div><span>6、*.Z</span><span> </span><span>用</span><span> </span><span>uncompress</span><span> </span><span>解压</span></div></div><div><div><div>38</div></div><div><span>7、*.tar.Z</span><span> </span><span>用tar</span><span> </span><span>-xZf</span><span> </span><span>解压</span></div></div><div><div><div>39</div></div><div><span>8、*.rar</span><span> </span><span>用</span><span> </span><span>unrar</span><span> </span><span>e解压</span></div></div><div><div><div>40</div></div><div><span>9、*.zip</span><span> </span><span>用</span><span> </span><span>unzip</span><span> </span><span>解压</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>
</li>
<li>
<section><h3>MV 移动文件/更名<a href="#mv-移动文件更名"><span>#</span></a></h3><p><code>mv [options] source dest</code></p><p><code>mv [options] source... directory</code></p><p><strong>参数说明</strong>：</p><ul>
<li>-i: 若指定目录已有同名文件，则先询问是否覆盖旧文件;</li>
<li>-f: 在mv操作要覆盖某已有的目标文件时不给任何指示;</li>
</ul>

<table><thead><tr><th>命令格式</th><th>运行结果</th></tr></thead><tbody><tr><td>mv 文件名 文件名</td><td>将源文件名改为目标文件名</td></tr><tr><td>mv 文件名 目录名</td><td>将文件移动到目标目录</td></tr><tr><td>mv 目录名 目录名</td><td>目标目录已存在，将源目录移动到目标目录；目标目录不存在则改名</td></tr><tr><td>mv 目录名 文件名</td><td>出错</td></tr></tbody></table><p><strong>实例</strong></p><p>将文件 aaa 更名为 bbb :</p><p><code>mv aaa bbb</code></p><p>将info目录放入logs目录中。注意，如果logs目录不存在，则该命令将info改名为logs。</p><p><code>mv info/ logs</code></p><p>再如将/usr/student下的所有文件和目录移到当前目录下，命令行为：</p><p><code>$ mv /usr/student/*  .</code></p></section>
</li>
<li>
<section><h3>开放端口<a href="#开放端口"><span>#</span></a></h3></section>
</li>
</ol><ul>
<li>
<p>开启防火墙</p>
<p><code>systemctl start firewalld</code></p>
</li>
<li>
<p>开放指定端口</p>
<p><code>firewall-cmd --zone=public --add-port=1935/tcp --permanent</code></p>
<blockquote><p>命令含义：</p><p>–zone #作用域</p><p>–add-port=1935/tcp #添加端口，格式为：端口/通讯协议</p><p>–permanent #永久生效，没有此参数重启后失效</p></blockquote>
</li>
<li>
<p>重启防火墙</p>
<p><code>firewall-cmd --reload</code></p>
</li>
<li>
<p>关闭防火墙</p>
<p><code>systemctl stop firewalld</code></p>
</li>
<li>
<p>查看防火墙状态</p>
<p><code>systemctl status firewalld</code></p>
<p><code>firewall-cmd --state</code></p>
</li>
<li>
<p>查看端口号</p>
<p><code>netstat -ntlp</code> //查看当前所有tcp端口·</p>
<p><code>netstat -ntulp |grep 1935</code> //查看所有1935端口使用情况·</p>
</li>
<li>
<p>根据进程号查看路径</p>
<p>ll /proc/进程号/cwd</p>
<p>ll /proc/16980/cwd</p>
</li>
<li>
<p>查看开放的端口</p>
<p>firewall-cmd —list-port</p>
</li>
</ul><ol>
<li>
<section><h3>配置防火墙<a href="#配置防火墙"><span>#</span></a></h3></section>
</li>
</ol><ul>
<li>
<p>关闭防火墙</p>
<p><code>systemctl stop firewalld</code></p>
</li>
<li>
<p>确认防火墙状态已关闭：</p>
<p><code>systemctl status firewalld</code></p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>○</span><span> </span><span>firewalld.service</span><span> </span><span>-</span><span> </span><span>firewalld</span><span> </span><span>-</span><span> </span><span>dynamic</span><span> </span><span>firewall</span><span> </span><span>daemon</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>   </span><span>Loaded:</span><span> </span><span>loaded</span><span> (/usr/lib/systemd/system/firewalld.service; </span><span>disabled</span><span>; </span><span>vendor</span><span> </span><span>preset:</span><span> </span><span>enabled</span><span>)</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>   </span><span>Active:</span><span> </span><span>inactive</span><span> (dead)</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>​</span><span>     </span><span>Docs:</span><span> </span><span>man:firewalld</span><span>(</span><span>1</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>再关闭其开机自启：</p>
<p><code>systemctl disable firewalld</code></p>
</li>
</ul><ol>
<li>
<section><h3>访问端口<a href="#访问端口"><span>#</span></a></h3></section>
</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>curl</span><span> </span><span>ip:port</span></div></div><div><div><div>2</div></div><div><span>docker</span><span> </span><span>授权当前账户执行docker权限</span></div></div><div><div><div>3</div></div><div><span>sudo</span><span> </span><span>groupadd</span><span> </span><span>docker</span><span>     </span><span>#添加docker用户组</span></div></div><div><div><div>4</div></div><div><span>sudo</span><span> </span><span>gpasswd</span><span> </span><span>-a</span><span> </span><span>$USER</span><span> </span><span>docker</span><span>     </span><span>#将登陆用户加入到docker用户组中</span></div></div><div><div><div>5</div></div><div><span>newgrp</span><span> </span><span>docker</span><span>     </span><span>#更新用户组</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>
<section><h3>创建用户<a href="#创建用户"><span>#</span></a></h3></section>
</li>
</ol><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>创建用户和密码</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>useradd</span><span> </span><span>-m</span><span> </span><span>aaa</span></div></div><div><div><div>3</div></div><div><span>创建用户名为aaa的用户</span></div></div><div><div><div>4</div></div><div><span>-m：自动建立用户的登入目录</span></div></div><div><div><div>5</div></div><div><span>sudo是允许系统管理员让普通用户执行root命令的一个工具（获取权限）</span></div></div><div><div><div>6</div></div><div><span>这里会需要输入管理员的密码（不是你想给新用户设置的密码！！！）</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span>sudo</span><span> </span><span>passwd</span><span> </span><span>aaa</span></div></div><div><div><div>9</div></div><div><span>输入用户aaa的密码</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>设置给予的权限</span></div></div><div><div><div>12</div></div><div><span>sudo</span><span> </span><span>vi</span><span> </span><span>/etc/sudoers</span></div></div><div><div><div>13</div></div><div><span>找到user</span><span> </span><span>privilege这一行，加入</span></div></div><div><div><div>14</div></div><div><span>aaa</span><span>  </span><span>ALL=</span><span>(</span><span>ALL:ALL</span><span>) </span><span>ALL</span></div></div><div><div><div>15</div></div><div><span>删除用户</span></div></div><div><div><div>16</div></div><div><span>sudo</span><span> </span><span>userdel</span><span> </span><span>-r</span><span> </span><span>aaa</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><ol>
<li>
<section><h3>配置环境变量<a href="#配置环境变量"><span>#</span></a></h3></section>
</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>vi</span><span> </span><span>/etc/profile</span><span> </span><span>进入配置文件</span></div></div><div><div><div>2</div></div><div><span>export</span><span> 环境变量key = 环境变量value</span></div></div><div><div><div>3</div></div><div><span>例：export</span><span> </span><span>DOTNET_ROOT=</span><span>$HOME</span><span>/dotnet</span></div></div><div><div><div>4</div></div><div><span>export</span><span> </span><span>PATH</span><span>=</span><span>$PATH</span><span>:</span><span>$HOME</span><span>/</span><span>dotnet</span></div></div><div><div><div>5</div></div><div><span>保存退出后</span><span> </span><span>刷新</span><span> </span><span>source</span><span> </span><span>/etc/profile</span><span> </span><span>使环境变量生效</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
</li>
</ol>
<p>​</p>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/5901b3f7/</id>
      <title type="text">Github+picGo+Typora搭建图床</title>
      <published>2024-05-22T20:31:13.000Z</published>
      <updated>2024-05-22T20:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/5901b3f7/"/>
      <summary type="text">本文《Github+picGo+Typora搭建图床》详细介绍了如何使用Github、PicGo和Typora搭建个人图床的过程。如何在Vscode中安装Cnblogs插件，以便将写好的博客上传到博客园。整个过程步骤清晰，适合初学者参考和实践。</summary>
      <content type="html"><![CDATA[<section><h2>准备<a href="#准备"><span>#</span></a></h2><blockquote><p>Github账号注册/创建一个Public仓库</p></blockquote><blockquote><p><a href="https://github.com/Molunerfinn/PicGo/releases" target="_blank">picgo下载链接</a></p></blockquote><blockquote><p><a href="https://typora.ymzhxing.cn/index.html?bd_vid=11765516185414740389" target="_blank">Typora下载安装</a></p></blockquote><blockquote><p>Vscode下载安装</p></blockquote></section>
<section><h2>生成 Github Tokens<a href="#生成-github-tokens"><span>#</span></a></h2><ul>
<li>
<p>登录<a href="https://github.com/" target="_blank">Github</a></p>
</li>
<li>
<p>移动到右上角的头像，选择<code>Settings</code></p>
</li>
<li>
<p>进入<code>Settings</code>后，向下滚动找到<code>Developer Settings</code><a href="https://github.com/settings/tokens" target="_blank">tokens</a></p>
</li>
<li>
<p>网页跳转后，选左边的<code>Personal access tokens</code>，点击<code>Generate a personal access token</code></p>
</li>
<li>
<p><code>Note</code>里填写为什么创建这个Token，可随意填写，下方选项只勾选<code>repo</code>即可</p>
</li>
<li>
<p>滑到最下方点击 <code>Generate token</code>，Token信息只会出现一次，生成后记得复制保存。</p>
<h2>PicGo设置<a href="#picgo设置"><span>#</span></a></h2>
<ul>
<li>
<p><a href="https://github.com/Molunerfinn/PicGo/releases" target="_blank">picgo下载链接</a></p>
</li>
<li>
<p>PicGo-Setup-2.4.0-beta.6.exe 选这个版本的</p>
</li>
<li>
<p>安装完成打开运行，左侧选择<code>图床设置</code>，选择<code>GitHub图床</code></p>
</li>
</ul>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/202405221413632.png" alt="image-20240522141343592" /><figcaption>image-20240522141343592</figcaption></figure><p></p>
<ul>
<li>参数说明
<ul>
<li>图床配置名 &gt;&gt; <code>Github创建的仓库名</code></li>
<li>设定仓库名 &gt;&gt; <code>Github用户名</code>/<code>Github创建的仓库名</code></li>
<li>设定分支名 &gt;&gt; main</li>
<li>设定Token &gt;&gt; 前面生成的<code>Token</code>（如果时间过期了就重新生成一个，嫌麻烦就直接生成一个永久的）</li>
<li>设定储存路径 &gt;&gt; 会存在你Github仓库<code>main</code>分支下，建议设置成日期格式方便后期查找删除</li>
<li>设定自定义域名 &gt;&gt; 设置为<code>https:cdn.jsd.cdn.zzko.cn/gh/Github用户名/仓库名/@main</code>（会使用VPN工具的话可以不使用cdn加速，空白即可）</li>
</ul>
</li>
</ul>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https:</span><span>//jsd.cdn.zzko.cn/gh/wangbin-blog/pic-resources@main</span></div></div><div><div><div>2</div></div><div><span>https:</span><span>//gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ul>
<li>sanjiudemiao为Github名，Blogimages是仓库名</li>
<li>设置完成，点击完确定。 一定要 *<strong>设为默认图床*</strong></li>
<li>打开 <code>PicGO设置</code>下的<code>时间戳重命名</code></li>
</ul>
<h2>Typora设置<a href="#typora设置"><span>#</span></a></h2>
<ul>
<li>
<p>手动激活</p>
<p>Typora 手动激活，不用修改时间，不用补丁</p>
<p>下面是操作步骤：</p>
<p>第一步： 下载最新版本的Typora安装</p>
<p>第二部： 安装完后，进入typora</p>
<p>的安装目录下的 \resources\page-dist\static\js 目录，找到 LicenseIndex开头的文件</p>
<p>第三部：用文本编辑器打开该文件，搜索hasActivated=“true”==e.hasActivated并将其替换为
hasActivated=“true”==“true”</p>
<p>（修改前，可将该文件备份一下，万一操作失误，可以进行恢复）</p>
</li>
<li>
<p>打开Typora，点击左上角菜单栏的【文件】，点击弹出框里下方的【偏好设置】</p>
</li>
<li>
<p>打开页面，左侧选择【图象】，图像里的设置按下设置：</p>
</li>
</ul>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/202405221409381.png" alt="image-20240421212929685" /><figcaption>image-20240421212929685</figcaption></figure><p></p>
<ul>
<li>
<p>设置完毕之后 点击验证图片上传选项 如果显示上传失败</p>
<blockquote><p>检查PicGO是否设置为<code>默认图床</code></p></blockquote>
</li>
<li>
<p>将图片从Picgo上传，粘贴到Typora上</p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/202405221411737.png" alt="image-20240522141110701" /><figcaption>image-20240522141110701</figcaption></figure><p></p>
</li>
<li>
<p>截图到粘贴到Typora上，然后点击上传图片</p>
</li>
</ul>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/202405221409748.png" alt="image-20240421213109034" /><figcaption>image-20240421213109034</figcaption></figure><p></p>
<h2>Vscode设置<a href="#vscode设置"><span>#</span></a></h2>
<ul>
<li>
<p>打开Vscode，点击左侧的<code>扩展</code>，搜索<code>cnblogs</code>，点击安装即可</p>
<blockquote><p>或者打开<a href="https://i.cnblogs.com/preference" target="_blank">博客园设置</a>
选择Vscode插件
点击·install· &gt;&gt; 点击·打开Vscode· &gt;&gt; 安装拓展即可</p><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/202405221413435.png" alt="image-20240421213109033" /><figcaption>image-20240421213109033</figcaption></figure><p></p></blockquote>
</li>
</ul>
<h2>开始写博客<a href="#开始写博客"><span>#</span></a></h2>
<ul>
<li>打开Typora完成博客的编写。</li>
<li>打开Vscode，打开你写好的博客文件</li>
<li>点击鼠标右键，选择上传到博客园，选择新建博文</li>
</ul>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/202405221409998.png" alt="ootd" /><figcaption>ootd</figcaption></figure><p></p>
<ul>
<li>右侧完成博文设置，点击确定，会显示博文已创建（勾选发布即可上传到博客主页上，不勾选则在草稿箱里）</li>
</ul>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/202405221412995.png" alt="ootd1" /><figcaption>ootd1</figcaption></figure><p></p>
<ul>
<li>再次点击鼠标右键，选择上传到博客园完成上传</li>
<li>后续修改直接在Typora上修改，然后打开Vscode，鼠标右键，再次点击上传到博客园即可</li>
</ul>
</li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/6375ab96/</id>
      <title type="text">【工具】Watt Toolkit GitHub加速</title>
      <published>2024-05-22T20:31:13.000Z</published>
      <updated>2024-05-22T20:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/6375ab96/"/>
      <summary type="text">本文介绍了如何使用 Watt Toolkit（即 Steam++）来加速 GitHub 访问。文章还提供了取消 git 代理的命令，方便用户根据需要进行切换。本文适合需要提高 GitHub 访问速度的开发者和用户参考。</summary>
      <content type="html"><![CDATA[<p>Steam 必备神器 <code>Watt Toolkit</code>，也就是 <code>Steam++</code> 自带了 GitHub 加速，但当我们开启 GitHub 加速后，网页是加速了，但 git 命令还不行。如果想让 <code>git clone</code> 等命令也实现加速的话，我们还需要配置一下 git 的代理。</p>
<p>首先将 <code>Watt Toolkit</code> 的 GitHub <code>加速模式</code> 选择 <code>系统代理模式</code>，然后我们可以通过操作系统的 <code>设置 -&gt; 网络和 Internet -&gt; 代理</code> 来查看代理 IP 和端口，例如：127.0.0.1&lt;26561&gt;。</p>
<p>然后，我们通过以下命令来设置 git 的 HTTP 代理，并且还要同时禁用 SSL 证书检查，这样 <code>git clone</code> 等命令也会实现加速效果了。</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>config</span><span> </span><span>--global</span><span> </span><span>http.proxy</span><span> </span><span>127.0.0.1:26561</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>config</span><span> </span><span>--global</span><span> </span><span>http.sslverify</span><span> </span><span>false</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>取消 git 代理的方式如下：</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>config</span><span> </span><span>--global</span><span> </span><span>--unset</span><span> </span><span>http.proxy</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>config</span><span> </span><span>--global</span><span> </span><span>--unset</span><span> </span><span>http.sslverify</span></div></div></code></pre><div><div></div><div></div></div></figure></div>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/6aea9c03/</id>
      <title type="text">Hexo Shoka 文章加密</title>
      <published>2024-05-22T20:31:13.000Z</published>
      <updated>2024-05-22T20:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/6aea9c03/"/>
      <summary type="text"></summary>
      <content type="html"><![CDATA[本文已加密保护，请访问网站查看。]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/e4550ecb/</id>
      <title type="text">Hexo Shoka 主题本地搜索</title>
      <published>2024-05-22T20:31:13.000Z</published>
      <updated>2024-05-22T20:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/e4550ecb/"/>
      <summary type="text">由于Shoka作者提供的搜索使用Algolia实现，但是Algolia免费版是有每月请求次数限制的，因此想要使用本地搜索来替换。功夫不负有心人，我在Shoka主题的搜索功能配置找到了解决办法，在此感谢linn提供的方法。在使用过程中也遇到了一些问题，所以在此记录一下各文件的修改情况。</summary>
      <content type="html"><![CDATA[<p>由于 <code>Shoka</code> 作者提供的搜索使用 <code>Algolia</code> 实现，但是 <code>Algolia</code> 免费版是有每月请求次数限制的，因此想要使用本地搜索来替换。功夫不负有心人，我在 <code>Shoka</code> 主题的搜索功能配置找到了解决办法，在此感谢 <code>linn</code> 提供的方法。</p>
<section><h2>问题 &amp; 解决<a href="#问题--解决"><span>#</span></a></h2><p>在使用过程中也遇到了一些问题，如 localSearch() 方法报不支持的语法错误，所以在此记录一下各文件的修改情况。</p><section><h3>安装插件<a href="#安装插件"><span>#</span></a></h3><p>本地搜索通过 <code>hexo-generator-searchdb</code> 插件实现，需要先安装插件。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>hexo-generator-searchdb</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>修改 page.js<a href="#修改-pagejs"><span>#</span></a></h3><p><code>shoka/source/js/_app/page.js</code> 中 <code>localSearch()</code> 修改后的文件如下，将整个 <code>localSearch</code> 复制到主题的 <code>shoka/source/js/_app/page.js</code> 中即可,不要覆盖原文件。</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>const</span><span> </span><span>localSearch</span><span> </span><span>=</span><span> </span><span>function</span><span><span>(</span><span>pjax</span><span>) {</span></span></div></div><div><div><div>2</div></div><div><span>  </span><span>// 参考 hexo next 主题的配置方法</span></div></div><div><div><div>3</div></div><div><span>  </span><span>// 参考 https://qiuyiwu.github.io/2019/01/25/Hexo-LocalSearch/ 博文</span></div></div><div><div><div>4</div></div><div><span>  </span><span>if</span><span>(</span><span>CONFIG</span><span>.</span><span>localSearch</span><span> </span><span>===</span><span> </span><span>null</span><span>)</span></div></div><div><div><div>5</div></div><div><span>    </span><span>return</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>  </span><span>if</span><span>(</span><span>!</span><span><span>siteSearch</span><span>) {</span></span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>siteSearch</span><span> </span><span>=</span><span> </span><span>BODY</span><span>.</span><span>createChild</span><span>(</span><span>'div'</span><span>, {</span></div></div><div><div><div>9</div></div><div><span>      </span><span>id</span><span>:</span><span> </span><span>'search'</span><span>,</span></div></div><div><div><div>10</div></div><div><span>      </span><span>innerHTML</span><span>:</span><span> </span><span>'&lt;div class="inner"&gt;&lt;div class="header"&gt;&lt;span class="icon"&gt;&lt;i class="ic i-search"&gt;&lt;/i&gt;&lt;/span&gt;&lt;div class="search-input-container"&gt;&lt;input class="search-input"autocompvare="off"placeholder="'</span><span>+</span><span>LOCAL</span><span>.</span><span>search</span><span>.</span><span>placeholder</span><span>+</span><span>'"spellcheck="false"type="text"id="local-search-input"&gt;&lt;/div&gt;&lt;span class="close-btn"&gt;&lt;i class="ic i-times-circle"&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="results"id="search-results"&gt;&lt;div class="inner"&gt;&lt;div id="search-stats"&gt;&lt;/div&gt;&lt;div id="search-hits"&gt;&lt;/div&gt;&lt;div id="search-pagination"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;'</span></div></div><div><div><div>11</div></div><div><span><span>    </span></span><span>});</span></div></div><div><div><div>12</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>  </span><span>var</span><span><span> </span><span>isFetched</span><span> </span></span><span>=</span><span> </span><span>false</span><span>;</span></div></div><div><div><div>15</div></div><div><span>  </span><span>var</span><span><span> </span><span>datas</span><span>;</span></span></div></div><div><div><div>16</div></div><div><span>  </span><span>var</span><span><span> </span><span>isXml</span><span> </span></span><span>=</span><span> </span><span>true</span><span>;</span></div></div><div><div><div>17</div></div><div><span>  </span><span>var</span><span><span> </span><span>current_page</span><span> </span></span><span>=</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>18</div></div><div><span>  </span><span>var</span><span><span> </span><span>pageSize</span><span> </span></span><span>=</span><span> </span><span>parseInt</span><span>(</span><span>CONFIG</span><span>.</span><span>localSearch</span><span>.</span><span>pageSize</span><span>, </span><span>10</span><span>);</span></div></div><div><div><div>19</div></div><div><span>  </span><span>if</span><span>(</span><span>isNaN</span><span><span>(</span><span>pageSize</span><span>)) </span><span>pageSize</span><span> </span></span><span>=</span><span> </span><span>10</span><span>;</span></div></div><div><div><div>20</div></div><div><span>  </span><span>var</span><span><span> </span><span>total_pages</span><span> </span></span><span>=</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>21</div></div><div><span>  </span><span>var</span><span><span> </span><span>max_page_on_show</span><span> </span></span><span>=</span><span> </span><span>7</span><span>; </span><span>// 一次最多显示 7 个页码</span></div></div><div><div><div>22</div></div><div><span>  </span><span>var</span><span><span> </span><span>start_page</span><span> </span></span><span>=</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>23</div></div><div><span>  </span><span>var</span><span><span> </span><span>end_page</span><span> </span></span><span>=</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>24</div></div><div><span>  </span><span>var</span><span><span> </span><span>resultItems</span><span> </span></span><span>=</span><span> [];</span></div></div><div><div><div>25</div></div><div>
</div></div><div><div><div>26</div></div><div><span>  </span><span>// search DB path</span></div></div><div><div><div>27</div></div><div><span>  </span><span>var</span><span><span> </span><span>searchPath</span><span> </span></span><span>=</span><span> </span><span>CONFIG</span><span>.</span><span>localSearch</span><span>.</span><span>path</span><span>;</span></div></div><div><div><div>28</div></div><div><span>  </span><span>if</span><span><span> (</span><span>searchPath</span><span>.</span></span><span>length</span><span> </span><span>==</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>29</div></div><div><span><span>    </span></span><span>searchPath</span><span> </span><span>=</span><span> </span><span>'search.xml'</span><span>;</span></div></div><div><div><div>30</div></div><div><span><span>  </span></span><span>} </span><span>else</span><span> </span><span>if</span><span><span> (</span><span>searchPath</span><span>.</span></span><span>endsWith</span><span>(</span><span>'json'</span><span>)) {</span></div></div><div><div><div>31</div></div><div><span><span>    </span></span><span>isXml</span><span> </span><span>=</span><span> </span><span>false</span><span>;</span></div></div><div><div><div>32</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>33</div></div><div>
</div></div><div><div><div>34</div></div><div><span>  </span><span>const</span><span> </span><span>input</span><span> </span><span>=</span><span> </span><span>$</span><span>(</span><span>'.search-input'</span><span>); </span><span>// document.querySelector('.search-input');</span></div></div><div><div><div>35</div></div><div><span>  </span><span>const</span><span> </span><span>resultContent</span><span> </span><span>=</span><span><span> </span><span>document</span><span>.</span></span><span>getElementById</span><span>(</span><span>'search-hits'</span><span>);</span></div></div><div><div><div>36</div></div><div><span>  </span><span>const</span><span> </span><span>paginationContent</span><span> </span><span>=</span><span><span> </span><span>document</span><span>.</span></span><span>getElementById</span><span>(</span><span>'search-pagination'</span><span>);</span></div></div><div><div><div>37</div></div><div>
</div></div><div><div><div>38</div></div><div><span>  </span><span>const</span><span> </span><span>getIndexByWord</span><span> </span><span>=</span><span> </span><span>function</span><span><span>(</span><span>word</span><span>, </span><span>text</span><span>, </span><span>caseSensitive</span><span>) {</span></span></div></div><div><div><div>39</div></div><div><span>    </span><span>if</span><span> (</span><span>CONFIG</span><span>.</span><span>localSearch</span><span>.</span><span>unescape</span><span>) {</span></div></div><div><div><div>40</div></div><div><span>      </span><span>var</span><span><span> </span><span>div</span><span> </span></span><span>=</span><span><span> </span><span>document</span><span>.</span></span><span>createElement</span><span>(</span><span>'div'</span><span>);</span></div></div><div><div><div>41</div></div><div><span><span>      </span></span><span>div</span><span>.</span><span>innerText</span><span> </span><span>=</span><span><span> </span><span>word</span><span>;</span></span></div></div><div><div><div>42</div></div><div><span><span>      </span></span><span>word</span><span> </span><span>=</span><span><span> </span><span>div</span><span>.</span></span><span>innerHTML</span><span>;</span></div></div><div><div><div>43</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>44</div></div><div><span>    </span><span>var</span><span><span> </span><span>wordLen</span><span> </span></span><span>=</span><span><span> </span><span>word</span><span>.</span></span><span>length</span><span>;</span></div></div><div><div><div>45</div></div><div><span>    </span><span>if</span><span><span> (</span><span>wordLen</span><span> </span></span><span>===</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>46</div></div><div><span>      </span><span>return</span><span> [];</span></div></div><div><div><div>47</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>48</div></div><div><span>    </span><span>var</span><span><span> </span><span>startPosition</span><span> </span></span><span>=</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>49</div></div><div><span>    </span><span>var</span><span><span> </span><span>position</span><span> </span></span><span>=</span><span> [];</span></div></div><div><div><div>50</div></div><div><span>    </span><span>var</span><span><span> </span><span>index</span><span> </span></span><span>=</span><span> [];</span></div></div><div><div><div>51</div></div><div><span>    </span><span>if</span><span> (</span><span>!</span><span><span>caseSensitive</span><span>) {</span></span></div></div><div><div><div>52</div></div><div><span><span>      </span></span><span>text</span><span> </span><span>=</span><span><span> </span><span>text</span><span>.</span></span><span>toLowerCase</span><span>();</span></div></div><div><div><div>53</div></div><div><span><span>      </span></span><span>word</span><span> </span><span>=</span><span><span> </span><span>word</span><span>.</span></span><span>toLowerCase</span><span>();</span></div></div><div><div><div>54</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>55</div></div><div>
</div></div><div><div><div>56</div></div><div><span>    </span><span>while</span><span><span> ((</span><span>position</span><span> </span></span><span>=</span><span><span> </span><span>text</span><span>.</span></span><span>indexOf</span><span><span>(</span><span>word</span><span>, </span><span>startPosition</span><span>)) </span></span><span>&gt;</span><span> </span><span>-</span><span>1</span><span>) {</span></div></div><div><div><div>57</div></div><div><span><span>      </span></span><span>index</span><span>.</span><span>push</span><span>({</span><span>position</span><span>:</span><span><span>position</span><span>, </span></span><span>word</span><span>:</span><span><span>word</span><span>});</span></span></div></div><div><div><div>58</div></div><div><span><span>      </span></span><span>startPosition</span><span> </span><span>=</span><span><span> </span><span>position</span><span> </span></span><span>+</span><span><span> </span><span>wordLen</span><span>;</span></span></div></div><div><div><div>59</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>60</div></div><div><span>    </span><span>return</span><span><span> </span><span>index</span><span>;</span></span></div></div><div><div><div>61</div></div><div><span><span>  </span></span><span>};</span></div></div><div><div><div>62</div></div><div>
</div></div><div><div><div>63</div></div><div><span>  </span><span>// Merge hits into slices</span></div></div><div><div><div>64</div></div><div><span>  </span><span>const</span><span> </span><span>mergeIntoSlice</span><span> </span><span>=</span><span> </span><span>function</span><span><span>(</span><span>start</span><span>, </span><span>end</span><span>, </span><span>index</span><span>, </span><span>searchText</span><span>) {</span></span></div></div><div><div><div>65</div></div><div><span>    </span><span>var</span><span><span> </span><span>item</span><span> </span></span><span>=</span><span><span> </span><span>index</span><span>[</span><span>index</span><span>.</span></span><span>length</span><span> </span><span>-</span><span> </span><span>1</span><span>];</span></div></div><div><div><div>66</div></div><div><span>    </span><span>var</span><span><span> </span><span>position</span><span> </span></span><span>=</span><span><span> </span><span>item</span><span>.</span></span><span>position</span><span>;</span></div></div><div><div><div>67</div></div><div><span>    </span><span>var</span><span><span> </span><span>word</span><span> </span></span><span>=</span><span><span> </span><span>item</span><span>.</span></span><span>word</span><span>;</span></div></div><div><div><div>68</div></div><div><span>    </span><span>var</span><span><span> </span><span>hits</span><span> </span></span><span>=</span><span> [];</span></div></div><div><div><div>69</div></div><div><span>    </span><span>var</span><span><span> </span><span>searchTextCountInSlice</span><span> </span></span><span>=</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>70</div></div><div><span>    </span><span>while</span><span><span> (</span><span>position</span><span> </span></span><span>+</span><span><span> </span><span>word</span><span>.</span></span><span>length</span><span> </span><span>&lt;=</span><span><span> </span><span>end</span><span> </span></span><span>&amp;&amp;</span><span><span> </span><span>index</span><span>.</span></span><span>length</span><span> </span><span>!==</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>71</div></div><div><span>      </span><span>if</span><span><span> (</span><span>word</span><span> </span></span><span>===</span><span><span> </span><span>searchText</span><span>) {</span></span></div></div><div><div><div>72</div></div><div><span><span>        </span></span><span>searchTextCountInSlice</span><span>++</span><span>;</span></div></div><div><div><div>73</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>74</div></div><div><span><span>      </span></span><span>hits</span><span>.</span><span>push</span><span>({</span></div></div><div><div><div>75</div></div><div><span>        </span><span>position</span><span>:</span><span><span>position</span><span>,</span></span></div></div><div><div><div>76</div></div><div><span>        </span><span>length</span><span>:</span><span><span> </span><span>word</span><span>.</span></span><span>length</span></div></div><div><div><div>77</div></div><div><span><span>      </span></span><span>});</span></div></div><div><div><div>78</div></div><div>
</div></div><div><div><div>79</div></div><div><span>      </span><span>var</span><span><span> </span><span>wordEnd</span><span> </span></span><span>=</span><span><span> </span><span>position</span><span> </span></span><span>+</span><span><span> </span><span>word</span><span>.</span></span><span>length</span><span>;</span></div></div><div><div><div>80</div></div><div>
</div></div><div><div><div>81</div></div><div><span>      </span><span>// Move to next position of hit</span></div></div><div><div><div>82</div></div><div><span><span>      </span></span><span>index</span><span>.</span><span>pop</span><span>();</span></div></div><div><div><div>83</div></div><div><span>      </span><span>while</span><span><span> (</span><span>index</span><span>.</span></span><span>length</span><span> </span><span>!==</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>84</div></div><div><span><span>        </span></span><span>item</span><span> </span><span>=</span><span><span> </span><span>index</span><span>[</span><span>index</span><span>.</span></span><span>length</span><span> </span><span>-</span><span> </span><span>1</span><span>];</span></div></div><div><div><div>85</div></div><div><span><span>        </span></span><span>position</span><span> </span><span>=</span><span><span> </span><span>item</span><span>.</span></span><span>position</span><span>;</span></div></div><div><div><div>86</div></div><div><span><span>        </span></span><span>word</span><span> </span><span>=</span><span><span> </span><span>item</span><span>.</span></span><span>word</span><span>;</span></div></div><div><div><div>87</div></div><div><span>        </span><span>if</span><span><span> (</span><span>wordEnd</span><span> </span></span><span>&gt;</span><span><span> </span><span>position</span><span>) {</span></span></div></div><div><div><div>88</div></div><div><span><span>          </span></span><span>index</span><span>.</span><span>pop</span><span>();</span></div></div><div><div><div>89</div></div><div><span><span>        </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>90</div></div><div><span>          </span><span>break</span><span>;</span></div></div><div><div><div>91</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>92</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>93</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>94</div></div><div><span>    </span><span>return</span><span> {</span></div></div><div><div><div>95</div></div><div><span>      </span><span>hits</span><span>:</span><span><span>hits</span><span>,</span></span></div></div><div><div><div>96</div></div><div><span>      </span><span>start</span><span>:</span><span><span>start</span><span>,</span></span></div></div><div><div><div>97</div></div><div><span>      </span><span>end</span><span>:</span><span><span>end</span><span>,</span></span></div></div><div><div><div>98</div></div><div><span>      </span><span>searchTextCount</span><span>:</span><span><span> </span><span>searchTextCountInSlice</span></span></div></div><div><div><div>99</div></div><div><span><span>    </span></span><span>};</span></div></div><div><div><div>100</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>101</div></div><div>
</div></div><div><div><div>102</div></div><div><span>  </span><span>// Highlight title and content</span></div></div><div><div><div>103</div></div><div><span>  </span><span>const</span><span> </span><span>highlightKeyword</span><span> </span><span>=</span><span> </span><span>function</span><span><span>(</span><span>text</span><span>, </span><span>slice</span><span>) {</span></span></div></div><div><div><div>104</div></div><div><span>    </span><span>var</span><span><span> </span><span>result</span><span> </span></span><span>=</span><span> </span><span>''</span><span>;</span></div></div><div><div><div>105</div></div><div><span>    </span><span>var</span><span><span> </span><span>prevEnd</span><span> </span></span><span>=</span><span><span> </span><span>slice</span><span>.</span></span><span>start</span><span>;</span></div></div><div><div><div>106</div></div><div><span><span>    </span></span><span>slice</span><span>.</span><span>hits</span><span>.</span><span>forEach</span><span>(</span><span>function</span><span><span>(</span><span>hit</span><span>)  {</span></span></div></div><div><div><div>107</div></div><div><span><span>      </span></span><span>result</span><span> </span><span>+=</span><span><span> </span><span>text</span><span>.</span></span><span>substring</span><span><span>(</span><span>prevEnd</span><span>, </span><span>hit</span><span>.</span></span><span>position</span><span>);</span></div></div><div><div><div>108</div></div><div><span>      </span><span>var</span><span><span> </span><span>end</span><span> </span></span><span>=</span><span><span> </span><span>hit</span><span>.</span></span><span>position</span><span> </span><span>+</span><span><span> </span><span>hit</span><span>.</span></span><span>length</span><span>;</span></div></div><div><div><div>109</div></div><div><span><span>      </span></span><span>result</span><span> </span><span>+=</span><span> </span><span>'&lt;mark&gt;'</span><span>+</span><span><span> </span><span>text</span><span>.</span></span><span>substring</span><span><span>(</span><span>hit</span><span>.</span></span><span>position</span><span><span>, </span><span>end</span><span>)</span></span><span>+</span><span>'&lt;/mark&gt;'</span><span>;</span></div></div><div><div><div>110</div></div><div><span><span>      </span></span><span>prevEnd</span><span> </span><span>=</span><span><span> </span><span>end</span><span>;</span></span></div></div><div><div><div>111</div></div><div><span><span>    </span></span><span>});</span></div></div><div><div><div>112</div></div><div><span><span>    </span></span><span>result</span><span> </span><span>+=</span><span><span> </span><span>text</span><span>.</span></span><span>substring</span><span><span>(</span><span>prevEnd</span><span>, </span><span>slice</span><span>.</span></span><span>end</span><span>);</span></div></div><div><div><div>113</div></div><div><span>    </span><span>return</span><span><span> </span><span>result</span><span>;</span></span></div></div><div><div><div>114</div></div><div><span><span>  </span></span><span>};</span></div></div><div><div><div>115</div></div><div>
</div></div><div><div><div>116</div></div><div><span>  </span><span>const</span><span> </span><span>pagination</span><span> </span><span>=</span><span> </span><span>function</span><span>() {</span></div></div><div><div><div>117</div></div><div>
</div></div><div><div><div>118</div></div><div><span>    </span><span>const</span><span> </span><span>addPrevPage</span><span> </span><span>=</span><span> </span><span>function</span><span><span>(</span><span>current_page</span><span>) {</span></span></div></div><div><div><div>119</div></div><div><span>      </span><span>var</span><span><span> </span><span>classContent</span><span> </span></span><span>=</span><span> </span><span>''</span><span>;</span></div></div><div><div><div>120</div></div><div><span>      </span><span>var</span><span><span> </span><span>numberContent</span><span> </span></span><span>=</span><span> </span><span>''</span><span>;</span></div></div><div><div><div>121</div></div><div><span>      </span><span>if</span><span><span> (</span><span>current_page</span><span> </span></span><span>===</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>122</div></div><div><span><span>        </span></span><span>classContent</span><span> </span><span>=</span><span> </span><span>'#search-pagination pagination-item disabled-item'</span><span>;</span></div></div><div><div><div>123</div></div><div><span><span>        </span></span><span>numberContent</span><span> </span><span>=</span><span> </span><span>'&lt;span class="#search-pagination page-number"&gt;&lt;i class="ic i-angle-left"&gt;&lt;/i&gt;&lt;/span&gt;'</span><span>;</span></div></div><div><div><div>124</div></div><div><span><span>      </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>125</div></div><div><span><span>        </span></span><span>classContent</span><span> </span><span>=</span><span> </span><span>'#search-pagination pagination-item'</span><span>;</span></div></div><div><div><div>126</div></div><div><span><span>        </span></span><span>numberContent</span><span> </span><span>=</span><span> </span><span>'&lt;a class="#search-pagination page-number" aria-label="Prev" href="#"&gt;&lt;i class="ic i-angle-left"&gt;&lt;/i&gt;&lt;/a&gt;'</span><span>;</span></div></div><div><div><div>127</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>128</div></div><div><span>      </span><span>var</span><span><span> </span><span>prevPage</span><span> </span></span><span>=</span><span> </span><span>'&lt;li class="'</span><span>+</span><span><span> </span><span>classContent</span><span> </span></span><span>+</span><span>'" id="prev-page"&gt;'</span><span>+</span><span><span> </span><span>numberContent</span></span><span>+</span><span>'&lt;/li&gt;'</span><span>;</span></div></div><div><div><div>129</div></div><div><span>      </span><span>return</span><span><span> </span><span>prevPage</span><span>;</span></span></div></div><div><div><div>130</div></div><div><span><span>    </span></span><span>};</span></div></div><div><div><div>131</div></div><div>
</div></div><div><div><div>132</div></div><div><span>    </span><span>const</span><span> </span><span>addNextPage</span><span> </span><span>=</span><span> </span><span>function</span><span><span>(</span><span>current_page</span><span>) {</span></span></div></div><div><div><div>133</div></div><div><span>      </span><span>var</span><span><span> </span><span>classContent</span><span> </span></span><span>=</span><span> </span><span>''</span><span>;</span></div></div><div><div><div>134</div></div><div><span>      </span><span>var</span><span><span> </span><span>numberContent</span><span> </span></span><span>=</span><span> </span><span>''</span><span>;</span></div></div><div><div><div>135</div></div><div><span>      </span><span>if</span><span><span> ((</span><span>current_page</span><span> </span></span><span>+</span><span> </span><span>1</span><span>) </span><span>===</span><span><span> </span><span>total_pages</span><span>) {</span></span></div></div><div><div><div>136</div></div><div><span><span>        </span></span><span>classContent</span><span> </span><span>=</span><span> </span><span>'#search-pagination pagination-item disabled-item'</span><span>;</span></div></div><div><div><div>137</div></div><div><span><span>        </span></span><span>numberContent</span><span> </span><span>=</span><span> </span><span>'&lt;span class="#search-pagination page-number"&gt;&lt;i class="ic i-angle-right"&gt;&lt;/i&gt;&lt;/span&gt;'</span><span>;</span></div></div><div><div><div>138</div></div><div><span><span>      </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>139</div></div><div><span><span>        </span></span><span>classContent</span><span> </span><span>=</span><span> </span><span>'#search-pagination pagination-item'</span><span>;</span></div></div><div><div><div>140</div></div><div><span><span>        </span></span><span>numberContent</span><span> </span><span>=</span><span> </span><span>'&lt;a class="#search-pagination page-number"aria-label="Next"href="#"&gt;&lt;i class="ic i-angle-right"&gt;&lt;/i&gt;&lt;/a&gt;'</span><span>;</span></div></div><div><div><div>141</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>142</div></div><div><span>      </span><span>var</span><span><span> </span><span>nextPage</span><span> </span></span><span>=</span><span> </span><span>'&lt;li class="'</span><span> </span><span>+</span><span><span> </span><span>classContent</span><span> </span></span><span>+</span><span>'"id="next-page"&gt;'</span><span>+</span><span><span> </span><span>numberContent</span><span> </span></span><span>+</span><span>'&lt;/li&gt;'</span><span>;</span></div></div><div><div><div>143</div></div><div><span>      </span><span>return</span><span><span> </span><span>nextPage</span><span>;</span></span></div></div><div><div><div>144</div></div><div><span><span>    </span></span><span>};</span></div></div><div><div><div>145</div></div><div>
</div></div><div><div><div>146</div></div><div><span>    </span><span>const</span><span> </span><span>addPage</span><span> </span><span>=</span><span> </span><span>function</span><span><span>(</span><span>index</span><span>, </span><span>current_page</span><span>)  {</span></span></div></div><div><div><div>147</div></div><div><span>      </span><span>var</span><span><span> </span><span>classContent</span><span> </span></span><span>=</span><span> </span><span>''</span><span>;</span></div></div><div><div><div>148</div></div><div><span>      </span><span>var</span><span><span> </span><span>numberContent</span><span> </span></span><span>=</span><span> </span><span>'&lt;a class="#search-pagination page-number"aria-label="'</span><span>+</span><span><span> (</span><span>index</span><span> </span></span><span>+</span><span> </span><span>1</span><span>) </span><span>+</span><span>'"href="#"&gt;'</span><span>+</span><span><span>(</span><span>index</span></span><span>+</span><span>1</span><span>)</span><span>+</span><span>'&lt;/a&gt;'</span><span>;</span></div></div><div><div><div>149</div></div><div><span>      </span><span>if</span><span><span> (</span><span>index</span><span> </span></span><span>===</span><span><span> </span><span>current_page</span><span>) {</span></span></div></div><div><div><div>150</div></div><div><span><span>        </span></span><span>classContent</span><span> </span><span>=</span><span> </span><span>'#search-pagination pagination-item current'</span><span>;</span></div></div><div><div><div>151</div></div><div><span><span>      </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>152</div></div><div><span><span>        </span></span><span>classContent</span><span> </span><span>=</span><span> </span><span>'#search-pagination pagination-item'</span><span>;</span></div></div><div><div><div>153</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>154</div></div><div><span>      </span><span>var</span><span><span> </span><span>page</span><span> </span></span><span>=</span><span> </span><span>'&lt;li class="'</span><span>+</span><span>classContent</span><span>+</span><span>'" id="page-'</span><span>+</span><span><span>(</span><span>index</span><span> </span></span><span>+</span><span> </span><span>1</span><span>)</span><span>+</span><span>'"&gt;'</span><span>+</span><span>numberContent</span><span>+</span><span>'&lt;/li&gt;'</span><span>;</span></div></div><div><div><div>155</div></div><div><span>      </span><span>return</span><span><span> </span><span>page</span><span>;</span></span></div></div><div><div><div>156</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>157</div></div><div>
</div></div><div><div><div>158</div></div><div><span>    </span><span>const</span><span> </span><span>addPaginationEvents</span><span> </span><span>=</span><span> </span><span>function</span><span><span>(</span><span>start_page</span><span>, </span><span>end_page</span><span>)  {</span></span></div></div><div><div><div>159</div></div><div><span>      </span><span>if</span><span><span> (</span><span>total_pages</span><span> </span></span><span>&lt;=</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>160</div></div><div><span>        </span><span>return</span><span>;</span></div></div><div><div><div>161</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>162</div></div><div><span>      </span><span>const</span><span> </span><span>onPrevPageClick</span><span> </span><span>=</span><span> </span><span>function</span><span><span>(</span><span>event</span><span>) {</span></span></div></div><div><div><div>163</div></div><div><span>        </span><span>if</span><span><span> (</span><span>current_page</span><span> </span></span><span>&gt;</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>164</div></div><div><span><span>          </span></span><span>current_page</span><span> </span><span>-=</span><span> </span><span>1</span><span>;</span></div></div><div><div><div>165</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>166</div></div><div><span>        </span><span>if</span><span><span> (</span><span>current_page</span><span> </span></span><span>&lt;</span><span><span> </span><span>start_page</span><span>) {</span></span></div></div><div><div><div>167</div></div><div><span><span>          </span></span><span>start_page</span><span> </span><span>=</span><span><span> </span><span>current_page</span><span>;</span></span></div></div><div><div><div>168</div></div><div><span><span>          </span></span><span>end_page</span><span> </span><span>=</span><span><span> </span><span>Math</span><span>.</span></span><span>min</span><span><span>(</span><span>end_page</span><span>, </span><span>start_page</span><span> </span></span><span>+</span><span><span> </span><span>max_page_on_show</span><span>);</span></span></div></div><div><div><div>169</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>170</div></div><div><span>        </span><span>pagination</span><span>();</span></div></div><div><div><div>171</div></div><div><span><span>      </span></span><span>};</span></div></div><div><div><div>172</div></div><div><span>      </span><span>const</span><span> </span><span>onNextPageClick</span><span> </span><span>=</span><span> </span><span>function</span><span><span>(</span><span>event</span><span>)  {</span></span></div></div><div><div><div>173</div></div><div><span>        </span><span>if</span><span><span> ((</span><span>current_page</span><span> </span></span><span>+</span><span> </span><span>1</span><span>) </span><span>&lt;</span><span><span> </span><span>total_pages</span><span>) {</span></span></div></div><div><div><div>174</div></div><div><span><span>          </span></span><span>current_page</span><span> </span><span>+=</span><span> </span><span>1</span><span>;</span></div></div><div><div><div>175</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>176</div></div><div><span>        </span><span>if</span><span><span> (</span><span>current_page</span><span> </span></span><span>&gt;</span><span><span> </span><span>end_page</span><span>) {</span></span></div></div><div><div><div>177</div></div><div><span><span>          </span></span><span>end_page</span><span> </span><span>=</span><span><span> </span><span>current_page</span><span>;</span></span></div></div><div><div><div>178</div></div><div><span><span>          </span></span><span>start_page</span><span> </span><span>=</span><span><span> </span><span>Math</span><span>.</span></span><span>max</span><span>(</span><span>0</span><span><span>, </span><span>end_page</span><span> </span></span><span>-</span><span><span> </span><span>max_page_on_show</span><span>);</span></span></div></div><div><div><div>179</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>180</div></div><div><span>        </span><span>pagination</span><span>();</span></div></div><div><div><div>181</div></div><div><span><span>      </span></span><span>};</span></div></div><div><div><div>182</div></div><div><span>      </span><span>const</span><span> </span><span>onPageClick</span><span> </span><span>=</span><span> </span><span>function</span><span><span>(</span><span>event</span><span>)  {</span></span></div></div><div><div><div>183</div></div><div><span>        </span><span>var</span><span><span> </span><span>page_number</span><span> </span></span><span>=</span><span> </span><span>parseInt</span><span><span>(</span><span>event</span><span>.</span></span><span>target</span><span>.</span><span>ariaLabel</span><span>);</span></div></div><div><div><div>184</div></div><div><span><span>        </span></span><span>current_page</span><span> </span><span>=</span><span><span> </span><span>page_number</span><span> </span></span><span>-</span><span> </span><span>1</span><span>; </span><span>// note minus 1 here</span></div></div><div><div><div>185</div></div><div><span>        </span><span>pagination</span><span>();</span></div></div><div><div><div>186</div></div><div><span><span>      </span></span><span>};</span></div></div><div><div><div>187</div></div><div>
</div></div><div><div><div>188</div></div><div><span>      </span><span>var</span><span><span> </span><span>prevPage</span><span> </span></span><span>=</span><span><span> </span><span>document</span><span>.</span></span><span>getElementById</span><span>(</span><span>'prev-page'</span><span>);</span></div></div><div><div><div>189</div></div><div><span>      </span><span>if</span><span><span>(</span><span>prevPage</span><span> </span></span><span>!=</span><span> </span><span>null</span><span><span>)</span><span>prevPage</span><span>.</span></span><span>addEventListener</span><span>(</span><span>'click'</span><span><span>, </span><span>onPrevPageClick</span><span>);</span></span></div></div><div><div><div>190</div></div><div>
</div></div><div><div><div>191</div></div><div><span>      </span><span>var</span><span><span> </span><span>nextPage</span><span> </span></span><span>=</span><span><span> </span><span>document</span><span>.</span></span><span>getElementById</span><span>(</span><span>'next-page'</span><span>);</span></div></div><div><div><div>192</div></div><div><span>      </span><span>if</span><span><span>(</span><span>nextPage</span><span> </span></span><span>!=</span><span> </span><span>null</span><span><span>) </span><span>nextPage</span><span>.</span></span><span>addEventListener</span><span>(</span><span>'click'</span><span><span>, </span><span>onNextPageClick</span><span>);</span></span></div></div><div><div><div>193</div></div><div><span>      </span><span>for</span><span> (</span><span>var</span><span><span> </span><span>i</span><span> </span></span><span>=</span><span><span> </span><span>start_page</span><span>; </span><span>i</span><span> </span></span><span>&lt;</span><span><span> </span><span>end_page</span><span>; </span><span>i</span><span> </span></span><span>+=</span><span> </span><span>1</span><span>) {</span></div></div><div><div><div>194</div></div><div><span>        </span><span>var</span><span><span> </span><span>page</span><span> </span></span><span>=</span><span><span> </span><span>document</span><span>.</span></span><span>getElementById</span><span>(</span><span>'page-'</span><span>+</span><span><span>(</span><span>i</span><span> </span></span><span>+</span><span> </span><span>1</span><span>));</span></div></div><div><div><div>195</div></div><div><span>        </span><span>if</span><span><span>(</span><span>page</span><span> </span></span><span>!=</span><span> </span><span>null</span><span><span>)</span><span>page</span><span>.</span></span><span>addEventListener</span><span>(</span><span>'click'</span><span><span>, </span><span>onPageClick</span><span>);</span></span></div></div><div><div><div>196</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>197</div></div><div><span><span>    </span></span><span>};</span></div></div><div><div><div>198</div></div><div>
</div></div><div><div><div>199</div></div><div>
</div></div><div><div><div>200</div></div><div>
</div></div><div><div><div>201</div></div><div><span><span>    </span></span><span>paginationContent</span><span>.</span><span>innerHTML</span><span> </span><span>=</span><span> </span><span>''</span><span>; </span><span>// clear</span></div></div><div><div><div>202</div></div><div>
</div></div><div><div><div>203</div></div><div><span>    </span><span>var</span><span><span> </span><span>begin_index</span><span> </span></span><span>=</span><span><span> </span><span>Math</span><span>.</span></span><span>min</span><span><span>(</span><span>current_page</span><span> </span></span><span>*</span><span><span> </span><span>pageSize</span><span>, </span><span>resultItems</span><span>.</span></span><span>length</span><span>);</span></div></div><div><div><div>204</div></div><div><span>    </span><span>var</span><span><span> </span><span>end_index</span><span> </span></span><span>=</span><span><span> </span><span>Math</span><span>.</span></span><span>min</span><span><span>(</span><span>begin_index</span><span> </span></span><span>+</span><span><span> </span><span>pageSize</span><span>, </span><span>resultItems</span><span>.</span></span><span>length</span><span>);</span></div></div><div><div><div>205</div></div><div>
</div></div><div><div><div>206</div></div><div><span><span>    </span></span><span>resultContent</span><span>.</span><span>innerHTML</span><span> </span><span>=</span><span><span> </span><span>resultItems</span><span>.</span></span><span>slice</span><span><span>(</span><span>begin_index</span><span>, </span><span>end_index</span><span>).</span></span><span>map</span><span>(</span><span>function</span><span><span>(</span><span>result</span><span>) {</span></span><span>return</span><span><span> </span><span>result</span><span>.</span></span><span>item</span><span>}).</span><span>join</span><span>(</span><span>''</span><span>);</span></div></div><div><div><div>207</div></div><div>
</div></div><div><div><div>208</div></div><div><span><span>    </span></span><span>start_page</span><span> </span><span>=</span><span><span> </span><span>Math</span><span>.</span></span><span>max</span><span>(</span><span>0</span><span><span>, </span><span>total_pages</span><span> </span></span><span>-</span><span><span> </span><span>max_page_on_show</span><span>);</span></span></div></div><div><div><div>209</div></div><div><span><span>    </span></span><span>end_page</span><span> </span><span>=</span><span><span> </span><span>start_page</span><span> </span></span><span>+</span><span><span> </span><span>Math</span><span>.</span></span><span>min</span><span><span>(</span><span>total_pages</span><span>, </span><span>max_page_on_show</span><span>);</span></span></div></div><div><div><div>210</div></div><div><span>    </span><span>var</span><span><span> </span><span>pageContent</span><span> </span></span><span>=</span><span> </span><span>'&lt;div class="#search-pagination"&gt;'</span><span>;</span></div></div><div><div><div>211</div></div><div><span><span>    </span></span><span>pageContent</span><span> </span><span>+=</span><span> </span><span>'&lt;div class="#search-pagination pagination"&gt;'</span><span>;</span></div></div><div><div><div>212</div></div><div><span><span>    </span></span><span>pageContent</span><span> </span><span>+=</span><span> </span><span>'&lt;ul&gt;'</span><span>;</span></div></div><div><div><div>213</div></div><div><span>    </span><span>if</span><span><span> (</span><span>total_pages</span><span> </span></span><span>&gt;</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>214</div></div><div><span>      </span><span>// add prev page arrow, when no prev page not selectable</span></div></div><div><div><div>215</div></div><div><span><span>      </span></span><span>pageContent</span><span> </span><span>+=</span><span> </span><span>addPrevPage</span><span><span>(</span><span>current_page</span><span>);</span></span></div></div><div><div><div>216</div></div><div><span>      </span><span>for</span><span> (</span><span>var</span><span><span> </span><span>i</span><span> </span></span><span>=</span><span><span> </span><span>start_page</span><span>; </span><span>i</span><span> </span></span><span>&lt;</span><span><span> </span><span>end_page</span><span>; </span><span>i</span><span> </span></span><span>+=</span><span> </span><span>1</span><span>) {</span></div></div><div><div><div>217</div></div><div><span><span>        </span></span><span>pageContent</span><span> </span><span>+=</span><span> </span><span>addPage</span><span><span>(</span><span>i</span><span>, </span><span>current_page</span><span>);</span></span></div></div><div><div><div>218</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>219</div></div><div><span>      </span><span>// add next page arrow, when no next page not selectable</span></div></div><div><div><div>220</div></div><div><span><span>      </span></span><span>pageContent</span><span> </span><span>+=</span><span> </span><span>addNextPage</span><span><span>(</span><span>current_page</span><span>);</span></span></div></div><div><div><div>221</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>222</div></div><div><span><span>    </span></span><span>pageContent</span><span> </span><span>+=</span><span> </span><span>'&lt;/ul&gt;'</span><span>;</span></div></div><div><div><div>223</div></div><div><span><span>    </span></span><span>pageContent</span><span> </span><span>+=</span><span> </span><span>'&lt;/div&gt;'</span><span>;</span></div></div><div><div><div>224</div></div><div><span><span>    </span></span><span>pageContent</span><span> </span><span>+=</span><span> </span><span>'&lt;/div&gt;'</span><span>;</span></div></div><div><div><div>225</div></div><div><span><span>    </span></span><span>paginationContent</span><span>.</span><span>innerHTML</span><span> </span><span>=</span><span><span> </span><span>pageContent</span><span>;</span></span></div></div><div><div><div>226</div></div><div><span>    </span><span>addPaginationEvents</span><span><span>(</span><span>start_page</span><span>, </span><span>end_page</span><span>);</span></span></div></div><div><div><div>227</div></div><div><span><span>    </span></span><span>resultContent</span><span>.</span><span>scrollTop</span><span> </span><span>=</span><span> </span><span>0</span><span>;  </span><span>// scroll to top</span></div></div><div><div><div>228</div></div><div><span><span>    </span></span><span>window</span><span>.</span><span>pjax</span><span> </span><span>&amp;&amp;</span><span><span> </span><span>window</span><span>.</span></span><span>pjax</span><span>.</span><span>refresh</span><span><span>(</span><span>resultContent</span><span>);</span></span></div></div><div><div><div>229</div></div><div><span><span>  </span></span><span>};</span></div></div><div><div><div>230</div></div><div>
</div></div><div><div><div>231</div></div><div>
</div></div><div><div><div>232</div></div><div>
</div></div><div><div><div>233</div></div><div><span>  </span><span>const</span><span> </span><span>inputEventFunction</span><span> </span><span>=</span><span> </span><span>function</span><span>() {</span></div></div><div><div><div>234</div></div><div><span>    </span><span>if</span><span> (</span><span>!</span><span><span>isFetched</span><span>) {</span></span></div></div><div><div><div>235</div></div><div><span><span>      </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>"Data not fetched."</span><span>);</span></div></div><div><div><div>236</div></div><div><span>      </span><span>return</span><span>;</span></div></div><div><div><div>237</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>238</div></div><div>
</div></div><div><div><div>239</div></div><div><span>    </span><span>var</span><span><span> </span><span>searchText</span><span> </span></span><span>=</span><span><span> </span><span>input</span><span>.</span></span><span>value</span><span>.</span><span>trim</span><span>().</span><span>toLowerCase</span><span>();</span></div></div><div><div><div>240</div></div><div><span>    </span><span>var</span><span><span> </span><span>keywords</span><span> </span></span><span>=</span><span><span> </span><span>searchText</span><span>.</span></span><span>split</span><span>(</span><span>/</span><span><span>[-</span><span>\s</span><span>]</span></span><span><span>+</span><span>/</span></span><span>);</span></div></div><div><div><div>241</div></div><div>
</div></div><div><div><div>242</div></div><div><span>    </span><span>if</span><span><span> (</span><span>keywords</span><span>.</span></span><span>length</span><span> </span><span>&gt;</span><span> </span><span>1</span><span>) {</span></div></div><div><div><div>243</div></div><div><span><span>      </span></span><span>keywords</span><span>.</span><span>push</span><span><span>(</span><span>searchText</span><span>);</span></span></div></div><div><div><div>244</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>245</div></div><div>
</div></div><div><div><div>246</div></div><div><span><span>    </span></span><span>resultItems</span><span> </span><span>=</span><span> [];</span></div></div><div><div><div>247</div></div><div><span>    </span><span>if</span><span><span> (</span><span>searchText</span><span>.</span></span><span>length</span><span> </span><span>&gt;</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>248</div></div><div><span>      </span><span>// Perform local searching</span></div></div><div><div><div>249</div></div><div><span><span>      </span></span><span>datas</span><span>.</span><span>forEach</span><span>(</span><span>function</span><span><span>(</span><span>index</span><span>) {</span></span></div></div><div><div><div>250</div></div><div>
</div></div><div><div><div>251</div></div><div><span>        </span><span>var</span><span><span> </span><span>categories</span><span> </span></span><span>=</span><span><span> </span><span>index</span><span>.</span></span><span>categories</span><span><span>, </span><span>title</span></span><span>=</span><span><span>index</span><span>.</span></span><span>title</span><span><span>, </span><span>content</span></span><span>=</span><span><span>index</span><span>.</span></span><span>content</span><span><span>, </span><span>url</span></span><span>=</span><span><span>index</span><span>.</span></span><span>url</span><span>;</span></div></div><div><div><div>252</div></div><div><span>        </span><span>var</span><span><span> </span><span>titleInLowerCase</span><span> </span></span><span>=</span><span><span> </span><span>title</span><span>.</span></span><span>toLowerCase</span><span>();</span></div></div><div><div><div>253</div></div><div><span>        </span><span>var</span><span><span> </span><span>contentInLowerCase</span><span> </span></span><span>=</span><span><span> </span><span>content</span><span>.</span></span><span>toLowerCase</span><span>();</span></div></div><div><div><div>254</div></div><div><span>        </span><span>var</span><span><span> </span><span>indexOfTitle</span><span> </span></span><span>=</span><span> [];</span></div></div><div><div><div>255</div></div><div><span>        </span><span>var</span><span><span> </span><span>indexOfContent</span><span> </span></span><span>=</span><span> [];</span></div></div><div><div><div>256</div></div><div><span>        </span><span>var</span><span><span> </span><span>searchTextCount</span><span> </span></span><span>=</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>257</div></div><div><span><span>        </span></span><span>keywords</span><span>.</span><span>forEach</span><span>( </span><span>function</span><span><span>(</span><span>keyword</span><span>) {</span></span></div></div><div><div><div>258</div></div><div><span><span>          </span></span><span>indexOfTitle</span><span> </span><span>=</span><span><span> </span><span>indexOfTitle</span><span>.</span></span><span>concat</span><span>(</span><span>getIndexByWord</span><span><span>(</span><span>keyword</span><span>, </span><span>titleInLowerCase</span><span>, </span></span><span>false</span><span>));</span></div></div><div><div><div>259</div></div><div><span><span>          </span></span><span>indexOfContent</span><span> </span><span>=</span><span><span> </span><span>indexOfContent</span><span>.</span></span><span>concat</span><span>(</span><span>getIndexByWord</span><span><span>(</span><span>keyword</span><span>, </span><span>contentInLowerCase</span><span>, </span></span><span>false</span><span>));</span></div></div><div><div><div>260</div></div><div><span><span>        </span></span><span>});</span></div></div><div><div><div>261</div></div><div>
</div></div><div><div><div>262</div></div><div>
</div></div><div><div><div>263</div></div><div><span>        </span><span>// Show search results</span></div></div><div><div><div>264</div></div><div><span>        </span><span>if</span><span><span> (</span><span>indexOfTitle</span><span>.</span></span><span>length</span><span> </span><span>&gt;</span><span> </span><span>0</span><span> </span><span>||</span><span><span> </span><span>indexOfContent</span><span>.</span></span><span>length</span><span> </span><span>&gt;</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>265</div></div><div><span>          </span><span>var</span><span><span> </span><span>hitCount</span><span> </span></span><span>=</span><span><span> </span><span>indexOfTitle</span><span>.</span></span><span>length</span><span> </span><span>+</span><span><span> </span><span>indexOfContent</span><span>.</span></span><span>length</span><span>;</span></div></div><div><div><div>266</div></div><div><span>          </span><span>// Sort index by position of keyword</span></div></div><div><div><div>267</div></div><div><span><span>          </span></span><span>[</span><span>indexOfTitle</span><span>, </span><span>indexOfContent</span><span>].</span><span>forEach</span><span>(</span><span>function</span><span><span>(</span><span>index</span><span>)  {</span></span></div></div><div><div><div>268</div></div><div><span><span>            </span></span><span>index</span><span>.</span><span>sort</span><span>(</span><span>function</span><span><span>(</span><span>itemLeft</span><span>, </span><span>itemRight</span><span>)  {</span></span></div></div><div><div><div>269</div></div><div><span>              </span><span>if</span><span><span> (</span><span>itemRight</span><span>.</span></span><span>position</span><span> </span><span>!==</span><span><span> </span><span>itemLeft</span><span>.</span></span><span>position</span><span>) {</span></div></div><div><div><div>270</div></div><div><span>                </span><span>return</span><span><span> </span><span>itemRight</span><span>.</span></span><span>position</span><span> </span><span>-</span><span><span> </span><span>itemLeft</span><span>.</span></span><span>position</span><span>;</span></div></div><div><div><div>271</div></div><div><span><span>              </span></span><span>}</span></div></div><div><div><div>272</div></div><div><span>              </span><span>return</span><span><span> </span><span>itemLeft</span><span>.</span></span><span>word</span><span>.</span><span>length</span><span> </span><span>-</span><span><span> </span><span>item</span><span>.</span></span><span>word</span><span>.</span><span>length</span><span>;</span></div></div><div><div><div>273</div></div><div><span><span>            </span></span><span>});</span></div></div><div><div><div>274</div></div><div><span><span>          </span></span><span>});</span></div></div><div><div><div>275</div></div><div>
</div></div><div><div><div>276</div></div><div><span>          </span><span>var</span><span><span> </span><span>slicesOfTitle</span><span> </span></span><span>=</span><span> [];</span></div></div><div><div><div>277</div></div><div><span>          </span><span>if</span><span><span> (</span><span>indexOfTitle</span><span>.</span></span><span>length</span><span> </span><span>!==</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>278</div></div><div><span>            </span><span>var</span><span><span> </span><span>tmp</span><span> </span></span><span>=</span><span> </span><span>mergeIntoSlice</span><span>(</span><span>0</span><span><span>, </span><span>title</span><span>.</span></span><span>length</span><span><span>, </span><span>indexOfTitle</span><span>, </span><span>searchText</span><span>);</span></span></div></div><div><div><div>279</div></div><div><span><span>            </span></span><span>searchTextCount</span><span> </span><span>+=</span><span><span> </span><span>tmp</span><span>.</span></span><span>searchTextCountInSlice</span><span>;</span></div></div><div><div><div>280</div></div><div><span><span>            </span></span><span>slicesOfTitle</span><span>.</span><span>push</span><span><span>(</span><span>tmp</span><span>);</span></span></div></div><div><div><div>281</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>282</div></div><div>
</div></div><div><div><div>283</div></div><div><span>          </span><span>var</span><span><span> </span><span>slicesOfContent</span><span> </span></span><span>=</span><span> [];</span></div></div><div><div><div>284</div></div><div><span>          </span><span>while</span><span><span> (</span><span>indexOfContent</span><span>.</span></span><span>length</span><span> </span><span>!==</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>285</div></div><div><span>            </span><span>var</span><span><span> </span><span>item</span><span> </span></span><span>=</span><span><span> </span><span>indexOfContent</span><span>[</span><span>indexOfContent</span><span>.</span></span><span>length</span><span> </span><span>-</span><span> </span><span>1</span><span>];</span></div></div><div><div><div>286</div></div><div><span>            </span><span>var</span><span><span> </span><span>position</span><span> </span></span><span>=</span><span><span> </span><span>item</span><span>.</span></span><span>position</span><span>;</span></div></div><div><div><div>287</div></div><div><span>            </span><span>var</span><span><span> </span><span>word</span><span> </span></span><span>=</span><span><span> </span><span>item</span><span>.</span></span><span>word</span><span>;</span></div></div><div><div><div>288</div></div><div><span>            </span><span>// Cut out 100 characters</span></div></div><div><div><div>289</div></div><div><span>            </span><span>var</span><span><span> </span><span>start</span><span> </span></span><span>=</span><span><span> </span><span>position</span><span> </span></span><span>-</span><span> </span><span>20</span><span>;</span></div></div><div><div><div>290</div></div><div><span>            </span><span>var</span><span><span> </span><span>end</span><span> </span></span><span>=</span><span><span> </span><span>position</span><span> </span></span><span>+</span><span> </span><span>30</span><span>;</span></div></div><div><div><div>291</div></div><div><span>            </span><span>if</span><span><span> (</span><span>start</span><span> </span></span><span>&lt;</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>292</div></div><div><span><span>              </span></span><span>start</span><span> </span><span>=</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>293</div></div><div><span><span>            </span></span><span>}</span></div></div><div><div><div>294</div></div><div><span>            </span><span>if</span><span><span> (</span><span>end</span><span> </span></span><span>&lt;</span><span><span> </span><span>position</span><span> </span></span><span>+</span><span><span> </span><span>word</span><span>.</span></span><span>length</span><span>) {</span></div></div><div><div><div>295</div></div><div><span><span>              </span></span><span>end</span><span> </span><span>=</span><span><span> </span><span>position</span><span> </span></span><span>+</span><span><span> </span><span>word</span><span>.</span></span><span>length</span><span>;</span></div></div><div><div><div>296</div></div><div><span><span>            </span></span><span>}</span></div></div><div><div><div>297</div></div><div><span>            </span><span>if</span><span><span> (</span><span>end</span><span> </span></span><span>&gt;</span><span><span> </span><span>content</span><span>.</span></span><span>length</span><span>) {</span></div></div><div><div><div>298</div></div><div><span><span>              </span></span><span>end</span><span> </span><span>=</span><span><span> </span><span>content</span><span>.</span></span><span>length</span><span>;</span></div></div><div><div><div>299</div></div><div><span><span>            </span></span><span>}</span></div></div><div><div><div>300</div></div><div><span>            </span><span>var</span><span><span> </span><span>tmp</span><span> </span></span><span>=</span><span> </span><span>mergeIntoSlice</span><span><span>(</span><span>start</span><span>, </span><span>end</span><span>, </span><span>indexOfContent</span><span>, </span><span>searchText</span><span>);</span></span></div></div><div><div><div>301</div></div><div><span><span>            </span></span><span>searchTextCount</span><span> </span><span>+=</span><span><span> </span><span>tmp</span><span>.</span></span><span>searchTextCountInSlice</span><span>;</span></div></div><div><div><div>302</div></div><div><span><span>            </span></span><span>slicesOfContent</span><span>.</span><span>push</span><span><span>(</span><span>tmp</span><span>);</span></span></div></div><div><div><div>303</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>304</div></div><div>
</div></div><div><div><div>305</div></div><div>
</div></div><div><div><div>306</div></div><div><span>          </span><span>// Sort slices in content by search text's count and hits' count</span></div></div><div><div><div>307</div></div><div><span><span>          </span></span><span>slicesOfContent</span><span>.</span><span>sort</span><span>( </span><span>function</span><span><span>(</span><span>sliceLeft</span><span>, </span><span>sliceRight</span><span>) {</span></span></div></div><div><div><div>308</div></div><div><span>            </span><span>if</span><span><span> (</span><span>sliceLeft</span><span>.</span></span><span>searchTextCount</span><span> </span><span>!==</span><span><span> </span><span>sliceRight</span><span>.</span></span><span>searchTextCount</span><span>) {</span></div></div><div><div><div>309</div></div><div><span>              </span><span>return</span><span><span> </span><span>sliceRight</span><span>.</span></span><span>searchTextCount</span><span> </span><span>-</span><span><span> </span><span>sliceLeft</span><span>.</span></span><span>searchTextCount</span><span>;</span></div></div><div><div><div>310</div></div><div><span><span>            </span></span><span>} </span><span>else</span><span> </span><span>if</span><span><span> (</span><span>sliceLeft</span><span>.</span></span><span>hits</span><span>.</span><span>length</span><span> </span><span>!==</span><span><span> </span><span>sliceRight</span><span>.</span></span><span>hits</span><span>.</span><span>length</span><span>) {</span></div></div><div><div><div>311</div></div><div><span>              </span><span>return</span><span><span> </span><span>sliceRight</span><span>.</span></span><span>hits</span><span>.</span><span>length</span><span> </span><span>-</span><span><span> </span><span>sliceLeft</span><span>.</span></span><span>hits</span><span>.</span><span>length</span><span>;</span></div></div><div><div><div>312</div></div><div><span><span>            </span></span><span>}</span></div></div><div><div><div>313</div></div><div><span>            </span><span>return</span><span><span> </span><span>sliceLeft</span><span>.</span></span><span>start</span><span> </span><span>-</span><span><span> </span><span>sliceRight</span><span>.</span></span><span>start</span><span>;</span></div></div><div><div><div>314</div></div><div><span><span>          </span></span><span>});</span></div></div><div><div><div>315</div></div><div>
</div></div><div><div><div>316</div></div><div><span>          </span><span>// Select top N slices in content</span></div></div><div><div><div>317</div></div><div><span>          </span><span>var</span><span><span> </span><span>upperBound</span><span> </span></span><span>=</span><span> </span><span>parseInt</span><span>(</span><span>CONFIG</span><span>.</span><span>localSearch</span><span>.</span><span>pageSize</span><span>, </span><span>10</span><span>);</span></div></div><div><div><div>318</div></div><div><span>          </span><span>if</span><span><span> (</span><span>upperBound</span><span> </span></span><span>&gt;=</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>319</div></div><div><span><span>            </span></span><span>slicesOfContent</span><span> </span><span>=</span><span><span> </span><span>slicesOfContent</span><span>.</span></span><span>slice</span><span>(</span><span>0</span><span><span>, </span><span>upperBound</span><span>);</span></span></div></div><div><div><div>320</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>321</div></div><div>
</div></div><div><div><div>322</div></div><div>
</div></div><div><div><div>323</div></div><div><span>          </span><span>var</span><span><span> </span><span>resultItem</span><span> </span></span><span>=</span><span> </span><span>''</span><span>;</span></div></div><div><div><div>324</div></div><div><span><span>          </span></span><span>resultItem</span><span> </span><span>+=</span><span> </span><span>'&lt;div class="#search-hits item"&gt;'</span><span>;</span></div></div><div><div><div>325</div></div><div><span>          </span><span>// resultItem += '&lt;div class="#search-hits"&gt;';</span></div></div><div><div><div>326</div></div><div><span>          </span><span>// resultItem += '&lt;ol class="item"&gt;'</span></div></div><div><div><div>327</div></div><div><span><span>          </span></span><span>resultItem</span><span> </span><span>+=</span><span> </span><span>'&lt;li&gt;'</span></div></div><div><div><div>328</div></div><div><span>          </span><span>// resultItem += '&lt;li&gt;';</span></div></div><div><div><div>329</div></div><div><span>          </span><span>var</span><span><span> </span><span>cats</span><span> </span></span><span>=</span><span><span> </span><span>categories</span><span> </span></span><span>!==</span><span> </span><span>undefined</span><span> </span><span>?</span><span> </span><span>'&lt;span&gt;'</span><span> </span><span>+</span><span><span> </span><span>categories</span><span>.</span></span><span>join</span><span>(</span><span>'&lt;i class="ic i-angle-right"&gt;&lt;/i&gt;'</span><span>) </span><span>+</span><span> </span><span>'&lt;/span&gt;'</span><span> </span><span>:</span><span> </span><span>'&lt;span&gt;No categories&lt;/span&gt;'</span><span>;</span></div></div><div><div><div>330</div></div><div><span><span>          </span></span><span>resultItem</span><span> </span><span>+=</span><span> </span><span>'&lt;a href="'</span><span>+</span><span>url</span><span>+</span><span>'"&gt;'</span><span> </span><span>+</span><span><span> </span><span>cats</span><span>;</span></span></div></div><div><div><div>331</div></div><div><span>          </span><span>if</span><span><span> (</span><span>slicesOfTitle</span><span>.</span></span><span>length</span><span> </span><span>!==</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>332</div></div><div><span>            </span><span>// resultItem += '&lt;li&gt;&lt;a href="'+url}"&gt;'+highlightKeyword(title, slicesOfTitle[0])}&lt;/a&gt;';</span></div></div><div><div><div>333</div></div><div><span><span>            </span></span><span>resultItem</span><span> </span><span>+=</span><span> </span><span>'&lt;b&gt;'</span><span>+</span><span>highlightKeyword</span><span><span>(</span><span>title</span><span>, </span><span>slicesOfTitle</span><span>[</span></span><span>0</span><span>])</span><span>+</span><span>'&lt;/b&gt;&lt;br&gt;'</span><span>;</span></div></div><div><div><div>334</div></div><div><span><span>          </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>335</div></div><div><span>            </span><span>// resultItem += '&lt;li&gt;&lt;a href="'+url}"&gt;'+title}&lt;/a&gt;';</span></div></div><div><div><div>336</div></div><div><span><span>            </span></span><span>resultItem</span><span> </span><span>+=</span><span> </span><span>'&lt;b&gt;'</span><span>+</span><span>title</span><span>+</span><span>'&lt;/b&gt;&lt;br&gt;'</span><span>;</span></div></div><div><div><div>337</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>338</div></div><div>
</div></div><div><div><div>339</div></div><div><span><span>          </span></span><span>slicesOfContent</span><span>.</span><span>forEach</span><span>(</span><span>function</span><span><span>(</span><span>slice</span><span>)  {</span></span></div></div><div><div><div>340</div></div><div><span>            </span><span>return</span><span><span> </span><span>resultItem</span><span> </span></span><span>+=</span><span> </span><span>'&lt;li class="#search-hits subitem"&gt;'</span><span>+</span><span>highlightKeyword</span><span><span>(</span><span>content</span><span>, </span><span>slice</span><span>)</span></span><span>+</span><span>' ...&lt;/li&gt;'</span><span>;</span></div></div><div><div><div>341</div></div><div><span><span>          </span></span><span>});</span></div></div><div><div><div>342</div></div><div><span>          </span><span>// resultItem += '&lt;/li&gt;';</span></div></div><div><div><div>343</div></div><div><span><span>          </span></span><span>resultItem</span><span> </span><span>+=</span><span> </span><span>'&lt;/a&gt;'</span><span>;</span></div></div><div><div><div>344</div></div><div><span><span>          </span></span><span>resultItem</span><span> </span><span>+=</span><span> </span><span>'&lt;/li&gt;'</span><span>;</span></div></div><div><div><div>345</div></div><div><span>          </span><span>// resultItem += '&lt;/ol&gt;';</span></div></div><div><div><div>346</div></div><div><span><span>          </span></span><span>resultItem</span><span> </span><span>+=</span><span> </span><span>'&lt;/div&gt;'</span><span>;</span></div></div><div><div><div>347</div></div><div><span><span>          </span></span><span>resultItems</span><span>.</span><span>push</span><span>({</span></div></div><div><div><div>348</div></div><div><span>            </span><span>item</span><span>:</span><span><span> </span><span>resultItem</span><span>,</span></span></div></div><div><div><div>349</div></div><div><span>            </span><span>id  </span><span>:</span><span><span> </span><span>resultItems</span><span>.</span></span><span>length</span><span>,</span></div></div><div><div><div>350</div></div><div><span>            </span><span>hitCount</span><span>:</span><span><span>hitCount</span><span>,</span></span></div></div><div><div><div>351</div></div><div><span>            </span><span>searchTextCount</span><span>:</span><span>searchTextCount</span></div></div><div><div><div>352</div></div><div><span><span>          </span></span><span>});</span></div></div><div><div><div>353</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>354</div></div><div><span><span>      </span></span><span>});</span></div></div><div><div><div>355</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>356</div></div><div>
</div></div><div><div><div>357</div></div><div><span>    </span><span>if</span><span><span> (</span><span>keywords</span><span>.</span></span><span>length</span><span> </span><span>===</span><span> </span><span>1</span><span> </span><span>&amp;&amp;</span><span><span> </span><span>keywords</span><span>[</span></span><span>0</span><span>] </span><span>===</span><span> </span><span>''</span><span>) {</span></div></div><div><div><div>358</div></div><div><span><span>      </span></span><span>resultContent</span><span>.</span><span>innerHTML</span><span> </span><span>=</span><span> </span><span>'&lt;div id="no-result"&gt;&lt;i&gt;&lt;/i&gt;&lt;/div&gt;'</span><span>;</span></div></div><div><div><div>359</div></div><div><span><span>    </span></span><span>} </span><span>else</span><span> </span><span>if</span><span><span> (</span><span>resultItems</span><span>.</span></span><span>length</span><span> </span><span>===</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>360</div></div><div><span><span>      </span></span><span>resultContent</span><span>.</span><span>innerHTML</span><span> </span><span>=</span><span> </span><span>'&lt;div id="no-result"&gt;&lt;i&gt;&lt;/i&gt;&lt;/div&gt;'</span><span>;</span></div></div><div><div><div>361</div></div><div><span><span>    </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>362</div></div><div><span><span>      </span></span><span>resultItems</span><span>.</span><span>sort</span><span>(</span><span>function</span><span><span>(</span><span>resultLeft</span><span>, </span><span>resultRight</span><span>)  {</span></span></div></div><div><div><div>363</div></div><div><span>        </span><span>if</span><span><span> (</span><span>resultLeft</span><span>.</span></span><span>searchTextCount</span><span> </span><span>!==</span><span><span> </span><span>resultRight</span><span>.</span></span><span>searchTextCount</span><span>) {</span></div></div><div><div><div>364</div></div><div><span>          </span><span>return</span><span><span> </span><span>resultRight</span><span>.</span></span><span>searchTextCount</span><span> </span><span>-</span><span><span> </span><span>resultLeft</span><span>.</span></span><span>searchTextCount</span><span>;</span></div></div><div><div><div>365</div></div><div><span><span>        </span></span><span>} </span><span>else</span><span> </span><span>if</span><span><span> (</span><span>resultLeft</span><span>.</span></span><span>hitCount</span><span> </span><span>!==</span><span><span> </span><span>resultRight</span><span>.</span></span><span>hitCount</span><span>) {</span></div></div><div><div><div>366</div></div><div><span>          </span><span>return</span><span><span> </span><span>resultRight</span><span>.</span></span><span>hitCount</span><span> </span><span>-</span><span><span> </span><span>resultLeft</span><span>.</span></span><span>hitCount</span><span>;</span></div></div><div><div><div>367</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>368</div></div><div><span>        </span><span>return</span><span><span> </span><span>resultRight</span><span>.</span></span><span>id</span><span> </span><span>-</span><span><span> </span><span>resultLeft</span><span>.</span></span><span>id</span><span>;</span></div></div><div><div><div>369</div></div><div><span><span>      </span></span><span>});</span></div></div><div><div><div>370</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>371</div></div><div>
</div></div><div><div><div>372</div></div><div><span>    </span><span>// Do pagination</span></div></div><div><div><div>373</div></div><div><span><span>    </span></span><span>total_pages</span><span> </span><span>=</span><span><span> </span><span>Math</span><span>.</span></span><span>ceil</span><span><span>(</span><span>resultItems</span><span>.</span></span><span>length</span><span> </span><span>/</span><span><span> </span><span>pageSize</span><span>);</span></span></div></div><div><div><div>374</div></div><div><span>    </span><span>pagination</span><span>();</span></div></div><div><div><div>375</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>376</div></div><div>
</div></div><div><div><div>377</div></div><div>
</div></div><div><div><div>378</div></div><div><span>  </span><span>const</span><span> </span><span>fetchData</span><span> </span><span>=</span><span> </span><span>function</span><span>() {</span></div></div><div><div><div>379</div></div><div><span>    </span><span>fetch</span><span>(</span><span>CONFIG</span><span>.</span><span>root</span><span> </span><span>+</span><span><span> </span><span>searchPath</span><span>)</span></span></div></div><div><div><div>380</div></div><div><span><span>      </span></span><span>.</span><span>then</span><span>(</span><span>function</span><span><span>(</span><span>response</span><span>) {</span></span><span>return</span><span><span> </span><span>response</span><span>.</span></span><span>text</span><span>()} )</span></div></div><div><div><div>381</div></div><div><span><span>      </span></span><span>.</span><span>then</span><span>( </span><span>function</span><span><span>(</span><span>res</span><span>) {</span></span></div></div><div><div><div>382</div></div><div><span>        </span><span>// Get the contents from search data</span></div></div><div><div><div>383</div></div><div><span><span>        </span></span><span>isFetched</span><span> </span><span>=</span><span> </span><span>true</span><span>;</span></div></div><div><div><div>384</div></div><div><span><span>        </span></span><span>datas</span><span> </span><span>=</span><span><span> </span><span>isXml</span><span> </span></span><span>?</span><span> [</span><span>new</span><span> </span><span>DOMParser</span><span>().</span><span>parseFromString</span><span><span>(</span><span>res</span><span>, </span></span><span>'text/xml'</span><span>).</span><span>querySelectorAll</span><span>(</span><span>'entry'</span><span>)].</span><span>map</span><span>( </span><span>function</span><span><span>(</span><span>element</span><span>) {</span></span></div></div><div><div><div>385</div></div><div><span>          </span><span>return</span><span> {</span></div></div><div><div><div>386</div></div><div><span>            </span><span>title  </span><span>:</span><span><span> </span><span>element</span><span>.</span></span><span>querySelector</span><span>(</span><span>'title'</span><span>).</span><span>textContent</span><span>,</span></div></div><div><div><div>387</div></div><div><span>            </span><span>content</span><span>:</span><span><span> </span><span>element</span><span>.</span></span><span>querySelector</span><span>(</span><span>'content'</span><span>).</span><span>textContent</span><span>,</span></div></div><div><div><div>388</div></div><div><span>            </span><span>url    </span><span>:</span><span><span> </span><span>element</span><span>.</span></span><span>querySelector</span><span>(</span><span>'url'</span><span>).</span><span>textContent</span></div></div><div><div><div>389</div></div><div><span><span>          </span></span><span>};</span></div></div><div><div><div>390</div></div><div><span><span>        </span></span><span>}) </span><span>:</span><span> </span><span>JSON</span><span>.</span><span>parse</span><span><span>(</span><span>res</span><span>);</span></span></div></div><div><div><div>391</div></div><div><span>        </span><span>// Only match articles with not empty titles</span></div></div><div><div><div>392</div></div><div><span><span>        </span></span><span>datas</span><span> </span><span>=</span><span><span> </span><span>datas</span><span>.</span></span><span>filter</span><span>(</span><span>function</span><span><span>(</span><span>data</span><span>) {</span></span><span>return</span><span><span> </span><span>data</span><span>.</span></span><span>title</span><span>} ).</span><span>map</span><span>( </span><span>function</span><span><span>(</span><span>data</span><span>) {</span></span></div></div><div><div><div>393</div></div><div><span><span>          </span></span><span>data</span><span>.</span><span>title</span><span> </span><span>=</span><span><span> </span><span>data</span><span>.</span></span><span>title</span><span>.</span><span>trim</span><span>();</span></div></div><div><div><div>394</div></div><div><span><span>          </span></span><span>data</span><span>.</span><span>content</span><span> </span><span>=</span><span><span> </span><span>data</span><span>.</span></span><span>content</span><span> </span><span>?</span><span><span> </span><span>data</span><span>.</span></span><span>content</span><span>.</span><span>trim</span><span>().</span><span>replace</span><span>(</span><span>/&lt;</span><span>[</span><span>^</span><span>&gt;]</span><span><span>+</span><span>&gt;/</span></span><span>g</span><span>, </span><span>''</span><span>) </span><span>:</span><span> </span><span>''</span><span>;</span></div></div><div><div><div>395</div></div><div><span><span>          </span></span><span>data</span><span>.</span><span>url</span><span> </span><span>=</span><span> </span><span>decodeURIComponent</span><span><span>(</span><span>data</span><span>.</span></span><span>url</span><span>).</span><span>replace</span><span>(</span><span><span>/</span><span>\/</span><span>{2,}</span><span>/</span></span><span>g</span><span>, </span><span>'/'</span><span>);</span></div></div><div><div><div>396</div></div><div><span>          </span><span>return</span><span><span> </span><span>data</span><span>;</span></span></div></div><div><div><div>397</div></div><div><span><span>        </span></span><span>});</span></div></div><div><div><div>398</div></div><div><span>        </span><span>// Remove loading animation</span></div></div><div><div><div>399</div></div><div><span><span>        </span></span><span>document</span><span>.</span><span>getElementById</span><span>(</span><span>'search-hits'</span><span>).</span><span>innerHTML</span><span> </span><span>=</span><span> </span><span>'&lt;i&gt;&lt;/i&gt;'</span><span>;</span></div></div><div><div><div>400</div></div><div><span>        </span><span>inputEventFunction</span><span>();</span></div></div><div><div><div>401</div></div><div><span><span>      </span></span><span>});</span></div></div><div><div><div>402</div></div><div><span><span>  </span></span><span>};</span></div></div><div><div><div>403</div></div><div>
</div></div><div><div><div>404</div></div><div><span>  </span><span>if</span><span> (</span><span>CONFIG</span><span>.</span><span>localSearch</span><span>.</span><span>preload</span><span>) {</span></div></div><div><div><div>405</div></div><div><span><span>    </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>"fetch data."</span><span>);</span></div></div><div><div><div>406</div></div><div><span>    </span><span>fetchData</span><span>();</span></div></div><div><div><div>407</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>408</div></div><div>
</div></div><div><div><div>409</div></div><div><span>  </span><span>if</span><span> (</span><span>CONFIG</span><span>.</span><span>localSearch</span><span>.</span><span>trigger</span><span> </span><span>===</span><span> </span><span>'auto'</span><span>) {</span></div></div><div><div><div>410</div></div><div><span><span>    </span></span><span>input</span><span>.</span><span>addEventListener</span><span>(</span><span>'input'</span><span><span>, </span><span>inputEventFunction</span><span>);</span></span></div></div><div><div><div>411</div></div><div><span><span>  </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>412</div></div><div><span><span>    </span></span><span>document</span><span>.</span><span>querySelector</span><span>(</span><span>'.search-icon'</span><span>).</span><span>addEventListener</span><span>(</span><span>'click'</span><span><span>, </span><span>inputEventFunction</span><span>);</span></span></div></div><div><div><div>413</div></div><div><span><span>    </span></span><span>input</span><span>.</span><span>addEventListener</span><span>(</span><span>'keypress'</span><span>,</span><span>function</span><span><span>(</span><span>event</span><span>) {</span></span></div></div><div><div><div>414</div></div><div><span>      </span><span>if</span><span><span> (</span><span>event</span><span>.</span></span><span>key</span><span> </span><span>===</span><span> </span><span>'Enter'</span><span>) {</span></div></div><div><div><div>415</div></div><div><span>        </span><span>inputEventFunction</span><span>();</span></div></div><div><div><div>416</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>417</div></div><div><span><span>    </span></span><span>});</span></div></div><div><div><div>418</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>419</div></div><div>
</div></div><div><div><div>420</div></div><div><span>  </span><span>// Handle and trigger popup window</span></div></div><div><div><div>421</div></div><div><span><span>  </span></span><span>document</span><span>.</span><span>querySelectorAll</span><span>(</span><span>'.popup-trigger'</span><span>).</span><span>forEach</span><span>( </span><span>function</span><span><span>(</span><span>element</span><span>) {</span></span></div></div><div><div><div>422</div></div><div><span><span>    </span></span><span>element</span><span>.</span><span>addEventListener</span><span>(</span><span>'click'</span><span>, </span><span>function</span><span>()  {</span></div></div><div><div><div>423</div></div><div><span><span>      </span></span><span>document</span><span>.</span><span>body</span><span>.</span><span>style</span><span>.</span><span>overflow</span><span> </span><span>=</span><span> </span><span>'hidden'</span><span>;</span></div></div><div><div><div>424</div></div><div><span><span>      </span></span><span>document</span><span>.</span><span>querySelector</span><span>(</span><span>'.search-pop-overlay'</span><span>).</span><span>classList</span><span>.</span><span>add</span><span>(</span><span>'search-active'</span><span>);</span></div></div><div><div><div>425</div></div><div><span><span>      </span></span><span>input</span><span>.</span><span>focus</span><span>();</span></div></div><div><div><div>426</div></div><div><span>      </span><span>if</span><span> (</span><span>!</span><span><span>isFetched</span><span>) </span></span><span>fetchData</span><span>();</span></div></div><div><div><div>427</div></div><div><span><span>    </span></span><span>});</span></div></div><div><div><div>428</div></div><div><span><span>  </span></span><span>});</span></div></div><div><div><div>429</div></div><div>
</div></div><div><div><div>430</div></div><div><span>  </span><span>// Handle and trigger popup window</span></div></div><div><div><div>431</div></div><div><span><span>  </span></span><span>$</span><span>.</span><span>each</span><span>(</span><span>'.search'</span><span>, </span><span>function</span><span><span>(</span><span>element</span><span>) {</span></span></div></div><div><div><div>432</div></div><div><span><span>    </span></span><span>element</span><span>.</span><span>addEventListener</span><span>(</span><span>'click'</span><span>, </span><span>function</span><span>() {</span></div></div><div><div><div>433</div></div><div><span><span>      </span></span><span>document</span><span>.</span><span>body</span><span>.</span><span>style</span><span>.</span><span>overflow</span><span> </span><span>=</span><span> </span><span>'hidden'</span><span>;</span></div></div><div><div><div>434</div></div><div><span>      </span><span>transition</span><span><span>(</span><span>siteSearch</span><span>, </span></span><span>'shrinkIn'</span><span>, </span><span>function</span><span>() {</span></div></div><div><div><div>435</div></div><div><span>          </span><span>$</span><span>(</span><span>'.search-input'</span><span>).</span><span>focus</span><span>();</span></div></div><div><div><div>436</div></div><div><span><span>        </span></span><span>}) </span><span>// transition.shrinkIn</span></div></div><div><div><div>437</div></div><div><span><span>    </span></span><span>});</span></div></div><div><div><div>438</div></div><div><span><span>  </span></span><span>});</span></div></div><div><div><div>439</div></div><div>
</div></div><div><div><div>440</div></div><div><span>  </span><span>// Monitor main search box</span></div></div><div><div><div>441</div></div><div><span>  </span><span>const</span><span> </span><span>onPopupClose</span><span> </span><span>=</span><span> </span><span>function</span><span>() {</span></div></div><div><div><div>442</div></div><div><span><span>    </span></span><span>document</span><span>.</span><span>body</span><span>.</span><span>style</span><span>.</span><span>overflow</span><span> </span><span>=</span><span> </span><span>''</span><span>;</span></div></div><div><div><div>443</div></div><div><span>    </span><span>transition</span><span><span>(</span><span>siteSearch</span><span>, </span></span><span>0</span><span>); </span><span>// "transition.shrinkOut"</span></div></div><div><div><div>444</div></div><div><span><span>  </span></span><span>};</span></div></div><div><div><div>445</div></div><div>
</div></div><div><div><div>446</div></div><div><span><span>  </span></span><span>siteSearch</span><span>.</span><span>addEventListener</span><span>(</span><span>'click'</span><span>, </span><span>function</span><span><span>(</span><span>event</span><span>) {</span></span></div></div><div><div><div>447</div></div><div><span>    </span><span>if</span><span><span> (</span><span>event</span><span>.</span></span><span>target</span><span> </span><span>===</span><span><span> </span><span>siteSearch</span><span>) {</span></span></div></div><div><div><div>448</div></div><div><span>      </span><span>onPopupClose</span><span>();</span></div></div><div><div><div>449</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>450</div></div><div><span><span>  </span></span><span>});</span></div></div><div><div><div>451</div></div><div>
</div></div><div><div><div>452</div></div><div><span>  </span><span>$</span><span>(</span><span>'.close-btn'</span><span>).</span><span>addEventListener</span><span>(</span><span>'click'</span><span><span>, </span><span>onPopupClose</span><span>);</span></span></div></div><div><div><div>453</div></div><div><span><span>  </span></span><span>window</span><span>.</span><span>addEventListener</span><span>(</span><span>'pjax:success'</span><span><span>, </span><span>onPopupClose</span><span>);</span></span></div></div><div><div><div>454</div></div><div><span><span>  </span></span><span>window</span><span>.</span><span>addEventListener</span><span>(</span><span>'keyup'</span><span>, </span><span>function</span><span><span>(</span><span>event</span><span>) {</span></span></div></div><div><div><div>455</div></div><div><span>    </span><span>if</span><span><span> (</span><span>event</span><span>.</span></span><span>key</span><span> </span><span>===</span><span> </span><span>'Escape'</span><span>) {</span></div></div><div><div><div>456</div></div><div><span>      </span><span>onPopupClose</span><span>();</span></div></div><div><div><div>457</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>458</div></div><div><span><span>  </span></span><span>});</span></div></div><div><div><div>459</div></div><div>
</div></div><div><div><div>460</div></div><div><span>};</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>修改 script.js<a href="#修改-scriptjs"><span>#</span></a></h3><p><code>shoka/scripts/generaters/script.js</code> 中主要是读取配置，添加如下代码</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>.........</span><span>..  </span><span>// 省略若干代码</span></div></div><div><div><div>2</div></div><div><span>if</span><span><span>(</span><span>config</span><span>.</span></span><span>algolia</span><span>) {</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>siteConfig</span><span>.</span><span>search</span><span> </span><span>=</span><span> {</span></div></div><div><div><div>4</div></div><div><span>      </span><span>appID    </span><span>:</span><span><span> </span><span>config</span><span>.</span></span><span>algolia</span><span>.</span><span>appId</span><span>,</span></div></div><div><div><div>5</div></div><div><span>      </span><span>apiKey   </span><span>:</span><span><span> </span><span>config</span><span>.</span></span><span>algolia</span><span>.</span><span>apiKey</span><span>,</span></div></div><div><div><div>6</div></div><div><span>      </span><span>indexName</span><span>:</span><span><span> </span><span>config</span><span>.</span></span><span>algolia</span><span>.</span><span>indexName</span><span>,</span></div></div><div><div><div>7</div></div><div><span>      </span><span>hits     </span><span>:</span><span><span> </span><span>theme</span><span>.</span></span><span>search</span><span>.</span><span>hits</span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>10</div></div><div><span>// 以下为需要添加的代码</span></div></div><div><div><div>11</div></div><div><span>if</span><span><span>(</span><span>config</span><span>.</span></span><span>search</span><span>) {</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>siteConfig</span><span>.</span><span>localSearch</span><span> </span><span>=</span><span> {</span></div></div><div><div><div>13</div></div><div><span>      </span><span>enable</span><span>:</span><span><span> </span><span>config</span><span>.</span></span><span>search</span><span>.</span><span>enable</span><span>,</span></div></div><div><div><div>14</div></div><div><span>      </span><span>path</span><span>:</span><span><span> </span><span>config</span><span>.</span></span><span>search</span><span>.</span><span>path</span><span>,</span></div></div><div><div><div>15</div></div><div><span>      </span><span>field</span><span>:</span><span><span> </span><span>config</span><span>.</span></span><span>search</span><span>.</span><span>field</span><span>,</span></div></div><div><div><div>16</div></div><div><span>      </span><span>format</span><span>:</span><span><span> </span><span>config</span><span>.</span></span><span>search</span><span>.</span><span>format</span><span>,</span></div></div><div><div><div>17</div></div><div><span>      </span><span>limit</span><span>:</span><span><span> </span><span>config</span><span>.</span></span><span>search</span><span>.</span><span>limit</span><span>,</span></div></div><div><div><div>18</div></div><div><span>      </span><span>content</span><span>:</span><span><span> </span><span>config</span><span>.</span></span><span>search</span><span>.</span><span>content</span><span>,</span></div></div><div><div><div>19</div></div><div><span>      </span><span>unescape</span><span>:</span><span><span> </span><span>config</span><span>.</span></span><span>search</span><span>.</span><span>unescape</span><span>,</span></div></div><div><div><div>20</div></div><div><span>      </span><span>preload</span><span>:</span><span><span>  </span><span>config</span><span>.</span></span><span>search</span><span>.</span><span>preload</span><span>,</span></div></div><div><div><div>21</div></div><div><span>      </span><span>trigger</span><span>:</span><span><span> </span><span>config</span><span>.</span></span><span>search</span><span>.</span><span>trigger</span><span>,</span></div></div><div><div><div>22</div></div><div><span>      </span><span>pageSize</span><span>:</span><span><span> </span><span>config</span><span>.</span></span><span>search</span><span>.</span><span>pageSize</span></div></div><div><div><div>23</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>24</div></div><div><span><span>  </span></span><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>修改 pjax.js<a href="#修改-pjaxjs"><span>#</span></a></h3><p><code>shoka/source/js/_app/pjax.js</code> 中是启动搜索功能的部分，这里在两个配置都有的情况下默认使用本地搜索而不是 <code>Algolia</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>if</span><span> (</span><span>CONFIG</span><span>.</span><span>localSearch</span><span> </span><span>!=</span><span> </span><span>null</span><span>) {</span></div></div><div><div><div>2</div></div><div><span>    </span><span>localSearch</span><span><span>(</span><span>pjax</span><span>)</span></span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>}</span><span>else</span><span> </span><span>if</span><span>(</span><span>CONFIG</span><span>.</span><span>search</span><span> </span><span>!=</span><span> </span><span>null</span><span>) {</span></div></div><div><div><div>4</div></div><div><span>    </span><span>algoliaSearch</span><span><span>(</span><span>pjax</span><span>)</span></span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>添加配置<a href="#添加配置"><span>#</span></a></h3><p>最后在 hexo 配置（最外层的 <code>_config.yml</code> ）中添加 <code>search</code> 配置，就大功告成了！</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>search</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>3</div></div><div><span>  </span><span>path</span><span>: </span><span>search.json</span><span> </span><span># search.xml</span></div></div><div><div><div>4</div></div><div><span>  </span><span>field</span><span>: </span><span>post</span></div></div><div><div><div>5</div></div><div><span>  </span><span>format</span><span>: </span><span>html</span></div></div><div><div><div>6</div></div><div><span>  </span><span>limit</span><span>: </span><span>10000</span></div></div><div><div><div>7</div></div><div><span>  </span><span>content</span><span>: </span><span>true</span></div></div><div><div><div>8</div></div><div><span>  </span><span>unescape</span><span>: </span><span>true</span></div></div><div><div><div>9</div></div><div><span>  </span><span>preload</span><span>:  </span><span>true</span></div></div><div><div><div>10</div></div><div><span>  </span><span>trigger</span><span>: </span><span>"auto"</span></div></div><div><div><div>11</div></div><div><span>  </span><span>pageSize</span><span>: </span><span>10</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>看下效果吧<a href="#看下效果吧"><span>#</span></a></h2><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/202405221725861.png" alt="image-20240522172507594" /><figcaption>image-20240522172507594</figcaption></figure><p></p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/e64ca3b2/</id>
      <title type="text">【工具】Typora安装使用</title>
      <published>2024-05-22T20:31:13.000Z</published>
      <updated>2024-05-22T20:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/e64ca3b2/"/>
      <summary type="text">如何安装和激活 Markdown 编辑器 Typora。首先，从官方下载最新版本的 Typora 并安装。接着，通过修改安装目录下的 LicenseIndex 文件中的特定代码，实现手动激活。为了优化使用体验，文章还提供了关闭每次启动时的激活弹窗和去除左下角“未激活”提示的方法，并提供了自定义样式的下载链接。</summary>
      <content type="html"><![CDATA[<section><h2>准备<a href="#准备"><span>#</span></a></h2><blockquote><p><a href="https://typora.ymzhxing.cn/index.html?bd_vid=11765516185414740389" target="_blank">Typora下载安装</a></p><p>版本：1.8.10</p></blockquote></section>
<section><h2>激活<a href="#激活"><span>#</span></a></h2><blockquote><p>Typora 手动激活，不用修改时间，不用补丁</p><p>下面是操作步骤：</p></blockquote><ol>
<li>
<p>下载最新版本的Typora安装</p>
</li>
<li>
<p>安装完后，进入typora的安装目录下的 <code>\resources\page-dist\static\js</code> 目录，找到 <code>LicenseIndex</code>开头的文件</p>
</li>
<li>
<p>用文本编辑器打开该文件，搜索<code>hasActivated="true"==e.hasActivated</code>并将其替换为
<code>hasActivated="true"=="true"</code></p>
<div><div><div></div><div>Important</div></div><div><p>（修改前，可将该文件备份一下，万一操作失误，可以进行恢复）</p></div></div>
</li>
<li>
<p>打开软件尽情使用吧！</p>
</li>
</ol><p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/202405241634156.png" alt="image-20240524163400032" /><figcaption>image-20240524163400032</figcaption></figure><p></p><ol>
<li>
<p>关闭软件每次启动时的已激活弹窗</p>
<p>继续在安装路径下找到<code>resources\page-dist\license.html</code>文件,依旧ctrl+F 定位到：<code>&lt;/body&gt;&lt;/html&gt;</code><strong>替换为</strong> <code>&lt;/body&gt;&lt;script&gt;window.οnlοad=function(){setTimeout(()=&gt;{window.close();},5);}&lt;/script&gt;&lt;/html&gt;</code></p>
</li>
</ol><p></p><figure><img src="https://raw.githubusercontent.com/wangbin-blog/pic-resources/main/2024/06/27092659761.png" alt="image-20240627092659701" /><figcaption>image-20240627092659701</figcaption></figure><p></p><ol>
<li>去除软件左下角“未激活”提示</li>
</ol><p>​	按照安装路径，找到 <code>resources\locales\zh-Hans.lproj\Panel.json</code>,文件中查找：<code>"UNREGISTERED":"未激活"</code><strong>替换为：</strong><code>"UNREGISTERED":" "</code></p><ol>
<li>安装自定义样式
<ul>
<li><a href="https://github.com/imageslr/mweb-themes" target="_blank">从Github下载</a></li>
</ul>
</li>
</ol><blockquote><p><strong>最后，重要提示：把自动更新一定要关闭，能用就不要升级，此方法再之后版本不一定能用，且用切珍惜</strong></p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/506e9c17/</id>
      <title type="text">【前端】高颜值登录页面（一键复制）</title>
      <published>2024-05-22T18:31:13.000Z</published>
      <updated>2024-05-22T18:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/506e9c17/"/>
      <summary type="text">登录页面是每一个项目不可缺少的页面，是一个应用的门面，首次进入看见的可能就是登录界面，做了这么久的前端，发现登录界面其实都大同小异，有时候没必要从头写，我写了几个自认为比较好看的uniapp登录界面记录一下，下次用到的话，可以直接复制过来，修改下就行了.只有静态页面，并未做逻辑上的东西，这样便于在此基础上做调整。</summary>
      <content type="html"><![CDATA[<blockquote><p>登录页面是每一个项目不可缺少的页面，是一个应用的门面，首次进入看见的可能就是登录界面，做了这么久的前端，发现登录界面其实都大同小异，有时候没必要从头写，我写了几个自认为比较好看的uniapp登录界面记录一下，下次用到的话，可以直接复制过来，修改下就行了。只有静态页面，并未做逻辑上的东西，这样便于在此基础上做调整。</p></blockquote>
<p><strong>先看效果：</strong></p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/202405221359689.png" alt="图片" /><figcaption>图片</figcaption></figure><p></p>
<p><strong>实际应用效果</strong></p>
<p></p><figure><img src="https://gcore.jsdelivr.net/gh/wangbin-blog/pic-resources@main/202405221400909.webp" alt="图片" /><figcaption>图片</figcaption></figure><p></p>

<p><strong>源码</strong></p>
<blockquote><p><strong>粉色登录界面（图一）：</strong></p></blockquote>
<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>template</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"content"</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"loginBox"</span><span>&gt;</span></div></div><div><div><div>4</div></div><div><span><span>      </span></span><span>&lt;</span><span>h3</span><span>&gt;登录&lt;/</span><span>h3</span><span>&gt;</span></div></div><div><div><div>5</div></div><div><span><span>      </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"inputBox"</span><span>&gt;</span></div></div><div><div><div>6</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"ipt"</span><span>&gt;</span></div></div><div><div><div>7</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"contact"</span><span> </span><span>size</span><span>=</span><span>"24"</span><span> </span><span>color</span><span>=</span><span>"rgb(247,120,172)"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>8</div></div><div><span><span>          </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"text"</span><span> </span><span>value</span><span>=</span><span>""</span><span> </span><span>placeholder</span><span>=</span><span>"请输入账号"</span><span>/&gt;</span></div></div><div><div><div>9</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>10</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"ipt"</span><span>&gt;</span></div></div><div><div><div>11</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"eye"</span><span> </span><span>size</span><span>=</span><span>"24"</span><span> </span><span>color</span><span>=</span><span>"rgb(247,120,172)"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>12</div></div><div><span><span>          </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"passsword"</span><span> </span><span>value</span><span>=</span><span>""</span><span> </span><span>placeholder</span><span>=</span><span>"请输入密码"</span><span>/&gt;</span></div></div><div><div><div>13</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>14</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"forgetPwd"</span><span>&gt;</span></div></div><div><div><div>15</div></div><div><span><span>          </span></span><span>&lt;</span><span>span</span><span>&gt;忘记密码&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>16</div></div><div><span><span>          </span></span><span>&lt;</span><span>span</span><span>&gt;没有账号，去注册&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>17</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>18</div></div><div><span><span>        </span></span><span>&lt;</span><span>button</span><span>&gt;登录&lt;/</span><span>button</span><span>&gt;</span></div></div><div><div><div>19</div></div><div><span><span>      </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>20</div></div><div><span><span>      </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"tipbox"</span><span>&gt;</span></div></div><div><div><div>21</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"txt"</span><span>&gt;</span></div></div><div><div><div>22</div></div><div><span><span>          </span></span><span>—— 其他账号登录 ——</span></div></div><div><div><div>23</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>24</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"otherUser"</span><span>&gt;</span></div></div><div><div><div>25</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"qq"</span><span> </span><span>size</span><span>=</span><span>"40"</span><span> </span><span>color</span><span>=</span><span>"rgb(66,157,250)"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>26</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"weixin"</span><span> </span><span>size</span><span>=</span><span>"40"</span><span> </span><span>color</span><span>=</span><span>"rgb(2,187,17)"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>27</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>28</div></div><div><span><span>      </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>29</div></div><div><span><span>    </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>30</div></div><div>
</div></div><div><div><div>31</div></div><div><span><span>    </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"tip"</span><span>&gt;</span></div></div><div><div><div>32</div></div><div><span><span>      </span></span><span>某某应用 2024</span></div></div><div><div><div>33</div></div><div><span><span>    </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>34</div></div><div><span><span>  </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>35</div></div><div><span>&lt;/</span><span>template</span><span>&gt;</span></div></div><div><div><div>36</div></div><div>
</div></div><div><div><div>37</div></div><div><span>&lt;</span><span>script</span><span>&gt;</span></div></div><div><div><div>38</div></div><div><span>  </span><span>export</span><span> </span><span>default</span><span> {</span></div></div><div><div><div>39</div></div><div><span>    </span><span>data</span><span>() {</span></div></div><div><div><div>40</div></div><div><span>      </span><span>return</span><span> {</span></div></div><div><div><div>41</div></div><div>
</div></div><div><div><div>42</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>43</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>44</div></div><div><span>    </span><span>onLoad</span><span>() {</span></div></div><div><div><div>45</div></div><div>
</div></div><div><div><div>46</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>47</div></div><div><span>    </span><span>methods</span><span>:</span><span> {</span></div></div><div><div><div>48</div></div><div>
</div></div><div><div><div>49</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>50</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>51</div></div><div><span>&lt;/</span><span>script</span><span>&gt;</span></div></div><div><div><div>52</div></div><div>
</div></div><div><div><div>53</div></div><div><span>&lt;</span><span>style</span><span> </span><span>scoped</span><span>&gt;</span></div></div><div><div><div>54</div></div><div><span>  </span><span>.content</span><span>{</span></div></div><div><div><div>55</div></div><div><span><span>    </span></span><span>height: </span><span><span>100</span><span>vh</span></span><span>;</span></div></div><div><div><div>56</div></div><div><span><span>    </span></span><span>background: </span><span>url</span><span>(</span><span>"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202005%2F10%2F20200510005139_JR8fL.jpeg&amp;refer=http%3A%2F%2Fc-ssl.duitang.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1714820289&amp;t=e835cde99a094cbd98f9c318f25160ec"</span><span><span>) </span><span>no-repeat</span><span>;</span></span></div></div><div><div><div>57</div></div><div><span><span>    </span></span><span>background-size: </span><span><span>100</span><span>%</span></span><span> </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>58</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>59</div></div><div><span>  </span><span>.loginBox</span><span>{</span></div></div><div><div><div>60</div></div><div><span><span>    </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>61</div></div><div><span><span>    </span></span><span>top: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>62</div></div><div><span><span>    </span></span><span>left: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>63</div></div><div><span><span>    </span></span><span>transform: </span><span>translate</span><span>(</span><span><span>-50</span><span>%</span></span><span>,</span><span><span>-60</span><span>%</span></span><span>);</span></div></div><div><div><div>64</div></div><div><span><span>    </span></span><span>width: </span><span><span>90</span><span>%</span></span><span>;</span></div></div><div><div><div>65</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>66</div></div><div><span><span>    </span></span><span>border-radius: </span><span>20</span><span>rpx;</span></div></div><div><div><div>67</div></div><div><span><span>    </span></span><span>padding: </span><span>60</span><span>rpx;</span></div></div><div><div><div>68</div></div><div><span><span>    </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>69</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>70</div></div><div><span>  </span><span>h3</span><span>{</span></div></div><div><div><div>71</div></div><div><span><span>    </span></span><span>color: </span><span>rgb</span><span>(</span><span>247</span><span>,</span><span>120</span><span>,</span><span>172</span><span>);</span></div></div><div><div><div>72</div></div><div><span><span>    </span></span><span>font-size: </span><span>40</span><span>rpx;</span></div></div><div><div><div>73</div></div><div><span><span>    </span></span><span>letter-spacing: </span><span>10</span><span>rpx;</span></div></div><div><div><div>74</div></div><div><span><span>    </span></span><span>margin-bottom: </span><span>40</span><span>rpx;</span></div></div><div><div><div>75</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>76</div></div><div><span>  </span><span>.inputBox</span><span>{</span></div></div><div><div><div>77</div></div><div>
</div></div><div><div><div>78</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>79</div></div><div><span>  </span><span>.ipt</span><span>{</span></div></div><div><div><div>80</div></div><div><span><span>    </span></span><span>height: </span><span>86</span><span>rpx;</span></div></div><div><div><div>81</div></div><div><span><span>    </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>82</div></div><div><span><span>    </span></span><span>justify-content: </span><span>flex-start</span><span>;</span></div></div><div><div><div>83</div></div><div><span><span>    </span></span><span>align-items: </span><span>center</span><span>;</span></div></div><div><div><div>84</div></div><div><span><span>    </span></span><span>margin-bottom: </span><span>20</span><span>rpx;</span></div></div><div><div><div>85</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>f5f5f5</span><span>;</span></div></div><div><div><div>86</div></div><div><span><span>    </span></span><span>border-radius: </span><span>10</span><span>rpx;</span></div></div><div><div><div>87</div></div><div><span><span>    </span></span><span>padding-left: </span><span>10</span><span>rpx;</span></div></div><div><div><div>88</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>89</div></div><div><span>  </span><span>.ipt</span><span> </span><span>input</span><span>{</span></div></div><div><div><div>90</div></div><div><span><span>    </span></span><span>margin-left: </span><span>20</span><span>rpx;</span></div></div><div><div><div>91</div></div><div><span><span>    </span></span><span>font-size: </span><span>28</span><span>rpx;</span></div></div><div><div><div>92</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>93</div></div><div><span>  </span><span>.ipt</span><span> </span><span>input</span><span>{</span></div></div><div><div><div>94</div></div><div><span><span>    </span></span><span>margin-left: </span><span>20</span><span>rpx;</span></div></div><div><div><div>95</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>96</div></div><div><span>  </span><span>.forgetPwd</span><span>{</span></div></div><div><div><div>97</div></div><div><span><span>    </span></span><span>font-size: </span><span>26</span><span>rpx;</span></div></div><div><div><div>98</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>b5b5b5</span><span>;</span></div></div><div><div><div>99</div></div><div><span><span>    </span></span><span>text-align: </span><span>end</span><span>;</span></div></div><div><div><div>100</div></div><div><span><span>    </span></span><span>padding:</span><span>0</span><span> </span><span>10</span><span>rpx;</span></div></div><div><div><div>101</div></div><div><span><span>    </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>102</div></div><div><span><span>    </span></span><span>justify-content: </span><span>space-between</span><span>;</span></div></div><div><div><div>103</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>104</div></div><div><span>  </span><span>button</span><span>{</span></div></div><div><div><div>105</div></div><div><span><span>    </span></span><span>margin-top: </span><span>20</span><span>rpx;</span></div></div><div><div><div>106</div></div><div><span><span>    </span></span><span>line-height: </span><span>85</span><span>rpx;</span></div></div><div><div><div>107</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>108</div></div><div><span><span>    </span></span><span>background: </span><span>linear-gradient</span><span><span>(to </span><span>right</span><span>,</span></span><span>rgb</span><span>(</span><span>255</span><span>, </span><span>170</span><span>, </span><span>127</span><span>),</span><span>rgb</span><span>(</span><span>247</span><span>,</span><span>120</span><span>,</span><span>172</span><span>));</span></div></div><div><div><div>109</div></div><div><span><span>    </span></span><span>border-radius: </span><span>40</span><span>rpx;</span></div></div><div><div><div>110</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>111</div></div><div><span><span>    </span></span><span>margin-top: </span><span>40</span><span>rpx;</span></div></div><div><div><div>112</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>113</div></div><div>
</div></div><div><div><div>114</div></div><div><span>  </span><span>.tip</span><span>{</span></div></div><div><div><div>115</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>116</div></div><div><span><span>    </span></span><span>font-size: </span><span>28</span><span>rpx;</span></div></div><div><div><div>117</div></div><div><span><span>    </span></span><span>position: </span><span>fixed</span><span>;</span></div></div><div><div><div>118</div></div><div><span><span>    </span></span><span>bottom: </span><span>50</span><span>rpx;</span></div></div><div><div><div>119</div></div><div><span><span>    </span></span><span>left: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>120</div></div><div><span><span>    </span></span><span>transform: </span><span>translate</span><span>(</span><span><span>-50</span><span>%</span></span><span>,</span><span><span>-50</span><span>%</span></span><span>);</span></div></div><div><div><div>121</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>f4f4f4</span><span>;</span></div></div><div><div><div>122</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>123</div></div><div><span>  </span><span>.tipbox</span><span> {</span></div></div><div><div><div>124</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>125</div></div><div><span><span>    </span></span><span>margin-top: </span><span>100</span><span>rpx;</span></div></div><div><div><div>126</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>127</div></div><div>
</div></div><div><div><div>128</div></div><div><span>  </span><span>.otherUser</span><span> {</span></div></div><div><div><div>129</div></div><div><span><span>    </span></span><span>margin-top: </span><span>30</span><span>rpx;</span></div></div><div><div><div>130</div></div><div><span><span>    </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>131</div></div><div><span><span>    </span></span><span>justify-content: </span><span>center</span><span>;</span></div></div><div><div><div>132</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>133</div></div><div>
</div></div><div><div><div>134</div></div><div><span>  </span><span>.txt</span><span> {</span></div></div><div><div><div>135</div></div><div><span><span>    </span></span><span>font-size: </span><span>28</span><span>rpx;</span></div></div><div><div><div>136</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>cbcbcb</span><span>;</span></div></div><div><div><div>137</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>138</div></div><div>
</div></div><div><div><div>139</div></div><div><span>  </span><span>.otherUser</span><span> </span><span>.uni-icons</span><span> {</span></div></div><div><div><div>140</div></div><div><span><span>    </span></span><span>margin-left: </span><span>20</span><span>rpx;</span></div></div><div><div><div>141</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>142</div></div><div><span>&lt;/</span><span>style</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<blockquote><p><strong>白色登录界面（图二）：</strong></p></blockquote>
<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>template</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"content"</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>&lt;</span><span>svg</span><span> </span><span>version</span><span>=</span><span>"1.1"</span><span> </span><span>xmlns</span><span>=</span><span>"http://www.w3.org/2000/svg"</span><span> </span><span>xmlns:xlink</span><span>=</span><span>"http://www.w3.org/1999/xlink"</span><span> </span><span>x</span><span>=</span><span>"0px"</span><span> </span><span>y</span><span>=</span><span>"0px"</span></div></div><div><div><div>4</div></div><div><span>      </span><span>width</span><span>=</span><span>"100%"</span><span> </span><span>height</span><span>=</span><span>"100%"</span><span> </span><span>viewBox</span><span>=</span><span>"0 0 1600 900"</span><span> </span><span>preserveAspectRatio</span><span>=</span><span>"xMidYMax slice"</span><span>&gt;</span></div></div><div><div><div>5</div></div><div><span><span>      </span></span><span>&lt;</span><span>defs</span><span>&gt;</span></div></div><div><div><div>6</div></div><div><span><span>        </span></span><span>&lt;</span><span>linearGradient</span><span> </span><span>id</span><span>=</span><span>"bg"</span><span>&gt;</span></div></div><div><div><div>7</div></div><div><span><span>          </span></span><span>&lt;</span><span>stop</span><span> </span><span>offset</span><span>=</span><span>"0%"</span><span> </span><span>style</span><span>=</span><span>"stop-color:rgba(130, 158, 249, 0.06)"</span><span>&gt;&lt;/</span><span>stop</span><span>&gt;</span></div></div><div><div><div>8</div></div><div><span><span>          </span></span><span>&lt;</span><span>stop</span><span> </span><span>offset</span><span>=</span><span>"50%"</span><span> </span><span>style</span><span>=</span><span>"stop-color:rgba(76, 190, 255, 0.6)"</span><span>&gt;&lt;/</span><span>stop</span><span>&gt;</span></div></div><div><div><div>9</div></div><div><span><span>          </span></span><span>&lt;</span><span>stop</span><span> </span><span>offset</span><span>=</span><span>"100%"</span><span> </span><span>style</span><span>=</span><span>"stop-color:rgba(115, 209, 72, 0.2)"</span><span>&gt;&lt;/</span><span>stop</span><span>&gt;</span></div></div><div><div><div>10</div></div><div><span><span>        </span></span><span>&lt;/</span><span>linearGradient</span><span>&gt;</span></div></div><div><div><div>11</div></div><div><span><span>        </span></span><span>&lt;</span><span>path</span><span> </span><span>id</span><span>=</span><span>"wave"</span><span> </span><span>fill</span><span>=</span><span>"url(#bg)"</span></div></div><div><div><div>12</div></div><div><span>          </span><span>d</span><span>=</span><span>"M-363.852,502.589c0,0,236.988-41.997,505.475,0</span></div></div><div><div><div>13</div></div><div><span><span>          </span></span><span>s371.981,38.998,575.971,0s293.985-39.278,505.474,5.859s493.475,48.368,716.963-4.995v560.106H-363.852V502.589z"</span><span> /&gt;</span></div></div><div><div><div>14</div></div><div><span><span>      </span></span><span>&lt;/</span><span>defs</span><span>&gt;</span></div></div><div><div><div>15</div></div><div><span><span>      </span></span><span>&lt;</span><span>g</span><span>&gt;</span></div></div><div><div><div>16</div></div><div><span><span>        </span></span><span>&lt;</span><span>use</span><span> </span><span>xlink:href</span><span>=</span><span>'#wave'</span><span> </span><span>opacity</span><span>=</span><span>".3"</span><span>&gt;</span></div></div><div><div><div>17</div></div><div><span><span>          </span></span><span>&lt;</span><span>animateTransform</span><span> </span><span>attributeName</span><span>=</span><span>"transform"</span><span> </span><span>attributeType</span><span>=</span><span>"XML"</span><span> </span><span>type</span><span>=</span><span>"translate"</span><span> </span><span>dur</span><span>=</span><span>"10s"</span></div></div><div><div><div>18</div></div><div><span>            </span><span>calcMode</span><span>=</span><span>"spline"</span><span> </span><span>values</span><span>=</span><span>"270 230; -334 180; 270 230"</span><span> </span><span>keyTimes</span><span>=</span><span>"0; .5; 1"</span></div></div><div><div><div>19</div></div><div><span>            </span><span>keySplines</span><span>=</span><span>"0.42, 0, 0.58, 1.0;0.42, 0, 0.58, 1.0"</span><span> </span><span>repeatCount</span><span>=</span><span>"indefinite"</span><span> /&gt;</span></div></div><div><div><div>20</div></div><div><span><span>        </span></span><span>&lt;/</span><span>use</span><span>&gt;</span></div></div><div><div><div>21</div></div><div><span><span>        </span></span><span>&lt;</span><span>use</span><span> </span><span>xlink:href</span><span>=</span><span>'#wave'</span><span> </span><span>opacity</span><span>=</span><span>".6"</span><span>&gt;</span></div></div><div><div><div>22</div></div><div><span><span>          </span></span><span>&lt;</span><span>animateTransform</span><span> </span><span>attributeName</span><span>=</span><span>"transform"</span><span> </span><span>attributeType</span><span>=</span><span>"XML"</span><span> </span><span>type</span><span>=</span><span>"translate"</span><span> </span><span>dur</span><span>=</span><span>"8s"</span></div></div><div><div><div>23</div></div><div><span>            </span><span>calcMode</span><span>=</span><span>"spline"</span><span> </span><span>values</span><span>=</span><span>"-270 230;243 220;-270 230"</span><span> </span><span>keyTimes</span><span>=</span><span>"0; .6; 1"</span></div></div><div><div><div>24</div></div><div><span>            </span><span>keySplines</span><span>=</span><span>"0.42, 0, 0.58, 1.0;0.42, 0, 0.58, 1.0"</span><span> </span><span>repeatCount</span><span>=</span><span>"indefinite"</span><span> /&gt;</span></div></div><div><div><div>25</div></div><div><span><span>        </span></span><span>&lt;/</span><span>use</span><span>&gt;</span></div></div><div><div><div>26</div></div><div><span><span>        </span></span><span>&lt;</span><span>use</span><span> </span><span>xlink:href</span><span>=</span><span>'#wave'</span><span> </span><span>opacty</span><span>=</span><span>".9"</span><span>&gt;</span></div></div><div><div><div>27</div></div><div><span><span>          </span></span><span>&lt;</span><span>animateTransform</span><span> </span><span>attributeName</span><span>=</span><span>"transform"</span><span> </span><span>attributeType</span><span>=</span><span>"XML"</span><span> </span><span>type</span><span>=</span><span>"translate"</span><span> </span><span>dur</span><span>=</span><span>"6s"</span></div></div><div><div><div>28</div></div><div><span>            </span><span>calcMode</span><span>=</span><span>"spline"</span><span> </span><span>values</span><span>=</span><span>"0 230;-140 200;0 230"</span><span> </span><span>keyTimes</span><span>=</span><span>"0; .4; 1"</span></div></div><div><div><div>29</div></div><div><span>            </span><span>keySplines</span><span>=</span><span>"0.42, 0, 0.58, 1.0;0.42, 0, 0.58, 1.0"</span><span> </span><span>repeatCount</span><span>=</span><span>"indefinite"</span><span> /&gt;</span></div></div><div><div><div>30</div></div><div><span><span>        </span></span><span>&lt;/</span><span>use</span><span>&gt;</span></div></div><div><div><div>31</div></div><div><span><span>      </span></span><span>&lt;/</span><span>g</span><span>&gt;</span></div></div><div><div><div>32</div></div><div><span><span>    </span></span><span>&lt;/</span><span>svg</span><span>&gt;</span></div></div><div><div><div>33</div></div><div>
</div></div><div><div><div>34</div></div><div><span><span>    </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"loginBox"</span><span>&gt;</span></div></div><div><div><div>35</div></div><div><span><span>      </span></span><span>&lt;</span><span>h3</span><span> </span><span>style</span><span>=</span><span>"</span><span>text-align: center;margin-bottom:120rpx;</span><span>"</span><span>&gt;欢迎登录&lt;/</span><span>h3</span><span>&gt;</span></div></div><div><div><div>36</div></div><div><span><span>      </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"inputBox"</span><span>&gt;</span></div></div><div><div><div>37</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"ipt"</span><span>&gt;</span></div></div><div><div><div>38</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"contact"</span><span> </span><span>size</span><span>=</span><span>"24"</span><span> </span><span>color</span><span>=</span><span>"rgb(66,157,250)"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>39</div></div><div><span><span>          </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"text"</span><span> </span><span>value</span><span>=</span><span>""</span><span> </span><span>placeholder</span><span>=</span><span>"请输入账号"</span><span>/&gt;</span></div></div><div><div><div>40</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>41</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"ipt"</span><span>&gt;</span></div></div><div><div><div>42</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"eye"</span><span> </span><span>size</span><span>=</span><span>"24"</span><span> </span><span>color</span><span>=</span><span>"rgb(66,157,250)"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>43</div></div><div><span><span>          </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"passsword"</span><span> </span><span>value</span><span>=</span><span>""</span><span> </span><span>placeholder</span><span>=</span><span>"请输入密码"</span><span>/&gt;</span></div></div><div><div><div>44</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>45</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"ipt"</span><span>&gt;</span></div></div><div><div><div>46</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"checkmarkempty"</span><span> </span><span>size</span><span>=</span><span>"24"</span><span> </span><span>color</span><span>=</span><span>"rgb(66,157,250)"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>47</div></div><div><span><span>          </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"text"</span><span> </span><span>value</span><span>=</span><span>""</span><span> </span><span>placeholder</span><span>=</span><span>"请输入验证码"</span><span>/&gt;</span></div></div><div><div><div>48</div></div><div><span><span>          </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"yzm"</span><span>&gt;</span></div></div><div><div><div>49</div></div><div><span><span>            </span></span><span>验证码</span></div></div><div><div><div>50</div></div><div><span><span>          </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>51</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>52</div></div><div><span><span>        </span></span><span>&lt;</span><span>button</span><span>&gt;登录&lt;/</span><span>button</span><span>&gt;</span></div></div><div><div><div>53</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"forgetPwd"</span><span>&gt;</span></div></div><div><div><div>54</div></div><div><span><span>          </span></span><span>&lt;</span><span>span</span><span>&gt;忘记密码&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>55</div></div><div><span><span>          </span></span><span>&lt;</span><span>span</span><span>&gt;没有账号，去注册&lt;/</span><span>span</span><span>&gt;</span></div></div><div><div><div>56</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>57</div></div><div><span><span>      </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>58</div></div><div><span><span>      </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"tipbox"</span><span>&gt;</span></div></div><div><div><div>59</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"txt"</span><span>&gt;</span></div></div><div><div><div>60</div></div><div><span><span>          </span></span><span>—— 其他账号登录 ——</span></div></div><div><div><div>61</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>62</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"otherUser"</span><span>&gt;</span></div></div><div><div><div>63</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"qq"</span><span> </span><span>size</span><span>=</span><span>"40"</span><span> </span><span>color</span><span>=</span><span>"rgb(66,157,250)"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>64</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"weixin"</span><span> </span><span>size</span><span>=</span><span>"40"</span><span> </span><span>color</span><span>=</span><span>"rgb(2,187,17)"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>65</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>66</div></div><div><span><span>      </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>67</div></div><div><span><span>    </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>68</div></div><div><span><span>  </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>69</div></div><div><span>&lt;/</span><span>template</span><span>&gt;</span></div></div><div><div><div>70</div></div><div>
</div></div><div><div><div>71</div></div><div><span>&lt;</span><span>script</span><span>&gt;</span></div></div><div><div><div>72</div></div><div><span>  </span><span>export</span><span> </span><span>default</span><span> {</span></div></div><div><div><div>73</div></div><div><span>    </span><span>data</span><span>() {</span></div></div><div><div><div>74</div></div><div><span>      </span><span>return</span><span> {</span></div></div><div><div><div>75</div></div><div>
</div></div><div><div><div>76</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>77</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>78</div></div><div><span>    </span><span>methods</span><span>:</span><span> {</span></div></div><div><div><div>79</div></div><div>
</div></div><div><div><div>80</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>81</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>82</div></div><div><span>&lt;/</span><span>script</span><span>&gt;</span></div></div><div><div><div>83</div></div><div>
</div></div><div><div><div>84</div></div><div><span>&lt;</span><span>style</span><span> </span><span>scoped</span><span>&gt;</span></div></div><div><div><div>85</div></div><div><span>  </span><span>svg</span><span> {</span></div></div><div><div><div>86</div></div><div><span><span>    </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>87</div></div><div><span><span>    </span></span><span>bottom: </span><span>0</span><span>;</span></div></div><div><div><div>88</div></div><div><span><span>    </span></span><span>left: </span><span>0</span><span>;</span></div></div><div><div><div>89</div></div><div><span><span>    </span></span><span>width: </span><span><span>100</span><span>%</span></span><span>;</span></div></div><div><div><div>90</div></div><div><span><span>    </span></span><span>height:</span><span><span>40</span><span>%</span></span><span>;</span></div></div><div><div><div>91</div></div><div><span><span>    </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>92</div></div><div><span><span>    </span></span><span>display: </span><span>block</span><span>;</span></div></div><div><div><div>93</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>ffffff</span><span>;</span></div></div><div><div><div>94</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>95</div></div><div>
</div></div><div><div><div>96</div></div><div><span>  </span><span>.loginBox</span><span>{</span></div></div><div><div><div>97</div></div><div><span><span>    </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>98</div></div><div><span><span>    </span></span><span>top: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>99</div></div><div><span><span>    </span></span><span>left: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>100</div></div><div><span><span>    </span></span><span>transform: </span><span>translate</span><span>(</span><span><span>-50</span><span>%</span></span><span>,</span><span><span>-60</span><span>%</span></span><span>);</span></div></div><div><div><div>101</div></div><div><span><span>    </span></span><span>width: </span><span><span>90</span><span>%</span></span><span>;</span></div></div><div><div><div>102</div></div><div><span><span>    </span></span><span>border-radius: </span><span>20</span><span>rpx;</span></div></div><div><div><div>103</div></div><div><span><span>    </span></span><span>padding: </span><span>60</span><span>rpx;</span></div></div><div><div><div>104</div></div><div><span><span>    </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>105</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>106</div></div><div><span>  </span><span>h3</span><span>{</span></div></div><div><div><div>107</div></div><div><span><span>    </span></span><span>color:</span><span>rgb</span><span>(</span><span>66</span><span>,</span><span>157</span><span>,</span><span>250</span><span>);</span></div></div><div><div><div>108</div></div><div><span><span>    </span></span><span>font-size: </span><span>40</span><span>rpx;</span></div></div><div><div><div>109</div></div><div><span><span>    </span></span><span>letter-spacing: </span><span>10</span><span>rpx;</span></div></div><div><div><div>110</div></div><div><span><span>    </span></span><span>margin-bottom: </span><span>40</span><span>rpx;</span></div></div><div><div><div>111</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>112</div></div><div><span>  </span><span>.inputBox</span><span>{</span></div></div><div><div><div>113</div></div><div>
</div></div><div><div><div>114</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>115</div></div><div><span>  </span><span>.ipt</span><span>{</span></div></div><div><div><div>116</div></div><div><span><span>    </span></span><span>height: </span><span>86</span><span>rpx;</span></div></div><div><div><div>117</div></div><div><span><span>    </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>118</div></div><div><span><span>    </span></span><span>justify-content: </span><span>flex-start</span><span>;</span></div></div><div><div><div>119</div></div><div><span><span>    </span></span><span>align-items: </span><span>center</span><span>;</span></div></div><div><div><div>120</div></div><div><span><span>    </span></span><span>margin-bottom: </span><span>40</span><span>rpx;</span></div></div><div><div><div>121</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>f5f5f5</span><span>;</span></div></div><div><div><div>122</div></div><div><span><span>    </span></span><span>border-radius: </span><span>10</span><span>rpx;</span></div></div><div><div><div>123</div></div><div><span><span>    </span></span><span>padding-left: </span><span>10</span><span>rpx;</span></div></div><div><div><div>124</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>125</div></div><div><span>  </span><span>.ipt</span><span> </span><span>input</span><span>{</span></div></div><div><div><div>126</div></div><div><span><span>    </span></span><span>margin-left: </span><span>20</span><span>rpx;</span></div></div><div><div><div>127</div></div><div><span><span>    </span></span><span>font-size: </span><span>28</span><span>rpx;</span></div></div><div><div><div>128</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>129</div></div><div><span>  </span><span>.ipt</span><span> </span><span>input</span><span>{</span></div></div><div><div><div>130</div></div><div><span><span>    </span></span><span>margin-left: </span><span>20</span><span>rpx;</span></div></div><div><div><div>131</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>132</div></div><div><span>  </span><span>.forgetPwd</span><span>{</span></div></div><div><div><div>133</div></div><div><span><span>    </span></span><span>margin-top: </span><span>30</span><span>rpx;</span></div></div><div><div><div>134</div></div><div><span><span>    </span></span><span>font-size: </span><span>26</span><span>rpx;</span></div></div><div><div><div>135</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>b5b5b5</span><span>;</span></div></div><div><div><div>136</div></div><div><span><span>    </span></span><span>text-align: </span><span>end</span><span>;</span></div></div><div><div><div>137</div></div><div><span><span>    </span></span><span>padding:</span><span>0</span><span> </span><span>10</span><span>rpx;</span></div></div><div><div><div>138</div></div><div><span><span>    </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>139</div></div><div><span><span>    </span></span><span>justify-content: </span><span>space-between</span><span>;</span></div></div><div><div><div>140</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>141</div></div><div><span>  </span><span>button</span><span>{</span></div></div><div><div><div>142</div></div><div><span><span>    </span></span><span>margin-top: </span><span>20</span><span>rpx;</span></div></div><div><div><div>143</div></div><div><span><span>    </span></span><span>line-height: </span><span>85</span><span>rpx;</span></div></div><div><div><div>144</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>145</div></div><div><span><span>    </span></span><span>background: </span><span>rgb</span><span>(</span><span>66</span><span>,</span><span>157</span><span>,</span><span>250</span><span>);</span></div></div><div><div><div>146</div></div><div><span><span>    </span></span><span>border-radius: </span><span>40</span><span>rpx;</span></div></div><div><div><div>147</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>148</div></div><div><span><span>    </span></span><span>margin-top: </span><span>40</span><span>rpx;</span></div></div><div><div><div>149</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>150</div></div><div>
</div></div><div><div><div>151</div></div><div><span>  </span><span>.tip</span><span>{</span></div></div><div><div><div>152</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>153</div></div><div><span><span>    </span></span><span>font-size: </span><span>28</span><span>rpx;</span></div></div><div><div><div>154</div></div><div><span><span>    </span></span><span>position: </span><span>fixed</span><span>;</span></div></div><div><div><div>155</div></div><div><span><span>    </span></span><span>bottom: </span><span>50</span><span>rpx;</span></div></div><div><div><div>156</div></div><div><span><span>    </span></span><span>left: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>157</div></div><div><span><span>    </span></span><span>transform: </span><span>translate</span><span>(</span><span><span>-50</span><span>%</span></span><span>,</span><span><span>-50</span><span>%</span></span><span>);</span></div></div><div><div><div>158</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>f4f4f4</span><span>;</span></div></div><div><div><div>159</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>160</div></div><div><span>  </span><span>.tipbox</span><span> {</span></div></div><div><div><div>161</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>162</div></div><div><span><span>    </span></span><span>margin-top: </span><span>100</span><span>rpx;</span></div></div><div><div><div>163</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>164</div></div><div>
</div></div><div><div><div>165</div></div><div><span>  </span><span>.otherUser</span><span> {</span></div></div><div><div><div>166</div></div><div><span><span>    </span></span><span>margin-top: </span><span>30</span><span>rpx;</span></div></div><div><div><div>167</div></div><div><span><span>    </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>168</div></div><div><span><span>    </span></span><span>justify-content: </span><span>center</span><span>;</span></div></div><div><div><div>169</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>170</div></div><div>
</div></div><div><div><div>171</div></div><div><span>  </span><span>.txt</span><span> {</span></div></div><div><div><div>172</div></div><div><span><span>    </span></span><span>font-size: </span><span>28</span><span>rpx;</span></div></div><div><div><div>173</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>cbcbcb</span><span>;</span></div></div><div><div><div>174</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>175</div></div><div>
</div></div><div><div><div>176</div></div><div><span>  </span><span>.otherUser</span><span> </span><span>.uni-icons</span><span> {</span></div></div><div><div><div>177</div></div><div><span><span>    </span></span><span>margin-left: </span><span>20</span><span>rpx;</span></div></div><div><div><div>178</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>179</div></div><div><span>  </span><span>.yzm</span><span>{</span></div></div><div><div><div>180</div></div><div><span><span>    </span></span><span>text-align: </span><span>end</span><span>;</span></div></div><div><div><div>181</div></div><div><span><span>    </span></span><span>font-size: </span><span>24</span><span>rpx;</span></div></div><div><div><div>182</div></div><div><span><span>    </span></span><span>background: </span><span>linear-gradient</span><span><span>(to </span><span>right</span><span>,</span></span><span>rgb</span><span>(</span><span>66</span><span>,</span><span>157</span><span>,</span><span>250</span><span>),</span><span>rgb</span><span>(</span><span>0</span><span>, </span><span>170</span><span>, </span><span>127</span><span>));</span></div></div><div><div><div>183</div></div><div><span><span>    </span></span><span>height: </span><span>60</span><span>rpx;</span></div></div><div><div><div>184</div></div><div><span><span>    </span></span><span>width: </span><span>150</span><span>rpx;</span></div></div><div><div><div>185</div></div><div><span><span>    </span></span><span>line-height: </span><span>60</span><span>rpx;</span></div></div><div><div><div>186</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>187</div></div><div><span><span>    </span></span><span>border-radius: </span><span>10</span><span>rpx;</span></div></div><div><div><div>188</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>189</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>190</div></div><div><span>&lt;/</span><span>style</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<p><em><strong>蓝色登录界面（图三）：</strong></em></p>
<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>template</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"content"</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"topBox"</span><span>&gt;</span></div></div><div><div><div>4</div></div><div><span><span>      </span></span><span>&lt;</span><span>h3</span><span>&gt;WELCOME&lt;/</span><span>h3</span><span>&gt;</span></div></div><div><div><div>5</div></div><div><span><span>      </span></span><span>&lt;</span><span>h3</span><span>&gt;欢迎使用某某应用&lt;/</span><span>h3</span><span>&gt;</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"inputBox"</span><span>&gt;</span></div></div><div><div><div>8</div></div><div><span><span>      </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"ipt"</span><span>&gt;</span></div></div><div><div><div>9</div></div><div><span><span>        </span></span><span>&lt;</span><span>h4</span><span>&gt;手机号&lt;/</span><span>h4</span><span>&gt;</span></div></div><div><div><div>10</div></div><div><span><span>        </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"text"</span><span> </span><span>value</span><span>=</span><span>""</span><span> </span><span>placeholder</span><span>=</span><span>"请输入手机号码"</span><span> /&gt;</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"ipt"</span><span>&gt;</span></div></div><div><div><div>13</div></div><div><span><span>        </span></span><span>&lt;</span><span>h4</span><span>&gt;密码&lt;/</span><span>h4</span><span>&gt;</span></div></div><div><div><div>14</div></div><div><span><span>        </span></span><span>&lt;</span><span>input</span><span> </span><span>type</span><span>=</span><span>"text"</span><span> </span><span>value</span><span>=</span><span>""</span><span> </span><span>placeholder</span><span>=</span><span>"请输入密码"</span><span> /&gt;</span></div></div><div><div><div>15</div></div><div><span><span>      </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>16</div></div><div><span><span>      </span></span><span>&lt;</span><span>button</span><span> </span><span>class</span><span>=</span><span>"loginBtn"</span><span>&gt;登录&lt;/</span><span>button</span><span>&gt;</span></div></div><div><div><div>17</div></div><div><span><span>      </span></span><span>&lt;</span><span>button</span><span> </span><span>class</span><span>=</span><span>"registerBtn"</span><span>&gt;注册&lt;/</span><span>button</span><span>&gt;</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span><span>      </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"tipbox"</span><span>&gt;</span></div></div><div><div><div>20</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"txt"</span><span>&gt;</span></div></div><div><div><div>21</div></div><div><span><span>          </span></span><span>—— 其他账号登录 ——</span></div></div><div><div><div>22</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>23</div></div><div><span><span>        </span></span><span>&lt;</span><span>view</span><span> </span><span>class</span><span>=</span><span>"otherUser"</span><span>&gt;</span></div></div><div><div><div>24</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"qq"</span><span> </span><span>size</span><span>=</span><span>"40"</span><span> </span><span>color</span><span>=</span><span>"rgb(66,157,250)"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>25</div></div><div><span><span>          </span></span><span>&lt;</span><span>uni-icons</span><span> </span><span>type</span><span>=</span><span>"weixin"</span><span> </span><span>size</span><span>=</span><span>"40"</span><span> </span><span>color</span><span>=</span><span>"rgb(2,187,17)"</span><span>&gt;&lt;/</span><span>uni-icons</span><span>&gt;</span></div></div><div><div><div>26</div></div><div><span><span>        </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>27</div></div><div><span><span>      </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>28</div></div><div><span><span>    </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>29</div></div><div><span><span>  </span></span><span>&lt;/</span><span>view</span><span>&gt;</span></div></div><div><div><div>30</div></div><div><span>&lt;/</span><span>template</span><span>&gt;</span></div></div><div><div><div>31</div></div><div>
</div></div><div><div><div>32</div></div><div><span>&lt;</span><span>script</span><span>&gt;</span></div></div><div><div><div>33</div></div><div><span>  </span><span>export</span><span> </span><span>default</span><span> {</span></div></div><div><div><div>34</div></div><div><span>    </span><span>data</span><span>() {</span></div></div><div><div><div>35</div></div><div><span>      </span><span>return</span><span> {</span></div></div><div><div><div>36</div></div><div>
</div></div><div><div><div>37</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>38</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>39</div></div><div><span>    </span><span>methods</span><span>:</span><span> {</span></div></div><div><div><div>40</div></div><div>
</div></div><div><div><div>41</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>42</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>43</div></div><div><span>&lt;/</span><span>script</span><span>&gt;</span></div></div><div><div><div>44</div></div><div>
</div></div><div><div><div>45</div></div><div><span>&lt;</span><span>style</span><span> </span><span>scoped</span><span>&gt;</span></div></div><div><div><div>46</div></div><div><span>  </span><span>.content</span><span> {</span></div></div><div><div><div>47</div></div><div><span><span>    </span></span><span>height: </span><span><span>100</span><span>vh</span></span><span>;</span></div></div><div><div><div>48</div></div><div><span><span>    </span></span><span>background-color: </span><span>aquamarine</span><span>;</span></div></div><div><div><div>49</div></div><div><span><span>    </span></span><span>background: </span><span>url</span><span>(</span><span>"https://www.galaxyclub.cn/Upload/IMAGES/15/0615/38af439784544e95b7c64cad64a14157_650x650.jpg"</span><span><span>) </span><span>no-repeat</span><span>;</span></span></div></div><div><div><div>50</div></div><div><span><span>    </span></span><span>background-size: </span><span>cover</span><span>;</span></div></div><div><div><div>51</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>52</div></div><div>
</div></div><div><div><div>53</div></div><div><span>  </span><span>.topBox</span><span> {</span></div></div><div><div><div>54</div></div><div><span><span>    </span></span><span>font-size: </span><span>34</span><span>rpx;</span></div></div><div><div><div>55</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>56</div></div><div><span><span>    </span></span><span>padding: </span><span>80</span><span>rpx </span><span>50</span><span>rpx;</span></div></div><div><div><div>57</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>58</div></div><div>
</div></div><div><div><div>59</div></div><div><span>  </span><span>h3</span><span> {</span></div></div><div><div><div>60</div></div><div><span><span>    </span></span><span>margin-bottom: </span><span>10</span><span>rpx;</span></div></div><div><div><div>61</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>62</div></div><div>
</div></div><div><div><div>63</div></div><div><span>  </span><span>.inputBox</span><span> {</span></div></div><div><div><div>64</div></div><div><span><span>    </span></span><span>position: </span><span>fixed</span><span>;</span></div></div><div><div><div>65</div></div><div><span><span>    </span></span><span>bottom: </span><span>0</span><span>;</span></div></div><div><div><div>66</div></div><div><span><span>    </span></span><span>left: </span><span>0</span><span>;</span></div></div><div><div><div>67</div></div><div><span><span>    </span></span><span>width: </span><span>750</span><span>rpx;</span></div></div><div><div><div>68</div></div><div><span><span>    </span></span><span>height: </span><span><span>85</span><span>vh</span></span><span>;</span></div></div><div><div><div>69</div></div><div><span><span>    </span></span><span>background-color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>70</div></div><div><span><span>    </span></span><span>border-top-left-radius: </span><span>40</span><span>rpx;</span></div></div><div><div><div>71</div></div><div><span><span>    </span></span><span>border-top-right-radius: </span><span>40</span><span>rpx;</span></div></div><div><div><div>72</div></div><div><span><span>    </span></span><span>padding: </span><span>60</span><span>rpx;</span></div></div><div><div><div>73</div></div><div><span><span>    </span></span><span>box-sizing: </span><span>border-box</span><span>;</span></div></div><div><div><div>74</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>75</div></div><div>
</div></div><div><div><div>76</div></div><div><span>  </span><span>.ipt</span><span> {</span></div></div><div><div><div>77</div></div><div><span><span>    </span></span><span>margin-bottom: </span><span>50</span><span>rpx;</span></div></div><div><div><div>78</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>79</div></div><div>
</div></div><div><div><div>80</div></div><div><span>  </span><span>.ipt</span><span> </span><span>h4</span><span> {</span></div></div><div><div><div>81</div></div><div><span><span>    </span></span><span>margin-bottom: </span><span>20</span><span>rpx;</span></div></div><div><div><div>82</div></div><div><span><span>    </span></span><span>font-size: </span><span>36</span><span>rpx;</span></div></div><div><div><div>83</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>333</span><span>;</span></div></div><div><div><div>84</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>85</div></div><div>
</div></div><div><div><div>86</div></div><div><span>  </span><span>.ipt</span><span> </span><span>input</span><span> {</span></div></div><div><div><div>87</div></div><div><span><span>    </span></span><span>border-bottom: </span><span><span>1</span><span>px</span></span><span><span> </span><span>solid</span><span> </span></span><span>#</span><span>dedede</span><span>;</span></div></div><div><div><div>88</div></div><div><span><span>    </span></span><span>padding-bottom: </span><span>20</span><span>rpx;</span></div></div><div><div><div>89</div></div><div><span><span>    </span></span><span>font-size: </span><span>28</span><span>rpx;</span></div></div><div><div><div>90</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>91</div></div><div>
</div></div><div><div><div>92</div></div><div><span>  </span><span>.loginBtn</span><span> {</span></div></div><div><div><div>93</div></div><div><span><span>    </span></span><span>margin-top: </span><span>20</span><span>rpx;</span></div></div><div><div><div>94</div></div><div><span><span>    </span></span><span>line-height: </span><span>85</span><span>rpx;</span></div></div><div><div><div>95</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>96</div></div><div><span><span>    </span></span><span>background: </span><span>linear-gradient</span><span><span>(to </span><span>right</span><span>, </span></span><span>rgb</span><span>(</span><span>86</span><span>, </span><span>104</span><span>, </span><span>214</span><span>), </span><span>rgb</span><span>(</span><span>86</span><span>, </span><span>104</span><span>, </span><span>214</span><span>));</span></div></div><div><div><div>97</div></div><div><span><span>    </span></span><span>border-radius: </span><span>40</span><span>rpx;</span></div></div><div><div><div>98</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>fff</span><span>;</span></div></div><div><div><div>99</div></div><div><span><span>    </span></span><span>margin-top: </span><span>50</span><span>rpx;</span></div></div><div><div><div>100</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>101</div></div><div>
</div></div><div><div><div>102</div></div><div><span>  </span><span>.registerBtn</span><span> {</span></div></div><div><div><div>103</div></div><div><span><span>    </span></span><span>margin-top: </span><span>20</span><span>rpx;</span></div></div><div><div><div>104</div></div><div><span><span>    </span></span><span>line-height: </span><span>85</span><span>rpx;</span></div></div><div><div><div>105</div></div><div><span><span>    </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>106</div></div><div><span><span>    </span></span><span>border-radius: </span><span>40</span><span>rpx;</span></div></div><div><div><div>107</div></div><div><span><span>    </span></span><span>color: </span><span>rgb</span><span>(</span><span>86</span><span>, </span><span>104</span><span>, </span><span>214</span><span>);</span></div></div><div><div><div>108</div></div><div><span><span>    </span></span><span>margin-top: </span><span>50</span><span>rpx;</span></div></div><div><div><div>109</div></div><div><span><span>    </span></span><span>border: </span><span>none</span><span>;</span></div></div><div><div><div>110</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>111</div></div><div>
</div></div><div><div><div>112</div></div><div><span>  </span><span>.tipbox</span><span> {</span></div></div><div><div><div>113</div></div><div><span><span>    </span></span><span>position: </span><span>fixed</span><span>;</span></div></div><div><div><div>114</div></div><div><span><span>    </span></span><span>bottom: </span><span>120</span><span>rpx;</span></div></div><div><div><div>115</div></div><div><span><span>    </span></span><span>left: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>116</div></div><div><span><span>    </span></span><span>transform: </span><span>translate</span><span>(</span><span><span>-50</span><span>%</span></span><span>, </span><span><span>-120</span><span>px</span></span><span>);</span></div></div><div><div><div>117</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>118</div></div><div>
</div></div><div><div><div>119</div></div><div><span>  </span><span>.otherUser</span><span> {</span></div></div><div><div><div>120</div></div><div><span><span>    </span></span><span>margin-top: </span><span>30</span><span>rpx;</span></div></div><div><div><div>121</div></div><div><span><span>    </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>122</div></div><div><span><span>    </span></span><span>justify-content: </span><span>center</span><span>;</span></div></div><div><div><div>123</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>124</div></div><div>
</div></div><div><div><div>125</div></div><div><span>  </span><span>.txt</span><span> {</span></div></div><div><div><div>126</div></div><div><span><span>    </span></span><span>font-size: </span><span>28</span><span>rpx;</span></div></div><div><div><div>127</div></div><div><span><span>    </span></span><span>color: </span><span>#</span><span>969696</span><span>;</span></div></div><div><div><div>128</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>129</div></div><div>
</div></div><div><div><div>130</div></div><div><span>  </span><span>.otherUser</span><span> </span><span>.uni-icons</span><span> {</span></div></div><div><div><div>131</div></div><div><span><span>    </span></span><span>margin-left: </span><span>20</span><span>rpx;</span></div></div><div><div><div>132</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>133</div></div><div><span>&lt;/</span><span>style</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/3cdc8223/</id>
      <title type="text">【Linux】RocketMQ 部署</title>
      <published>2024-05-21T08:31:13.000Z</published>
      <updated>2024-05-21T08:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/3cdc8223/"/>
      <summary type="text">在Linux环境下部署RocketMQ的完整过程。文章详细说明了如何通过Docker部署RocketMQ，包括创建NameServer、Broker和RocketMQ Console的服务，并提供了相应的Docker命令和配置文件示例。</summary>
      <content type="html"><![CDATA[<section><h2>系统要求<a href="#系统要求"><span>#</span></a></h2><blockquote><p><strong>系统要求</strong><br />
1、64位操作系统，推荐 Linux/Unix/macOS<br />
2、64位 JDK 1.8+<br />
3、<a href="https://rocketmq.apache.org/zh/docs/quickStart/01quickstart" target="_blank">官网文档</a></p></blockquote></section>
<section><h2>安装部署<a href="#安装部署"><span>#</span></a></h2><section><h3>下载<a href="#下载"><span>#</span></a></h3><blockquote><p>这里使用<a href="https://dist.apache.org/repos/dist/release/rocketmq/5.1.0/rocketmq-all-5.1.0-bin-release.zip" target="_blank">release</a>免编译版本</p></blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 解压</span></div></div><div><div><div>2</div></div><div><span>$</span><span> </span><span>unzip</span><span> </span><span>rocketmq-all-5.1.0-source-release.zip</span></div></div><div><div><div>3</div></div><div><span># 打开文件夹</span></div></div><div><div><div>4</div></div><div><span>$</span><span> </span><span>cd</span><span> </span><span>rocketmq-all-5.1.0-source-release/</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>启动NameServer<a href="#启动nameserver"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>### 启动namesrv</span></div></div><div><div><div>2</div></div><div><span>$</span><span> </span><span>nohup</span><span> </span><span>sh</span><span> </span><span>bin/mqnamesrv</span><span> &amp;</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>### 验证namesrv是否启动成功</span></div></div><div><div><div>5</div></div><div><span>$</span><span> </span><span>tail</span><span> </span><span>-f</span><span> </span><span>~/logs/rocketmqlogs/namesrv.log</span></div></div><div><div><div>6</div></div><div><span>The</span><span> </span><span>Name</span><span> </span><span>Server</span><span> </span><span>boot</span><span> </span><span>success...</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>我们可以在namesrv.log 中看到 <code>The Name Server boot success..</code>， 表示NameServer 已成功启动。</p></blockquote></section><section><h3>启动Broker+Proxy<a href="#启动brokerproxy"><span>#</span></a></h3><p>NameServer成功启动后，我们启动Broker和Proxy，5.x 版本下我们建议使用 Local 模式部署，即 Broker 和 Proxy 同进程部署。5.x 版本也支持 Broker 和 Proxy 分离部署以实现更灵活的集群能力。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>### 先启动broker</span></div></div><div><div><div>2</div></div><div><span>$</span><span> </span><span>nohup</span><span> </span><span>sh</span><span> </span><span>bin/mqbroker</span><span> </span><span>-n</span><span> </span><span>localhost:9876</span><span> </span><span>--enable-proxy</span><span> &amp;</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>### 验证broker是否启动成功, 比如, broker的ip是192.168.1.2 然后名字是broker-a</span></div></div><div><div><div>5</div></div><div><span>$</span><span> </span><span>tail</span><span> </span><span>-f</span><span> </span><span>~/logs/rocketmqlogs/proxy.log</span></div></div><div><div><div>6</div></div><div><span>The</span><span> </span><span>broker[broker-a,192.169.1.2:10911]</span><span> </span><span>boot</span><span> </span><span>success...</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>我们可以在 proxy.log 中看到<code>The broker[brokerName,ip:port] boot success..</code>，这表明 broker 已成功启动。</p></blockquote></section><section><h3>工具测试消息收发<a href="#工具测试消息收发"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>export</span><span> </span><span>NAMESRV_ADDR=localhost:9876</span></div></div><div><div><div>2</div></div><div><span>$</span><span> </span><span>sh</span><span> </span><span>bin/tools.sh</span><span> </span><span>org.apache.rocketmq.example.quickstart.Producer</span></div></div><div><div><div>3</div></div><div><span> </span><span>SendResult</span><span> [sendStatus=SEND_OK, </span><span>msgId=</span><span> </span><span>...</span></div></div><div><div><div>4</div></div><div><span>$</span><span> </span><span>sh</span><span> </span><span>bin/tools.sh</span><span> </span><span>org.apache.rocketmq.example.quickstart.Consumer</span></div></div><div><div><div>5</div></div><div><span> </span><span>ConsumeMessageThread_%d</span><span> </span><span>Receive</span><span> </span><span>New</span><span> </span><span>Messages:</span><span> [MessageExt...</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>dashboard(非必须)<a href="#dashboard非必须"><span>#</span></a></h3><section><h4>安装<a href="#安装"><span>#</span></a></h4><p>安装 dashboard，需要编译源代码. <a href="https://github.com/apache/rocketmq-dashboard" target="_blank">源码github 地址</a></p><p>下载之后，修改 application.yml 参数，我这里只修改了 Name Server 地址：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>rocketmq</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>config</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>namesrvAddrs</span><span>:</span></div></div><div><div><div>4</div></div><div><span><span>      </span></span><span>- </span><span>127.0.0.1:9876</span></div></div><div><div><div>5</div></div><div><span><span>      </span></span><span>- </span><span>47.xx.xx.xx:9876</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后执行 Maven 打包命令，打出 jar 包：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>mvn</span><span> </span><span>clean</span><span> </span><span>package</span><span> </span><span>-Dmaven.test.skip=true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>打好 jar 包后上传到服务器，执行下面命令启动：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>java</span><span> </span><span>-jar</span><span> </span><span>rocketmq-dashboard-1.0.1-SNAPSHOT.jar</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>测试<a href="#测试"><span>#</span></a></h4><p>浏览器输入 <a href="http://127.0.0.1:8080/" target="_blank">http://127.0.0.1:8080/</a></p></section></section></section>
<section><h2>Docker 部署<a href="#docker-部署"><span>#</span></a></h2><section><h3>创建namesrv服务<a href="#创建namesrv服务"><span>#</span></a></h3><section><h4>拉取镜像<a href="#拉取镜像"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>pull</span><span> </span><span>apache/rocketmq</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>创建namesrv数据存储路径<a href="#创建namesrv数据存储路径"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>mkdir</span><span> </span><span>-p</span><span>  </span><span>/docker/rocketmq/data/namesrv/logs</span><span>   </span><span>/docker/rocketmq/data/namesrv/store</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>构建namesrv容器<a href="#构建namesrv容器"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>--restart=always </span><span>\</span></div></div><div><div><div>3</div></div><div><span>--name </span><span>rmqnamesrv</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>-p </span><span>9876:9876</span><span> </span><span>\</span></div></div><div><div><div>5</div></div><div><span>-v </span><span>/docker/rocketmq/data/namesrv/logs:/root/logs</span><span> </span><span>\</span></div></div><div><div><div>6</div></div><div><span>-v </span><span>/docker/rocketmq/data/namesrv/store:/root/store</span><span> </span><span>\</span></div></div><div><div><div>7</div></div><div><span>-e </span><span>"MAX_POSSIBLE_HEAP=100000000"</span><span> </span><span>\</span></div></div><div><div><div>8</div></div><div><span>apache/rocketmq </span><span>\</span></div></div><div><div><div>9</div></div><div><span>sh </span><span>mqnamesrv</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>-restart=always| docker重启时候容器自动重启<br />
-name rmqnamesrv | 把容器的名字设置为rmqnamesrv<br />
-p 9876&lt;9876&gt;| 把容器内的端口9876挂载到宿主机9876上面<br />
-v /docker/rocketmq/data/namesrv/logs:/root/logs |       把容器内的/root/logs日志目录挂载到宿主机的 /docker/rocketmq/data/namesrv/logs目录<br />
-v /docker/rocketmq/data/namesrv/store:/root/store |         把容器内的/root/store数据存储目录挂载到宿主机的 /docker/rocketmq/data/namesrv目录
rmqnamesrv | 容器的名字<br />
-e “MAX_POSSIBLE_HEAP=100000000” | 设置容器的最大堆内存为100000000<br />
apache/rocketmq | 使用的镜像名称<br />
sh mqnamesrv | 启动namesrv服务</p></blockquote></section></section><section><h3>创建broker节点<a href="#创建broker节点"><span>#</span></a></h3><section><h4>创建broker数据存储路径<a href="#创建broker数据存储路径"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>mkdir</span><span> </span><span>-p</span><span>  </span><span>/docker/rocketmq/data/broker/logs</span><span>   </span><span>/docker/rocketmq/data/broker/store</span><span> </span><span>/docker/rocketmq/conf</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>创建配置文件<a href="#创建配置文件"><span>#</span></a></h4><blockquote><p>注意修改 <code>brokerIP1 = 172.18.88.54</code> 中ip地址。</p></blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>vi</span><span> </span><span>/docker/rocketmq/conf/broker.conf</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 所属集群名称，如果节点较多可以配置多个</span></div></div><div><div><div>2</div></div><div><span>brokerClusterName</span><span> </span><span>=</span><span> </span><span>DefaultCluster</span></div></div><div><div><div>3</div></div><div><span>#broker名称，master和slave使用相同的名称，表明他们的主从关系</span></div></div><div><div><div>4</div></div><div><span>brokerName</span><span> </span><span>=</span><span> </span><span>broker-a</span></div></div><div><div><div>5</div></div><div><span>#0表示Master，大于0表示不同的slave</span></div></div><div><div><div>6</div></div><div><span>brokerId</span><span> </span><span>=</span><span> </span><span>0</span></div></div><div><div><div>7</div></div><div><span>#表示几点做消息删除动作，默认是凌晨4点</span></div></div><div><div><div>8</div></div><div><span>deleteWhen</span><span> </span><span>=</span><span> </span><span>04</span></div></div><div><div><div>9</div></div><div><span>#在磁盘上保留消息的时长，单位是小时</span></div></div><div><div><div>10</div></div><div><span>fileReservedTime</span><span> </span><span>=</span><span> </span><span>48</span></div></div><div><div><div>11</div></div><div><span>#有三个值：SYNC_MASTER，ASYNC_MASTER，SLAVE；同步和异步表示Master和Slave之间同步数据的机制；</span></div></div><div><div><div>12</div></div><div><span>brokerRole</span><span> </span><span>=</span><span> </span><span>ASYNC_MASTER</span></div></div><div><div><div>13</div></div><div><span>#刷盘策略，取值为：ASYNC_FLUSH，SYNC_FLUSH表示同步刷盘和异步刷盘；SYNC_FLUSH消息写入磁盘后才返回成功状态，ASYNC_FLUSH不需要；</span></div></div><div><div><div>14</div></div><div><span>flushDiskType</span><span> </span><span>=</span><span> </span><span>ASYNC_FLUSH</span></div></div><div><div><div>15</div></div><div><span># 设置broker节点所在服务器的ip地址</span></div></div><div><div><div>16</div></div><div><span>brokerIP1</span><span> </span><span>=</span><span> </span><span>172.18.88.54</span></div></div><div><div><div>17</div></div><div><span># 磁盘使用达到95%之后,生产者再写入消息会报错 CODE: 14 DESC: service not available now, maybe disk full</span></div></div><div><div><div>18</div></div><div><span>diskMaxUsedSpaceRatio</span><span>=</span><span>95</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>构建broker容器<a href="#构建broker容器"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span>  </span><span>\</span></div></div><div><div><div>2</div></div><div><span>--restart=always </span><span>\</span></div></div><div><div><div>3</div></div><div><span>--name </span><span>rmqbroker</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>--link </span><span>rmqnamesrv:namesrv</span><span> </span><span>\</span></div></div><div><div><div>5</div></div><div><span>-p </span><span>10911:10911</span><span> </span><span>\</span></div></div><div><div><div>6</div></div><div><span>-p </span><span>10909:10909</span><span> </span><span>\</span></div></div><div><div><div>7</div></div><div><span>-v  </span><span>/docker/rocketmq/data/broker/logs:/root/logs</span><span> </span><span>\</span></div></div><div><div><div>8</div></div><div><span>-v  </span><span>/docker/rocketmq/data/broker/store:/root/store</span><span> </span><span>\</span></div></div><div><div><div>9</div></div><div><span>-v </span><span>/docker/rocketmq/conf/broker.conf:/opt/rocketmq-4.4.0/conf/broker.conf</span><span> </span><span>\</span></div></div><div><div><div>10</div></div><div><span>-e </span><span>"NAMESRV_ADDR=namesrv:9876"</span><span> </span><span>\</span></div></div><div><div><div>11</div></div><div><span>-e </span><span>"MAX_POSSIBLE_HEAP=200000000"</span><span> </span><span>\</span></div></div><div><div><div>12</div></div><div><span>apache/rocketmq </span><span>\</span></div></div><div><div><div>13</div></div><div><span>sh </span><span>mqbroker</span><span> </span><span>-c</span><span> </span><span>/opt/rocketmq-4.4.0/conf/broker.conf</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>-name rmqbroker | 把容器的名字设置为rmqbroker<br />
–link rmqnamesrv:namesrv | 和rmqnamesrv容器通信<br />
-p 10911&lt;10911&gt; | 把容器的非vip通道端口挂载到宿主机<br />
-p 10909&lt;10909&gt; | 把容器的vip通道端口挂载到宿主机<br />
-e “NAMESRV_ADDR=namesrv&lt;9876&gt;” | 指定namesrv的地址为本机namesrv的ip地址&lt;9876&gt;<br />
-e “MAX_POSSIBLE_HEAP=200000000” rocketmqinc/rocketmq sh mqbroker |指定broker服务的最大堆内存<br />
rocketmqinc/rocketmq | 使用的镜像名称<br />
sh mqbroker -c /opt/rocketmq-4.4.0/conf/broker.conf | 指定配置文件启动broker节点</p></blockquote></section></section><section><h3>创建rockermq-console服务<a href="#创建rockermq-console服务"><span>#</span></a></h3><section><h4>拉取镜像<a href="#拉取镜像-1"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>pull</span><span> </span><span>pangliang/rocketmq-console-ng</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>构建rockermq-console容器<a href="#构建rockermq-console容器"><span>#</span></a></h4><blockquote><p>需要替换<code>192.168.52.136</code> 为实际ip地址</p></blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-d</span><span> </span><span>\</span></div></div><div><div><div>2</div></div><div><span>--restart=always </span><span>\</span></div></div><div><div><div>3</div></div><div><span>--name </span><span>rmqadmin</span><span> </span><span>\</span></div></div><div><div><div>4</div></div><div><span>-e </span><span>"JAVA_OPTS=-Drocketmq.namesrv.addr=172.18.88.54:9876 </span><span>\</span></div></div><div><div><div>5</div></div><div><span>-Dcom.rocketmq.sendMessageWithVIPChannel=false"</span><span> </span><span>\</span></div></div><div><div><div>6</div></div><div><span>-p </span><span>10010:8080</span><span> </span><span>\</span></div></div><div><div><div>7</div></div><div><span>pangliang/rocketmq-console-ng</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>-restart=always| docker重启时候镜像自动重启<br />
-name rmqadmin | 把容器的名字设置为rmqadmin<br />
-e “JAVA_OPTS=-Drocketmq.namesrv.addr=192.168.52.136&lt;9876&gt; | 设置namesrv服务的ip地址<br />
-Dcom.rocketmq.sendMessageWithVIPChannel=false” | 不使用vip通道发送消息<br />
–p 10010&lt;8080&gt; | 把容器内的端口8080挂载到宿主机上的9999端口</p></blockquote></section><section><h4>开放端口  9876/10911/10010<a href="#开放端口--98761091110010"><span>#</span></a></h4></section><section><h4>创建系统服务<a href="#创建系统服务"><span>#</span></a></h4><section><h5>1、 编写管理脚本命令，vi /etc/init.d/rocketmq<a href="#1-编写管理脚本命令vi-etcinitdrocketmq"><span>#</span></a></h5><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/bin/sh</span></div></div><div><div><div>2</div></div><div><span>#</span></div></div><div><div><div>3</div></div><div><span># rocketmq - this script starts and stops the rocketmq daemon</span></div></div><div><div><div>4</div></div><div><span>#</span></div></div><div><div><div>5</div></div><div><span># chkconfig: - 85 15</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>ROCKETMQ_HOME</span><span>=</span><span>/home/sys_wh/soft/rocketmq-5.1.4</span></div></div><div><div><div>8</div></div><div><span>ROCKETMQ_BIN</span><span>=</span><span><span>${</span><span>ROCKETMQ_HOME</span><span>}</span></span><span>/bin</span></div></div><div><div><div>9</div></div><div><span>ADDR</span><span>=</span><span>192.168.0.75:9876</span></div></div><div><div><div>10</div></div><div><span>LOG_DIR</span><span>=</span><span><span>${</span><span>ROCKETMQ_HOME</span><span>}</span></span><span>/logs</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>start</span><span>() {</span></div></div><div><div><div>13</div></div><div><span>if</span><span><span> [ </span><span>!</span><span> </span><span>-d</span><span> </span></span><span><span>${</span><span>LOG_DIR</span><span>}</span></span><span> ];</span><span>then</span></div></div><div><div><div>14</div></div><div><span>mkdir</span><span> </span><span><span>${</span><span>LOG_DIR</span><span>}</span></span></div></div><div><div><div>15</div></div><div><span>fi</span></div></div><div><div><div>16</div></div><div><span>cd</span><span> </span><span><span>${</span><span>ROCKETMQ_HOME</span><span>}</span></span></div></div><div><div><div>17</div></div><div><span>nohup</span><span> </span><span>sh</span><span> </span><span>bin/mqnamesrv</span><span> &gt; </span><span><span>${</span><span>LOG_DIR</span><span>}</span></span><span>/mqnamesrv.log</span><span> 2&gt;&amp;1 &amp;</span></div></div><div><div><div>18</div></div><div><span>echo</span><span> </span><span>-n</span><span> </span><span>"The Name Server boot success..."</span></div></div><div><div><div>19</div></div><div><span>nohup</span><span> </span><span>sh</span><span> </span><span>bin/mqbroker</span><span> </span><span>-c</span><span> </span><span><span>${</span><span>ROCKETMQ_HOME</span><span>}</span></span><span>/conf/broker.conf</span><span> &gt;</span><span><span>${</span><span>LOG_DIR</span><span>}</span></span><span>/broker.log</span><span> 2&gt;&amp;1 &amp;</span></div></div><div><div><div>20</div></div><div><span>echo</span><span> </span><span>-n</span><span> </span><span>"The broker[%s, </span><span><span>${</span><span>ADDR</span><span>}</span></span><span>] boot success..."</span></div></div><div><div><div>21</div></div><div><span>}</span></div></div><div><div><div>22</div></div><div><span>stop</span><span>() {</span></div></div><div><div><div>23</div></div><div><span>cd</span><span> </span><span><span>${</span><span>ROCKETMQ_HOME</span><span>}</span></span></div></div><div><div><div>24</div></div><div><span>sh</span><span> </span><span>bin/mqshutdown</span><span> </span><span>broker</span></div></div><div><div><div>25</div></div><div><span>sleep</span><span> </span><span>1</span></div></div><div><div><div>26</div></div><div><span>sh</span><span> </span><span>bin/mqshutdown</span><span> </span><span>namesrv</span></div></div><div><div><div>27</div></div><div><span>}</span></div></div><div><div><div>28</div></div><div><span>restart</span><span>() {</span></div></div><div><div><div>29</div></div><div><span>stop</span></div></div><div><div><div>30</div></div><div><span>sleep</span><span> </span><span>5</span></div></div><div><div><div>31</div></div><div><span>start</span></div></div><div><div><div>32</div></div><div><span>}</span></div></div><div><div><div>33</div></div><div>
</div></div><div><div><div>34</div></div><div>
</div></div><div><div><div>35</div></div><div><span>case</span><span> </span><span>"</span><span>$1</span><span>"</span><span> </span><span>in</span></div></div><div><div><div>36</div></div><div><span>start</span><span>)</span></div></div><div><div><div>37</div></div><div><span>start</span></div></div><div><div><div>38</div></div><div><span>;;</span></div></div><div><div><div>39</div></div><div><span>stop</span><span>)</span></div></div><div><div><div>40</div></div><div><span>stop</span></div></div><div><div><div>41</div></div><div><span>;;</span></div></div><div><div><div>42</div></div><div><span>restart</span><span>)</span></div></div><div><div><div>43</div></div><div><span>restart</span></div></div><div><div><div>44</div></div><div><span>;;</span></div></div><div><div><div>45</div></div><div><span>*)</span></div></div><div><div><div>46</div></div><div><span>echo</span><span> </span><span>$"Usage: </span><span>$0</span><span> {start|stop|restart}"</span></div></div><div><div><div>47</div></div><div><span>exit</span><span> </span><span>2</span></div></div><div><div><div>48</div></div><div><span>esac</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><blockquote><p>注意：</p></blockquote><p>1.1 注： 复制这个脚本到Linux可能会丢失最上面的一部分，不知道为什么，通过xshell打开Linux，然后复制这些内容到文件中，会丢失一部分，自己复制过去以后检查清楚是否丢失一些内容。不然就算注册成一个服务也没法用。</p><p>1.2 ROCKETMQ_HOME的地址、利用nohup启动broker是指定启动的配置文件都要写对</p></section><section><h5>2、将rocketmq服务添加为开机启动服务<a href="#2将rocketmq服务添加为开机启动服务"><span>#</span></a></h5><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>chmod</span><span> </span><span>+x</span><span> </span><span>/etc/init.d/rocketmq</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>chkconfig</span><span> </span><span>--add</span><span> </span><span>rocketmq</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>再运行chkconfig —list查看是否出现以下内容，出现则代表加入成功了</p></blockquote><p>注：若出现下图0-6都是关，那代表还不能开机自启，再运行 <code>chkconfig rocketmq on</code>，然后再运行chkconfig —list以后2-5都是开以后才行。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@host-172-20-42-212 rocketmq-5.1.2]# chkconfig --list</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>Note:</span><span> </span><span>This</span><span> </span><span>output</span><span> </span><span>shows</span><span> </span><span>SysV</span><span> </span><span>services</span><span> </span><span>only</span><span> </span><span>and</span><span> </span><span>does</span><span> </span><span>not</span><span> </span><span>include</span><span> </span><span>native</span></div></div><div><div><div>4</div></div><div><span>      </span><span>systemd</span><span> </span><span>services.</span><span> </span><span>SysV</span><span> </span><span>configuration</span><span> </span><span>data</span><span> </span><span>might</span><span> </span><span>be</span><span> </span><span>overridden</span><span> </span><span>by</span><span> </span><span>native</span></div></div><div><div><div>5</div></div><div><span>      </span><span>systemd</span><span> </span><span>configuration.</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>      </span><span>If</span><span> </span><span>you</span><span> </span><span>want</span><span> </span><span>to</span><span> </span><span>list</span><span> </span><span>systemd</span><span> </span><span>services</span><span> </span><span>use</span><span> </span><span>'systemctl list-unit-files'.</span></div></div><div><div><div>8</div></div><div><span>      </span><span>To</span><span> </span><span>see</span><span> </span><span>services</span><span> </span><span>enabled</span><span> </span><span>on</span><span> </span><span>particular</span><span> </span><span>target</span><span> </span><span>use</span></div></div><div><div><div>9</div></div><div><span>      </span><span>'systemctl list-dependencies [target]'</span><span>.</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>rocketmq</span><span>         </span><span>0:off</span><span>  </span><span>1:off</span><span>  </span><span>2:off</span><span>  </span><span>3:off</span><span>  </span><span>4:off</span><span>  </span><span>5:off</span><span>  </span><span>6:off</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h5>3、通过service命令来管理rocketmq<a href="#3通过service命令来管理rocketmq"><span>#</span></a></h5><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 启动</span></div></div><div><div><div>2</div></div><div><span>service</span><span> </span><span>rocketmq</span><span> </span><span>start</span></div></div><div><div><div>3</div></div><div><span># 关闭</span></div></div><div><div><div>4</div></div><div><span>service</span><span> </span><span>rocketmq</span><span> </span><span>stop</span></div></div><div><div><div>5</div></div><div><span># 重启</span></div></div><div><div><div>6</div></div><div><span>service</span><span> </span><span>rocketmq</span><span> </span><span>restart</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>--</span><span> </span><span>启动namesrv</span></div></div><div><div><div>2</div></div><div><span>nohup</span><span> </span><span>sh</span><span> </span><span>/home/sys_wh/soft/rocketmq-5.1.4/bin/mqnamesrv</span><span> &gt; </span><span>/home/sys_wh/soft/rocketmq-5.1.4/logs/mqnamesrv.log</span><span> 2&gt;&amp;1 &amp;</span></div></div><div><div><div>3</div></div><div><span>--</span><span> </span><span>验证是否成功</span></div></div><div><div><div>4</div></div><div><span>tail</span><span> </span><span>-f</span><span> </span><span>/home/sys_wh/soft/rocketmq-5.1.4/logs/mqnamesrv.log</span></div></div><div><div><div>5</div></div><div><span>--</span><span> </span><span>启动broker</span></div></div><div><div><div>6</div></div><div><span>nohup</span><span> </span><span>sh</span><span> </span><span>/home/sys_wh/soft/rocketmq-5.1.4/bin/mqbroker</span><span> </span><span>-c</span><span> </span><span>/home/sys_wh/soft/rocketmq-5.1.4/conf/broker.conf</span><span> &gt;</span><span>/home/sys_wh/soft/rocketmq-5.1.4/logs/broker.log</span><span> 2&gt;&amp;1 &amp;</span></div></div><div><div><div>7</div></div><div><span>--</span><span> </span><span>验证是否成功</span></div></div><div><div><div>8</div></div><div><span>tail</span><span> </span><span>-f</span><span> </span><span>/home/sys_wh/soft/rocketmq-5.1.4/logs/broker.log</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>--停止broker</span></div></div><div><div><div>11</div></div><div><span>sh</span><span> </span><span>/home/sys_wh/soft/rocketmq-5.1.4/bin/mqshutdown</span><span> </span><span>broker</span></div></div><div><div><div>12</div></div><div><span>--停止</span><span> </span><span>namesrv</span></div></div><div><div><div>13</div></div><div><span>sh</span><span> </span><span>/home/sys_wh/soft/rocketmq-5.1.4/bin/mqshutdown</span><span> </span><span>namesrv</span></div></div><div><div><div>14</div></div><div><span>--</span><span> </span><span>启动管理平台</span></div></div><div><div><div>15</div></div><div><span>nohup</span><span> </span><span>java</span><span> </span><span>-jar</span><span> </span><span>rocketmq-dashboard-1.0.0.jar</span><span>   &gt; </span><span>dashboard.log</span><span> 2&gt;&amp;1 &amp;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>4、设置密码</p><p>4.1 开启acl控制</p><p>在<code>conf/broker.conf</code>中开启<code>aclEnable=true</code></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>vim</span><span> </span><span>conf/broker.conf</span></div></div><div><div><div>2</div></div><div><span># 最下面增加下面一行</span></div></div><div><div><div>3</div></div><div><span>aclEnable</span><span>=</span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>4.2 配置账号密码</p><p>修改<code>conf/plain_acl.yml</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>accounts:</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span># 管理员账号/密码</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>accessKey: catsicrocketmq</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>secretKey: Catsic1qsx@WDC</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>4.3 配置面板中的密码</p><p>	在dashboard.jar包同级目录创建config文件夹，将项目底下的application.properties上传到config文件夹下，将注释放开，设置对应的账号密码。修改后重启</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>rocketmq.config.accessKey=catsicrocketmq</span></div></div><div><div><div>2</div></div><div><span>rocketmq.config.secretKey=Catsic1qsx@WDC</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>4.4 当前，已经为RocketMQ设置了密码，但是，还存在问题，操作面板没有设置密码，操作面板没有设置密码，在实际应用中，也是很危险的。下面讲解面板设置密码：</p><p>4.5 开启账号密码访问</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 修改application.properties</span></div></div><div><div><div>2</div></div><div><span># 是否开启账号密码验证</span></div></div><div><div><div>3</div></div><div><span>rocketmq.config.loginRequired= true</span></div></div><div><div><div>4</div></div><div><span># 账号密码配置文件为：users.properties，将users.properties上传到config目录，修改内容为</span></div></div><div><div><div>5</div></div><div><span># ,1 为管理员，不加为普通用户</span></div></div><div><div><div>6</div></div><div><span>catstiMQ=catsti1qaz@WSX,1</span></div></div><div><div><div>7</div></div><div><span># 修改默认用户配置文件路径</span></div></div><div><div><div>8</div></div><div><span>vim application.properties</span></div></div><div><div><div>9</div></div><div><span># 将其修改为：</span></div></div><div><div><div>10</div></div><div><span>rocketmq.config.dataPath=./config</span></div></div><div><div><div>11</div></div><div><span># 重启dashboard</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/4a0c2abb/</id>
      <title type="text">【Linux】安装OpenJDK</title>
      <published>2024-05-21T08:31:13.000Z</published>
      <updated>2024-05-21T08:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/4a0c2abb/"/>
      <summary type="text">本文详细介绍了在Linux系统上安装OpenJDK的方法，包括在线安装和离线安装两种方式。在线安装部分，首先检查系统中是否已存在Java环境，然后使用yum命令安装OpenJDK，并配置环境变量。离线安装部分，适用于无外网的集群环境，需预先下载OpenJDK二进制包，上传至指定目录，解压并配置环境变量。</summary>
      <content type="html"><![CDATA[<section><h2>【Linux】 安装OpenJDK<a href="#linux-安装openjdk"><span>#</span></a></h2><blockquote><p>本文详细介绍了在Linux系统上安装OpenJDK的方法，包括在线安装和离线安装两种方式。在线安装部分，首先检查系统中是否已存在Java环境，然后使用yum命令安装OpenJDK，并配置环境变量。离线安装部分，适用于无外网的集群环境，需预先下载OpenJDK二进制包，上传至指定目录，解压并配置环境变量。通过本文的指导，读者可以轻松地在Linux系统上安装和配置OpenJDK，确保Java应用程序的正常运行。</p></blockquote></section>
<section><h2>在线安装<a href="#在线安装"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>### a) 检查系统中是否有java环境</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>​                    <code>rpm -qa | grep java</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>### b) 使用yum安装/升级OpenJDK：</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>​                    <code>yum -y install java-1.8.0-openjdk-devel</code>
​    ### c) 查找OpenJDK安装路径：
​                    <code>[root@node01 ~]# which java       //找到java的执行路径</code></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>/usr/bin/java</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>[root@node01 ~]# ls -lrt /usr/bin/java       //执行路径指向环境的软连接</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>lrwxrwxrwx</span><span> </span><span>1</span><span> </span><span>root</span><span> </span><span>root</span><span> </span><span>22</span><span> </span><span>Sep</span><span> </span><span>10</span><span> </span><span>21:23</span><span> </span><span>/usr/bin/java</span><span> -&gt; </span><span>/etc/alternatives/java</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>[root@node01 ~]# ls -lrt /etc/alternatives/java     //最终指向安装路径</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>lrwxrwxrwx</span><span> </span><span>1</span><span> </span><span>root</span><span> </span><span>root</span><span> </span><span>73</span><span> </span><span>Sep</span><span> </span><span>10</span><span> </span><span>21:23</span><span> </span><span>/etc/alternatives/java</span><span> -&gt; </span><span>/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.302.b08-0.el7_9.x86_64/jre/bin/java</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h3>d) 配置环境变量（规范配置方法）：<a href="#d-配置环境变量规范配置方法"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@node01 java]# vi /etc/profile.d/my_env.sh</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span># 添加如下环境变量：</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>#JAVA_HOME</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>export</span><span> </span><span>JAVA_HOME</span><span><span>=</span><span>/</span></span><span>usr</span><span>/</span><span>lib</span><span>/</span><span>jvm</span><span>/</span><span>jre-1</span><span>.</span><span>8</span><span>.</span><span>0-openjdk-1</span><span>.</span><span>8</span><span>.</span><span>0</span><span>.</span><span>322</span><span>.</span><span>b06-1</span><span>.</span><span>el7_9</span><span>.</span><span>x86_64</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>export</span><span> </span><span>PATH</span><span>=</span><span>$PATH</span><span>:</span><span>$JAVA_HOME</span><span>/</span><span>bin</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>e) 保存退出后刷新配置（或重启Xshell窗口）：<a href="#e-保存退出后刷新配置或重启xshell窗口"><span>#</span></a></h3><p>[root@node01 java]# source /etc/profile.d/my_env.sh</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@node01 ~]# java -version</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>openjdk</span><span> </span><span>version</span><span> </span><span>"1.8.0_302"</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>OpenJDK</span><span> </span><span>Runtime</span><span> </span><span>Environment</span><span> (build </span><span>1.8.0_302-b08</span><span>)</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>OpenJDK</span><span> </span><span>64-Bit</span><span> </span><span>Server</span><span> </span><span>VM</span><span> (build </span><span>25.302-b08,</span><span> </span><span>mixed</span><span> </span><span>mode</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>离线安装<a href="#离线安装"><span>#</span></a></h2><section><h3>a) 若集群无外网，则可以使用OpenJDK二进制包进行离线部署。预先下载OpenJDK 1.8.0_41-b04：<a href="#a-若集群无外网则可以使用openjdk二进制包进行离线部署预先下载openjdk-180_41-b04"><span>#</span></a></h3><blockquote><p><a href="https://download.java.net/openjdk/jdk8u41/ri/openjdk-8u41-b04-linux-x64-14_jan_2020.tar.gz" target="_blank">下载地址</a></p></blockquote></section><section><h3>b) 检查当前系统中是否已有Java运行环境（JRE），若有，执行卸载：<a href="#b-检查当前系统中是否已有java运行环境jre若有执行卸载"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@node01 ~]# rpm -qa | </span><span>grep</span><span> </span><span>java</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>c) 卸载自带JRE命令(如无跳过)：<a href="#c-卸载自带jre命令如无跳过"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@node01 ~]# yum -y remove java*</span></div></div><div><div><div>2</div></div><div><span>[root@node01 ~]# yum -y remove tzdata-java*</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>d) 将openjdk-8u41-b04-linux-x64-14_jan_2020.tar.gz上传至/opt/software目录下：<a href="#d-将openjdk-8u41-b04-linux-x64-14_jan_2020targz上传至optsoftware目录下"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span><span>  </span></span><span>[root@node01 ~]# mkdir /opt/software</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>e) 解压、将解压后的目录转移至/usr/java/下：<a href="#e-解压将解压后的目录转移至usrjava下"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>                </span></span><span>#### 解压</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@node01 software]# tar xf openjdk-8u41-b04-linux-x64-14_jan_2020.tar.gz</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>                </span></span><span>#### 将解压后的目录转移至/usr/java/下：</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@node01 software]# mv /opt/software/java-se-8u41-ri /usr/java</span></div></div><div><div><div>2</div></div><div><span>[root@node01 software]# cd /usr/java</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>[root@node01 java]# ll</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>total</span><span> </span><span>0</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span>drwxr-xr-x</span><span> </span><span>9</span><span> </span><span>10</span><span> </span><span>143</span><span> </span><span>219</span><span> </span><span>Jan</span><span> </span><span>15</span><span>  </span><span>2020</span><span> </span><span>java-se-8u41-ri</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>f) 配置环境变量（规范配置方法）：<a href="#f-配置环境变量规范配置方法"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@node01 java]# vi /etc/profile.d/my_env.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>g) 添加如下环境变量：<a href="#g-添加如下环境变量"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#JAVA_HOME</span></div></div><div><div><div>2</div></div><div><span>export JAVA_HOME=/usr/java/java-se-8u41-ri</span></div></div><div><div><div>3</div></div><div><span>export PATH=$PATH:$JAVA_HOME/bin</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>h) 保存退出后刷新配置（或重启Xshell窗口）：<a href="#h-保存退出后刷新配置或重启xshell窗口"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@node01 java]# source /etc/profile.d/my_env.sh</span></div></div><div><div><div>2</div></div><div><span>[root@node01 ~]# java -version</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>openjdk</span><span> </span><span>version</span><span> </span><span>"1.8.0_41"</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>OpenJDK</span><span> </span><span>Runtime</span><span> </span><span>Environment</span><span> (build </span><span>1.8.0_41-b04</span><span>)</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span>OpenJDK</span><span> </span><span>64-Bit</span><span> </span><span>Server</span><span> </span><span>VM</span><span> (build </span><span>25.40-b25,</span><span> </span><span>mixed</span><span> </span><span>mode</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/599fe741/</id>
      <title type="text">【Linux】manjaro 环境配置</title>
      <published>2024-05-21T08:31:13.000Z</published>
      <updated>2024-05-21T08:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/599fe741/"/>
      <summary type="text">本文《Manjaro 环境配置》详细介绍了在Manjaro Linux系统中进行环境配置的各种方法。文章首先介绍了常用的Pacman包管理命令，包括软件的安装、更新、删除等操作。这些内容对于初学者和有一定经验的用户都非常有帮助，能够快速搭建一个高效、美观的Manjaro环境。</summary>
      <content type="html"><![CDATA[<section><h3>常用语法<a href="#常用语法"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#安装软件</span></div></div><div><div><div>2</div></div><div><span>pacman -S 包名 ...</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>#给所有提示设置选项</span></div></div><div><div><div>5</div></div><div><span>yes | sudo pacman -S 包名 ...</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>#只下载包，不安装</span></div></div><div><div><div>8</div></div><div><span>pacman -Sw 包名 ...</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>#清理未安装的包文件，包文件位于 /var/cache/pacman/pkg/ 目录</span></div></div><div><div><div>11</div></div><div><span>pacman -Sc</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>#清理所有的缓存文件</span></div></div><div><div><div>14</div></div><div><span>pacman -Scc</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span>#删除单个软件包，保留其全部已经安装的依赖关系</span></div></div><div><div><div>17</div></div><div><span>pacman -R 包名</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>#删除指定软件包，及其所有没有被其他已安装软件包使用的依赖关系</span></div></div><div><div><div>20</div></div><div><span>pacman -Rs 包名</span></div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span>#在删除包的同时，删除所有依赖这个软件包的程序</span></div></div><div><div><div>23</div></div><div><span>pacman -Rsc 包名</span></div></div><div><div><div>24</div></div><div>
</div></div><div><div><div>25</div></div><div><span>#在删除包时不检查依赖</span></div></div><div><div><div>26</div></div><div><span>pacman -Rd 包名</span></div></div><div><div><div>27</div></div><div>
</div></div><div><div><div>28</div></div><div><span>#更新所有包 y更新数据库，yy强制更新，u升级软件</span></div></div><div><div><div>29</div></div><div><span>pacman -Syu</span></div></div><div><div><div>30</div></div><div>
</div></div><div><div><div>31</div></div><div><span>#在数据库中查询软件包，查询位置包含了包的名字和描述</span></div></div><div><div><div>32</div></div><div><span>pacman -Ss 关键字</span></div></div><div><div><div>33</div></div><div>
</div></div><div><div><div>34</div></div><div><span>#获取已安装软件包所包含文件的列表</span></div></div><div><div><div>35</div></div><div><span>pacman -Ql</span></div></div><div><div><div>36</div></div><div>
</div></div><div><div><div>37</div></div><div><span>#从本地安装软件包</span></div></div><div><div><div>38</div></div><div><span>pacman -U xxx.tar.gz</span></div></div><div><div><div>39</div></div><div>
</div></div><div><div><div>40</div></div><div><span>#显示软件包依赖树</span></div></div><div><div><div>41</div></div><div><span>pactree 包名</span></div></div><div><div><div>42</div></div><div>
</div></div><div><div><div>43</div></div><div><span># 卸载所有无用包</span></div></div><div><div><div>44</div></div><div><span>pacman -c</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>
<section><h3>系统配置<a href="#系统配置"><span>#</span></a></h3><section><h4>设置中国源<a href="#设置中国源"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 排列中国源</span></div></div><div><div><div>2</div></div><div><span>sudo pacman-mirrors -i -c China -m rank</span></div></div><div><div><div>3</div></div><div><span># 选择中科大、阿里、华为等</span></div></div><div><div><div>4</div></div><div><span>https://mirrors.ustc.edu.cn/manjaro/</span></div></div><div><div><div>5</div></div><div><span># 同步软件包数据库</span></div></div><div><div><div>6</div></div><div><span>sudo pacman -Syy</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span>sudo gedit /etc/pacman.conf</span></div></div><div><div><div>9</div></div><div><span>在打开的文件的末尾添加如下内容：</span></div></div><div><div><div>10</div></div><div><span>[archlinuxcn]</span></div></div><div><div><div>11</div></div><div><span>SigLevel = Optional TrustedOnly</span></div></div><div><div><div>12</div></div><div><span>Server = https://mirrors.ustc.edu.cn/archlinuxcn/$arch</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>修改好上述两个部分后，终端执行下面的指令：</span></div></div><div><div><div>15</div></div><div><span>sudo pacman -Syy</span></div></div><div><div><div>16</div></div><div><span># 安装秘钥</span></div></div><div><div><div>17</div></div><div><span>sudo pacman -S archlinuxcn-keyring</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>时间同步<a href="#时间同步"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 安装openNTPD</span></div></div><div><div><div>2</div></div><div><span>sudo pacman -S openntpd</span></div></div><div><div><div>3</div></div><div><span># 重启openNTPD</span></div></div><div><div><div>4</div></div><div><span>systemctl restart openntpd</span></div></div><div><div><div>5</div></div><div><span># 设置开机启动</span></div></div><div><div><div>6</div></div><div><span>systemctl enable openntpd</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h3>软件安装<a href="#软件安装"><span>#</span></a></h3><section><h4>安装yay<a href="#安装yay"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 安装aur工具</span></div></div><div><div><div>2</div></div><div><span>sudo pacman -S yay</span></div></div><div><div><div>3</div></div><div><span># 设置中国源</span></div></div><div><div><div>4</div></div><div><span>yay --aururl "https://aur.tuna.tsinghua.edu.cn" --save</span></div></div><div><div><div>5</div></div><div><span># 验证是否成功</span></div></div><div><div><div>6</div></div><div><span>yay -P -g</span></div></div><div><div><div>7</div></div><div><span># 更新包</span></div></div><div><div><div>8</div></div><div><span>yay -Syu</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>安装base-devel<a href="#安装base-devel"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 建议提前安装基础包，避免安装其他包时出现依赖错误</span></div></div><div><div><div>2</div></div><div><span>sudo pacman -S base-devel</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>安装vim<a href="#安装vim"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>yay -S vim</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>安装chrom<a href="#安装chrom"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>yay -S google-chrome</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>安装输入法<a href="#安装输入法"><span>#</span></a></h4><section><h5>fcitx+搜狗<a href="#fcitx搜狗"><span>#</span></a></h5><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 输入法对比：https://wiki.archlinux.org/index.php/Fcitx_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#%E4%B8%AD%E6%96%87</span></div></div><div><div><div>2</div></div><div><span># 安装输入法需要的依赖</span></div></div><div><div><div>3</div></div><div><span>yay -S fcitx-im fcitx-configtool fcitx-qt4</span></div></div><div><div><div>4</div></div><div><span># 编辑 ~/.pam_environment（不存在就添加），添加以下内容：</span></div></div><div><div><div>5</div></div><div><span>GTK_IM_MODULE=fcitx</span></div></div><div><div><div>6</div></div><div><span>QT_IM_MODULE=fcitx</span></div></div><div><div><div>7</div></div><div><span>XMODIFIERS=@im=fcitx</span></div></div><div><div><div>8</div></div><div><span># 安装搜狗输入法需要的依赖</span></div></div><div><div><div>9</div></div><div><span>yay -S qtwebkit-bin</span></div></div><div><div><div>10</div></div><div><span># 安装搜狗输入法</span></div></div><div><div><div>11</div></div><div><span>yay -S fcitx-sogoupinyin</span></div></div><div><div><div>12</div></div><div><span># 解决搜狗输入法候选项乱码</span></div></div><div><div><div>13</div></div><div><span>cd ~/.config</span></div></div><div><div><div>14</div></div><div><span>sudo rm -rf SogouPY* sogou*</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h5>fctix5+rime<a href="#fctix5rime"><span>#</span></a></h5><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>先用这个</span></div></div><div><div><div>2</div></div><div><span>sudo pacman -S fcitx-rime</span></div></div><div><div><div>3</div></div><div><span>sudo pacman -S fcitx-im</span></div></div><div><div><div>4</div></div><div><span>sudo pacman -S fcitx-configtool</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>然后你需要编辑一个文件：</span></div></div><div><div><div>7</div></div><div><span>sudo gedit ~/.xprofile</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>在文件末尾添加如下文本：</span></div></div><div><div><div>10</div></div><div><span>export GTK_IM_MODULE=fcitx</span></div></div><div><div><div>11</div></div><div><span>export QT_IM_MODULE=fcitx</span></div></div><div><div><div>12</div></div><div><span>export XMODIFIERS="@im=fcitx"</span></div></div><div><div><div>13</div></div><div><span>重启一下系统</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span># 如果上述不可以再使用yay安装，有些包pacman没有</span></div></div><div><div><div>19</div></div><div><span>yay -S fcitx5-git fcitx5-config-qt-git fcitx5-gtk-git fcitx5-rime-git</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h5>配置<a href="#配置"><span>#</span></a></h5><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 编辑 ~/.pam_environment（不存在就添加），添加以下内容：</span></div></div><div><div><div>2</div></div><div><span>GTK_IM_MODULE=fcitx5</span></div></div><div><div><div>3</div></div><div><span>QT_IM_MODULE=fcitx5</span></div></div><div><div><div>4</div></div><div><span>XMODIFIERS=@im=fcitx5</span></div></div><div><div><div>5</div></div><div><span>fcitx5 &amp;</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h5>开机自起<a href="#开机自起"><span>#</span></a></h5><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo cp /usr/share/applications/fcitx5.desktop /etc/xdg/autostart/</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h5>rime配置<a href="#rime配置"><span>#</span></a></h5><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 如果没有写权限，需要先赋予权限</span></div></div><div><div><div>2</div></div><div><span>sudo vim /usr/share/rime-data/build/luna_pinyin.schema.yaml</span></div></div><div><div><div>3</div></div><div><span>#配置候选数量</span></div></div><div><div><div>4</div></div><div><span>menu:</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>page_size: 10</span></div></div><div><div><div>6</div></div><div><span>#设置默认为简体</span></div></div><div><div><div>7</div></div><div><span>#定位这一行</span></div></div><div><div><div>8</div></div><div><span>- name: simplification</span></div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>#在下方增加如下配置</span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>reset: 1</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h4>安装deepin移植的微信<a href="#安装deepin移植的微信"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>yay -S deepin-wine-wechat</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>安装qq &amp;&amp; TIM<a href="#安装qq--tim"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>安装QQ：</span></div></div><div><div><div>2</div></div><div><span>sudo pacman -S deepin.com.qq.office</span></div></div><div><div><div>3</div></div><div><span>||</span></div></div><div><div><div>4</div></div><div><span>sudo pacman -S com.qq.weixin.spark</span></div></div><div><div><div>5</div></div><div><span>安装Tim：</span></div></div><div><div><div>6</div></div><div><span>sudo pacman -S deepin.com.qq.im</span></div></div><div><div><div>7</div></div><div><span>||</span></div></div><div><div><div>8</div></div><div><span>sudo pacman -S com.qq.tim.spark</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>安装typora<a href="#安装typora"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>yay -S typora</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>百度网盘<a href="#百度网盘"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>yay -S baidunetdisk-bin</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>安装深度截图<a href="#安装深度截图"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#安装</span></div></div><div><div><div>2</div></div><div><span>sudo pacman -S deepin-screenshot</span></div></div><div><div><div>3</div></div><div><span>#设置快捷键</span></div></div><div><div><div>4</div></div><div><span>系统设置---&gt;工作区---&gt;快捷键---&gt;自定义快捷键---&gt;编辑---&gt;新建---&gt;全局快捷键---&gt;命令URL---&gt;命名/触发器(快捷键)/动作(deepin-screenshot)</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>安装idea<a href="#安装idea"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>下载idea</span></div></div><div><div><div>2</div></div><div><span>wget https://download.jetbrains.8686c.com/idea/ideaIC-2020.1.3.tar.gz</span></div></div><div><div><div>3</div></div><div><span>解压</span></div></div><div><div><div>4</div></div><div><span>tar -zxvf ideaIC-2020.1.3.tar.gz</span></div></div><div><div><div>5</div></div><div><span>安装</span></div></div><div><div><div>6</div></div><div><span>bin/idea.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>安装网易云音乐<a href="#安装网易云音乐"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>yay -S netease-cloud-music</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>安装vscode<a href="#安装vscode"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>yay -S visual-studio-code-bin</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>安装git<a href="#安装git"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>yay -S git</span></div></div><div><div><div>2</div></div><div><span>yay -S gitkraken</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h5>安装NodeJS<a href="#安装nodejs"><span>#</span></a></h5><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 安装nodejs</span></div></div><div><div><div>2</div></div><div><span>sudo pacman -S nodejs</span></div></div><div><div><div>3</div></div><div><span># 安装npm</span></div></div><div><div><div>4</div></div><div><span>sudo pacman -S npm</span></div></div><div><div><div>5</div></div><div><span># 安装cnpm源</span></div></div><div><div><div>6</div></div><div><span>sudo npm install -g cnpm --registry=https://registry.npm.taobao.org</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h4>安装wps<a href="#安装wps"><span>#</span></a></h4><section><h5>自动安装<a href="#自动安装"><span>#</span></a></h5><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#如果以下方式不行  使用yay试试</span></div></div><div><div><div>2</div></div><div><span>sudo pacman -S wps-office ttf-wps-fonts</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h5>手动安装<a href="#手动安装"><span>#</span></a></h5><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 去官网下载安装deb包</span></div></div><div><div><div>2</div></div><div><span>https://linux.wps.cn/</span></div></div><div><div><div>3</div></div><div><span># 安装debtap</span></div></div><div><div><div>4</div></div><div><span>yay -S debtap</span></div></div><div><div><div>5</div></div><div><span>#安装字体依赖</span></div></div><div><div><div>6</div></div><div><span>sudo pacman -S ttf-wps-fonts c</span></div></div><div><div><div>7</div></div><div><span># 更新debtap</span></div></div><div><div><div>8</div></div><div><span>sudo debtap -u</span></div></div><div><div><div>9</div></div><div><span># 静默模式转换安装包  根据提示输入包名随便写   license写GPL</span></div></div><div><div><div>10</div></div><div><span>debtap -q xxx.deb</span></div></div><div><div><div>11</div></div><div><span># 安装 如果提示缺少依赖  先安装依赖  再手动安装包</span></div></div><div><div><div>12</div></div><div><span>sudo pacman -U xxx.tar.zst</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section>
<section><h3>系统美化<a href="#系统美化"><span>#</span></a></h3><section><h4>安装latte-dock<a href="#安装latte-dock"><span>#</span></a></h4><blockquote><p><code>yay -S latte-dock</code> <br />
添加一个新空面板，默认会出现在上面，然后删除下面这个面板
在新面板上添加必要的部件：应用程序面板，数字时钟，托盘图标
还可以加全局菜单，显示面板等等<br />
启动<code>latte-dock</code>，下方就会出现一个dock栏，具体配置看自己爱好</p></blockquote></section><section><h4>配置ohmyzsh <a href="https://github.com/zsh-users" target="_blank">插件地址</a><a href="#配置ohmyzsh-插件地址"><span>#</span></a></h4><blockquote><p>1、首先修改默认shell为zsh:<br />
<code>chsh -s /usr/bin/zsh</code> <br />
安装ohmyzsh <br />
wget <a href="https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh" target="_blank">https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh</a> -O - | sh <br />
如果每次执行都失败提示被拒绝连接就先改一下hosts文件<br />
<code> sudo nano /etc/hosts</code> <br />
把这段话复制到下面 <br /></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># GitHub Start</span></div></div><div><div><div>2</div></div><div><span>151.101.64.133 raw.githubusercontent.com</span></div></div><div><div><div>3</div></div><div><span># GitHub End</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>2、安装zsh-syntax-highlighting：提供命令高亮</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>3、安装autosuggestions：记住你之前使用过的命令</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>git clone git://github.com/zsh-users/zsh-autosuggestions ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>4、安装incr：（需要注意的是这个插件会拖慢zsh的速度，新手入门可以试试）</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>git clone git://github.com/makeitjoe/incr.zsh $ZSH_CUSTOM/plugins/incr</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>5、启用所有插件</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>nano ~/.zshrc</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>将plugins=(git)改为:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>plugins=(git zsh-syntax-highlighting zsh-autosuggestions incr sudo extract)</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>6、重载配置
<code> source ~/.zshrc</code>
如果想要卸载 oh my zsh，直接执行下面命令<br />
<code> uninstall oh my zsh</code></p></blockquote></section><section><h4>优化grub主题<a href="#优化grub主题"><span>#</span></a></h4><blockquote><p>准备好主题文档夹，可以在<a href="https://www.gnome-look.org/browse/cat/109/ord/latest/" target="_blank">Grub Themes</a>挑选下载<br />
1、将主题文档夹移至/boot/grub/themes/下<br /></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>$ sudo mv -r YourTheme /boot/grub/themes</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>2、更改Grub配置文档 <br /></p><blockquote><p>注释掉GRUB_BACKGROUND行</p></blockquote><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#GRUB_BACKGROUND="/usr/share/grub/YourImg.*"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>更改GRUB_THEME行</p></blockquote><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>GRUB_THEME="/usr/share/grub/themes/YourTheme/theme.txt"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>更新Grub配置</p></blockquote><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>$ sudo update-grub</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>重启即可看见效果啦~ <br /></p></blockquote><p>==3、注：在Grub Themes下载的主题压缩包，其中一部分有安装脚本install.sh，解压后，进入主题文档夹，执行sudo ./install.sh即可配置成功，等效于上述的步骤。==</p></blockquote></section></section>
<section><h3>参考文档<a href="#参考文档"><span>#</span></a></h3><ul>
<li>Manjaro <a href="https://www.bilibili.com/video/BV17K4y1K7ur" target="_blank">发行版的安装</a></li>
<li>Manjaro <a href="https://www.bilibili.com/video/BV1Gv41177GE" target="_blank">软件包管理和中文化配置</a></li>
<li>Manjaro <a href="https://www.bilibili.com/video/BV1AQ4y1Z7wj" target="_blank">自启动程序配置</a></li>
<li>Manjaro <a href="https://www.bilibili.com/video/BV1Xv411L75q" target="_blank">桌面环境的切换</a></li>
<li>Manjaro <a href="https://zhuanlan.zhihu.com/p/114296129" target="_blank">环境配置</a></li>
<li>Manjaro <a href="https://www.dazhuanlan.com/2019/08/27/5d654c90b0b83/" target="_blank">grub 主题修改</a></li>
<li>Manjaro <a href="https://zhang_hao_yu123.gitee.io/2021/01/14/manjaro-an-zhuang-he-pei-zhi/" target="_blank">命令安装</a></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/6632db9d/</id>
      <title type="text">【Linux】Doris 安装部署</title>
      <published>2024-05-21T08:31:13.000Z</published>
      <updated>2024-05-21T08:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/6632db9d/"/>
      <summary type="text">在Linux环境下Doris和StarRocks的安装部署流程。首先，文档涵盖了环境配置，包括服务器环境、Docker的安装与卸载步骤，重点描述了Doris的编译安装过程，以及StarRocks的部署准备、环境配置、服务启动等步骤，提供了如何通过MySQL客户端访问FE、添加BE与Broker实例到集群的具体操作方法</summary>
      <content type="html"><![CDATA[<section><h2><strong>doris 安装部署</strong><a href="#doris-安装部署"><span>#</span></a></h2><section><h3>一、环境配置<a href="#一环境配置"><span>#</span></a></h3><section><h4>1. 服务器环境<a href="#1-服务器环境"><span>#</span></a></h4><blockquote><ul>
<li>centos 7</li>
<li>docker <a href="https://download.docker.com/linux/static/stable/x86_64/" target="_blank">下载地址</a></li>
<li>doris 1.0.0 <a href="https://doris.apache.org/zh-CN/downloads/downloads.html#doris-%E4%B8%BB%E4%BB%A3%E7%A0%81" target="_blank">下载地址</a></li>
<li>doris <a href="https://doris.apache.org/zh-CN/installing/compilation.html" target="_blank">官方文档</a></li>
<li>storrocks <a href="https://docs.starrocks.com/zh-cn/main/quick_start/Deploy" target="_blank">官方文档</a></li>
<li><a href="https://blog.csdn.net/ult_me?type=blog" target="_blank">学习地址</a></li>
</ul></blockquote></section></section><section><h3>二、安装docker<a href="#二安装docker"><span>#</span></a></h3><section><h4>1. 使用xftp 等工具上传docker 安装包到linux服务器<a href="#1-使用xftp-等工具上传docker-安装包到linux服务器"><span>#</span></a></h4></section><section><h4>2. 解压<a href="#2-解压"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>tar -zxvf docekr-xxx.tgz</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>3. 复制压缩后的文件到指定文件夹<a href="#3-复制压缩后的文件到指定文件夹"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>cp docker/* /usr/bin</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>4. 注册编辑docker服务<a href="#4-注册编辑docker服务"><span>#</span></a></h4><blockquote><p><code>vim /etc/systemd/system/docker.service</code></p><p>如果无法使用vim 可以在windows上编辑好文件后上传至linux服务器的此目录内</p></blockquote><blockquote><p>参考docker.service:</p></blockquote><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[Unit]</span></div></div><div><div><div>2</div></div><div><span>Description=Docker Application Container Engine</span></div></div><div><div><div>3</div></div><div><span>Documentation=https://docs.docker.com</span></div></div><div><div><div>4</div></div><div><span>After=network-online.target firewalld.service</span></div></div><div><div><div>5</div></div><div><span>Wants=network-online.target</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>[Service]</span></div></div><div><div><div>8</div></div><div><span>LimitNOFILE=1048576</span></div></div><div><div><div>9</div></div><div><span>LimitNPROC=1048576</span></div></div><div><div><div>10</div></div><div><span>LimitCORE=infinity</span></div></div><div><div><div>11</div></div><div><span>Type=notify</span></div></div><div><div><div>12</div></div><div><span># the default is not to use systemd for cgroups because the delegate issues still</span></div></div><div><div><div>13</div></div><div><span># exists and systemd currently does not support the cgroup feature set required</span></div></div><div><div><div>14</div></div><div><span># for containers run by docker</span></div></div><div><div><div>15</div></div><div><span>#ExecStart=/usr/bin/dockerd --privileged=true --default-ulimit nofile=65536:65536 -H fd://</span></div></div><div><div><div>16</div></div><div><span>ExecStart=/usr/bin/dockerd</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>ExecReload=/bin/kill -s HUP $MAINPID</span></div></div><div><div><div>19</div></div><div><span># Having non-zero Limit*s causes performance problems due to accounting overhead</span></div></div><div><div><div>20</div></div><div><span># in the kernel. We recommend using cgroups to do container-local accounting.</span></div></div><div><div><div>21</div></div><div><span># Uncomment TasksMax if your systemd version supports it.</span></div></div><div><div><div>22</div></div><div><span># Only systemd 226 and above support this version.</span></div></div><div><div><div>23</div></div><div><span>#TasksMax=infinity</span></div></div><div><div><div>24</div></div><div><span>TimeoutStartSec=0</span></div></div><div><div><div>25</div></div><div><span># set delegate yes so that systemd does not reset the cgroups of docker containers</span></div></div><div><div><div>26</div></div><div><span>Delegate=yes</span></div></div><div><div><div>27</div></div><div><span># kill only the docker process, not all processes in the cgroup</span></div></div><div><div><div>28</div></div><div><span>KillMode=process</span></div></div><div><div><div>29</div></div><div><span># restart the docker process if it exits prematurely</span></div></div><div><div><div>30</div></div><div><span>Restart=on-failure</span></div></div><div><div><div>31</div></div><div><span>StartLimitBurst=3</span></div></div><div><div><div>32</div></div><div><span>StartLimitInterval=60s</span></div></div><div><div><div>33</div></div><div>
</div></div><div><div><div>34</div></div><div><span>[Install]</span></div></div><div><div><div>35</div></div><div><span>WantedBy=multi-user.target</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>5. 添加可执行权限<a href="#5-添加可执行权限"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>chmod +x /etc/systemd/system/docker.service</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>6. 一键三连<a href="#6-一键三连"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>systemctl daemon-reload #</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>systemctl start docker # 启动服务</span></div></div><div><div><div>3</div></div><div><span><span> </span></span><span>systemctl enable docker.service # 设置开机自启动</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>7. docker卸载<a href="#7-docker卸载"><span>#</span></a></h4><ol>
<li>停掉docker服务</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>systemctl</span><span> </span><span>stop</span><span> </span><span>docker</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>查看yum安装的docker文件包</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>yum</span><span> </span><span>list</span><span> </span><span>installed</span><span> |</span><span>grep</span><span> </span><span>docker</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>删除所有安装的docker文件包</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>yum</span><span> </span><span>-y</span><span> </span><span>remove</span><span> </span><span>docker.x86_64</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>查看rpm包是否还有</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>rpm</span><span> </span><span>-qa</span><span> |</span><span>grep</span><span> </span><span>docker</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>删除docker镜像放置的位置</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>rm</span><span> </span><span>-rf</span><span> </span><span>/var/lib/docker</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h3>三、安装Doris<a href="#三安装doris"><span>#</span></a></h3><section><h4>1、编译<a href="#1编译"><span>#</span></a></h4><section><h5>1). 使用【doris】源码，需要编译，这里直接使用物理机编译<a href="#1-使用doris源码需要编译这里直接使用物理机编译"><span>#</span></a></h5><ul>
<li>
<p>a).  0.14.0版本之前版本依赖如下</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>GCC</span><span> </span><span>7.3+,</span><span> </span><span>Oracle</span><span> </span><span>JDK</span><span> </span><span>1.8+,</span><span> </span><span>Python</span><span> </span><span>2.7+,</span><span> </span><span>Apache</span><span> </span><span>Maven</span><span> </span><span>3.5+,</span><span> </span><span>CMake</span><span> </span><span>3.11+</span><span> </span><span>Bison</span><span> </span><span>3.0+</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>如果使用Ubuntu 16.04 及以上系统 可以执行以下命令来安装依赖</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>apt-get</span><span> </span><span>install</span><span> </span><span>build-essential</span><span> </span><span>openjdk-8-jdk</span><span> </span><span>maven</span><span> </span><span>cmake</span><span> </span><span>byacc</span><span> </span><span>flex</span><span> </span><span>automake</span><span> </span><span>libtool-bin</span><span> </span><span>bison</span><span> </span><span>binutils-dev</span><span> </span><span>libiberty-dev</span><span> </span><span>zip</span><span> </span><span>unzip</span><span> </span><span>libncurses5-dev</span><span> </span><span>curl</span><span> </span><span>git</span><span> </span><span>ninja-build</span><span> </span><span>python</span><span> </span><span>autopoint</span><span> </span><span>pkg-config</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>如果是CentOS 可以执行以下命令</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>yum</span><span> </span><span>groupinstall</span><span> </span><span>'Development Tools'</span><span> &amp;&amp; </span><span>sudo</span><span> </span><span>yum</span><span> </span><span>install</span><span> </span><span>maven</span><span> </span><span>cmake</span><span> </span><span>byacc</span><span> </span><span>flex</span><span> </span><span>automake</span><span> </span><span>libtool</span><span> </span><span>bison</span><span> </span><span>binutils-devel</span><span> </span><span>zip</span><span> </span><span>unzip</span><span> </span><span>ncurses-devel</span><span> </span><span>curl</span><span> </span><span>git</span><span> </span><span>wget</span><span> </span><span>python2</span><span> </span><span>glibc-static</span><span> </span><span>libstdc++-static</span><span> </span><span>java-1.8.0-openjdk</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>b). 在0.14.0 之后版本依赖如下</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>GCC</span><span> </span><span>10+,</span><span> </span><span>Oracle</span><span> </span><span>JDK</span><span> </span><span>1.8+,</span><span> </span><span>Python</span><span> </span><span>2.7+,</span><span> </span><span>Apache</span><span> </span><span>Maven</span><span> </span><span>3.5+,</span><span> </span><span>CMake</span><span> </span><span>3.19.2+</span><span> </span><span>Bison</span><span> </span><span>3.0+</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>如果使用Ubuntu 16.04 及以上系统 可以执行以下命令来安装依赖</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>apt</span><span> </span><span>install</span><span> </span><span>build-essential</span><span> </span><span>openjdk-8-jdk</span><span> </span><span>maven</span><span> </span><span>cmake</span><span> </span><span>byacc</span><span> </span><span>flex</span><span> </span><span>automake</span><span> </span><span>libtool-bin</span><span> </span><span>bison</span><span> </span><span>binutils-dev</span><span> </span><span>libiberty-dev</span><span> </span><span>zip</span><span> </span><span>unzip</span><span> </span><span>libncurses5-dev</span><span> </span><span>curl</span><span> </span><span>git</span><span> </span><span>ninja-build</span><span> </span><span>python</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>add-apt-repository</span><span> </span><span>ppa:ubuntu-toolchain-r/ppa</span></div></div><div><div><div>3</div></div><div><span>sudo</span><span> </span><span>apt</span><span> </span><span>update</span></div></div><div><div><div>4</div></div><div><span>sudo</span><span> </span><span>apt</span><span> </span><span>install</span><span> </span><span>gcc-10</span><span> </span><span>g++-10</span></div></div><div><div><div>5</div></div><div><span>sudo</span><span> </span><span>apt-get</span><span> </span><span>install</span><span> </span><span>autoconf</span><span> </span><span>automake</span><span> </span><span>libtool</span><span> </span><span>autopoint</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>如果是CentOS 可以执行以下命令</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>yum</span><span> </span><span>groupinstall</span><span> </span><span>'Development Tools'</span><span> &amp;&amp; </span><span>sudo</span><span> </span><span>yum</span><span> </span><span>install</span><span> </span><span>maven</span><span> </span><span>cmake</span><span> </span><span>byacc</span><span> </span><span>flex</span><span> </span><span>automake</span><span> </span><span>libtool</span><span> </span><span>bison</span><span> </span><span>binutils-devel</span><span> </span><span>zip</span><span> </span><span>unzip</span><span> </span><span>ncurses-devel</span><span> </span><span>curl</span><span> </span><span>git</span><span> </span><span>wget</span><span> </span><span>python2</span><span> </span><span>glibc-static</span><span> </span><span>libstdc++-static</span><span> </span><span>java-1.8.0-openjdk</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>yum</span><span> </span><span>install</span><span> </span><span>centos-release-scl</span></div></div><div><div><div>3</div></div><div><span>sudo</span><span> </span><span>yum</span><span> </span><span>install</span><span> </span><span>devtoolset-10</span></div></div><div><div><div>4</div></div><div><span>scl</span><span> </span><span>enable</span><span> </span><span>devtoolset-10</span><span> </span><span>bash</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>**安装完成后，自行设置环境变量 PATH, JAVA_HOME 等。(可以通过alternatives —list命令找到jdk的安装目录) 注意： Doris 0.14.0 的版本仍然使用gcc7 的依赖编译，之后的代码将使用gcc10 的依赖 **</p>
</li>
<li>
<p>c). 下载源码</p>
<p><a href="https://doris.apache.org/zh-CN/downloads/downloads.html" target="_blank">官网地址</a></p>
</li>
<li>
<p>d) 编译</p>
<p>上传源码到服务器后，解压文件，进入文件夹后，执行编译</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 支持则使用下面命令进行编译</span></div></div><div><div><div>2</div></div><div><span>$</span><span> </span><span>sh</span><span> </span><span>build.sh</span></div></div><div><div><div>3</div></div><div><span># 如不支持需要加 USE_AVX2=0</span></div></div><div><div><div>4</div></div><div><span>$</span><span> </span><span>USE_AVX2=</span><span>0</span><span> </span><span>sh</span><span> </span><span>build.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p><strong>编译完成后，产出文件在 output/ 目录中</strong></p>
</li>
</ul></section><section><h5>2)、使用【starrocks】无需编译，直接部署即可，但CPU需支持【avx2】指令集<a href="#2使用starrocks无需编译直接部署即可但cpu需支持avx2指令集"><span>#</span></a></h5><blockquote><ol>
<li>下载官方镜像 <a href="https://docs.starrocks.com/zh-cn/main/administration/Build_in_docker" target="_blank">文档</a></li>
</ol></blockquote></section></section><section><h4>2、部署环境准备<a href="#2部署环境准备"><span>#</span></a></h4><ul>
<li>
<p>Linux 操作系统版本需求</p>
<blockquote>

<table><thead><tr><th>Linux 系统</th><th>版本</th></tr></thead><tbody><tr><td>CentOS</td><td>7.1 及以上</td></tr><tr><td>Ubuntu</td><td>16.04 及以上</td></tr></tbody></table></blockquote>
</li>
<li>
<p>软件需求</p>
<blockquote>

<table><thead><tr><th>软件</th><th>版本</th></tr></thead><tbody><tr><td>java</td><td>1.8+</td></tr><tr><td>GCC</td><td>4.8.2 及以上</td></tr></tbody></table></blockquote>
</li>
<li>
<p>操作系统安装要求
<code>vi /etc/security/limits.conf</code>
# 在末尾加入配置（表示：所有用户所有组，软限制和硬限制，对文件打开数，设为65535）：
* soft nofile 65536
* hard nofile 65536
# 修改后需要断开远程工具（如Xshell等）后重新连接方可生效，或者，直接再临时修改一次，使用：
​    ulimit -n 65535
# 确认生效：
​    ulimit -n</p>
</li>
<li>
<p>CPU检查</p>
<blockquote><ul>
<li>使用doris 编译的 可以跳过此检查；</li>
<li>使用storrocks 下载部署的，需要检查cpu是否支持<code>avx2</code> 指令集</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cat</span><span> </span><span>/proc/cpuinfo</span><span> | </span><span>grep</span><span> </span><span>avx2</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>有结果输出即表明CPU支持。如果无输出，则需要更换支持AVX2的机器。部分情况下，我们会在Windows系统下使用虚拟机安装CentOS作为测试环境，此时我们可以使用CPU-Z、AIDA64等工具在Windows下检查宿主机CPU的指令集支持情况。</p></blockquote>
</li>
<li>
<p>操作系统检查</p>
<blockquote><p>StarRocks要求系统为Linux CentOS 7及以上版本（下文演示使用CentOS 7.6），内核版本建议在3.10以上，查看系统及内核信息：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>[root@node01 ~]# cat /etc/redhat-release</span></div></div><div><div><div>2</div></div><div><span> </span><span>CentOS</span><span> </span><span>Linux</span><span> </span><span>release</span><span> </span><span>7.6.1810</span><span> (Core)</span></div></div><div><div><div>3</div></div><div><span><span> </span></span><span>[root@node01 ~]# uname -a</span></div></div><div><div><div>4</div></div><div><span> </span><span>Linux</span><span> </span><span>node01</span><span> </span><span>3.10.0-1160.25.1.el7.x86_64</span><span> </span><span>#1 SMP Wed Apr 28 21:49:45 UTC 2021 &gt; x86_64 x86_64 x86_64 GNU/Linux</span></div></div></code></pre><div><div></div><div></div></div></figure></div></blockquote>
</li>
<li>
<p>时钟同步</p>
<blockquote><p>Doris 的元数据要求时间精度要小于5000ms，所以所有集群所有机器要进行时钟同步，避免因为时钟问题引发的元数据不一致导致服务出现异常。</p></blockquote>
</li>
<li>
<p>网络需求</p>
<blockquote><p>Doris、storrocks 各个实例直接通过网络进行通讯。以下表格展示了所有需要的端口</p>

<table><thead><tr><th>实例名</th><th>端口名称</th><th>默认端口</th><th>通信方向</th><th>说明</th></tr></thead><tbody><tr><td>BE</td><td>be_port</td><td>9060</td><td>FE—&gt;BE</td><td>BE 上 thrift server 的端口，用于接收来自 FE 的请求</td></tr><tr><td>BE</td><td>webserver_port</td><td>8040</td><td>BE &lt;—&gt; BE</td><td>BE 上的 http server 的端口</td></tr><tr><td>BE</td><td>heartbeat_service_port</td><td>9050</td><td>FE —&gt; BE</td><td>BE 上心跳服务端口（thrift），用于接收来自 FE 的心跳</td></tr><tr><td>BE</td><td>brpc_port</td><td>8060</td><td>FE &lt;—&gt; BE, BE &lt;—&gt; BE</td><td>BE 上的 brpc 端口，用于 BE 之间通讯</td></tr><tr><td>FE</td><td>http_port</td><td>8030</td><td>FE &lt;—&gt; FE，用户 &lt;—&gt; FE</td><td>FE 上的 http server 端口</td></tr><tr><td>FE</td><td>rpc_port</td><td>9020</td><td>BE —&gt; FE, FE &lt;—&gt; FE</td><td>FE 上的 thrift server 端口，每个fe的配置需要保持一致</td></tr><tr><td>FE</td><td>query_port</td><td>9030</td><td>用户 &lt;—&gt; FE</td><td>FE 上的 mysql server 端口</td></tr><tr><td>FE</td><td>edit_log_port</td><td>9010</td><td>FE &lt;—&gt; FE</td><td>FE 上的 bdbje 之间通信用的端口</td></tr><tr><td>Broker</td><td>broker_ipc_port</td><td>8000</td><td>FE —&gt; Broker, BE —&gt; Broker</td><td>Broker 上的 thrift server，用于接收请求</td></tr></tbody></table></blockquote>
<blockquote><p><strong>注：</strong></p><ol>
<li><strong>当部署多个 FE 实例时，要保证 FE 的 http_port 配置相同。</strong></li>
<li><strong>部署前请确保各个端口在应有方向上的访问权限。</strong></li>
<li><strong>若上述端口不与服务器中其他服务的端口冲突，通常不建议修改。</strong></li>
<li>以FE为例，部署前若需修改端口，可在配置文件fe/conf/fe.conf中修改为需要使用的端口（再次注意集群中FE的http端口需要一致，默认为8030）：</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># store metadata, create it if it is not exist.</span></div></div><div><div><div>2</div></div><div><span># Default value is ${STARROCKS_HOME}/meta</span></div></div><div><div><div>3</div></div><div><span># meta_dir = ${STARROCKS_HOME}/meta</span></div></div><div><div><div>4</div></div><div><span>http_port</span><span> </span><span>=</span><span> </span><span>8030</span></div></div><div><div><div>5</div></div><div><span>rpc_port</span><span> </span><span>=</span><span> </span><span>9020</span></div></div><div><div><div>6</div></div><div><span>query_port</span><span> </span><span>=</span><span> </span><span>9030</span></div></div><div><div><div>7</div></div><div><span>edit_log_port</span><span> </span><span>=</span><span> </span><span>9010</span></div></div><div><div><div>8</div></div><div><span>mysql_service_nio_enabled</span><span> </span><span>=</span><span> </span><span>true</span></div></div></code></pre><div><div></div><div></div></div></figure></div></blockquote>
</li>
<li>
<p>配置防火墙，开放端口</p>
<blockquote><p>防火墙开放集群实例默认端口命令：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>firewall-cmd --zone=public --add-port=8000/tcp --permanent</span></div></div><div><div><div>2</div></div><div><span>firewall-cmd --zone=public --add-port=8030/tcp --permanent</span></div></div><div><div><div>3</div></div><div><span>firewall-cmd --zone=public --add-port=8040/tcp --permanent</span></div></div><div><div><div>4</div></div><div><span>firewall-cmd --zone=public --add-port=8060/tcp --permanent</span></div></div><div><div><div>5</div></div><div><span>firewall-cmd --zone=public --add-port=9010/tcp --permanent</span></div></div><div><div><div>6</div></div><div><span>firewall-cmd --zone=public --add-port=9020/tcp --permanent</span></div></div><div><div><div>7</div></div><div><span>firewall-cmd --zone=public --add-port=9030/tcp --permanent</span></div></div><div><div><div>8</div></div><div><span>firewall-cmd --zone=public --add-port=9050/tcp --permanent</span></div></div><div><div><div>9</div></div><div><span>firewall-cmd --zone=public --add-port=9060/tcp --permanent</span></div></div><div><div><div>10</div></div><div><span>firewall-cmd --reload</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>查看开放的端口：</p></blockquote><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@node01 ~]# firewall-cmd --list-port</span></div></div><div><div><div>2</div></div><div><span>8030/tcp 8000/tcp 8060/tcp 9010/tcp 9020/tcp 9030/tcp 9050/tcp 9060/tcp 8040/tcp</span></div></div></code></pre><div><div></div><div></div></div></figure></div></blockquote>
</li>
<li>
<p>安装JDK</p>
<blockquote><p>StarRocks依赖JDK 1.8+环境，Oracle JDK 1.8+或OpenJDK8+均可以使用（下文演示使用OpenJDK 1.8.0_41）：</p><p>[root@node01 ~]# java -version
openjdk version “1.8.0_41”
OpenJDK Runtime Environment (build 1.8.0_41-b04)
OpenJDK 64-Bit Server VM (build 25.40-b25, mixed mode)</p><p>OpenJDK 8的安装操作见&lt;文档&gt;：<a href="http://note.youdao.com/noteshare?id=6a91052faf8d92c8bb559d030af50173&amp;sub=06660F2C04AC4D259E712C37184AF3BA" target="_blank">【Linux】安装OpenJDK.md</a></p></blockquote>
</li>
<li>
<p>安装Mysql</p>
<blockquote><p>StarRocks采用MySQL协议进行通信，用户可通过mysql-client连接到StarRocks集群。选 择mysql-client版本时要求采用5.1之后的版本，因为5.1之前不能支持长度超过16个字 符的用户名（下文演示使用mysql -client-5.7.35）。</p></blockquote>
<blockquote><p>为方便集群部署和运维，我们通常建议在集群服务器中选择一个节点安装mysql-client。当然，我们也可以不安装mysql-client，通过外部的SQLyog、DBeaver、Navicat等图形化工具直接访问StarRocks。</p></blockquote>
<blockquote><p>mysql 安装操作文档见：<a href="http://note.youdao.com/noteshare?id=d5a1fbccd727cefea317f9cf16fe5fcd&amp;sub=7CA727CB637D44AE8CE8C59C0101F31E" target="_blank">【Linux】CentOS7安装mysql5.7</a></p></blockquote>
</li>
</ul></section><section><h4>3、安装部署<a href="#3安装部署"><span>#</span></a></h4><blockquote><p>严格来说，StarRocks并没有所谓的“Standalone运行模式”，生产环境下更是不建议进行单实例部署。这里将单机部署整理出来，主要是考虑当用户测试环境受限于机器数量或仅希望验证功能，那么也可以在一台机器上简易部署把StarRocks跑起来。</p></blockquote><blockquote><p>以服务器“starrocks（172.18.88.54）”为例，在进行完部署环境的准备工作后，我们开始进行单节点的部署。</p></blockquote><blockquote><p>单节点架构设计如下：</p></blockquote>

<table><thead><tr><th>机器节点</th><th>172.18.88.54（starrocks）</th></tr></thead><tbody><tr><td>部署服务</td><td>1 FE(Leader) <br />1 BE<br />1 Broker<br />mysql-client</td></tr></tbody></table><blockquote><p>部署目录及数据目录设计如下，后续的部署操作严格按照部署设计进行：</p></blockquote>

<table><thead><tr><th>服务</th><th>说明</th></tr></thead><tbody><tr><td>FE</td><td>部署目录：/opt/module/starrocks/fe <br /> 日志目录：/opt/module/starrocks/fe/log（默认）<br />元数据目录：/opt/meta</td></tr><tr><td>BE</td><td>部署目录：/opt/module/starrocks/be <br />日志目录：/opt/module/starrocks/be/log（默认）<br />数据目录：/opt/storage</td></tr><tr><td>Broker</td><td>部署目录：/opt/module/starrocks/apache_hdfs_broker</td></tr></tbody></table><section><h5>1. 下载二进制包<a href="#1-下载二进制包"><span>#</span></a></h5><p>StarRocks的二进制部署包可在官网下载获取：<a href="https://www.starrocks.com/zh-CN/download/community" target="_blank">下载地址</a></p><p>doris 使用编译到output文件中的文件
这儿是用storrocks 为例,将下载好的部署包上传至 <code>/opt/software</code> 目录下</p><blockquote><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@starrocks ~]# mkdir /opt/software</span></div></div><div><div><div>2</div></div><div><span>[root@starrocks ~]# cd /opt/software/</span></div></div><div><div><div>3</div></div><div><span>[root@starrocks software]# ll</span></div></div><div><div><div>4</div></div><div><span>total 988752</span></div></div><div><div><div>5</div></div><div><span>-rw-r--r-- 1 root root 1012479814 Nov 22 15:46 StarRocks-1.19.2.tar.gz</span></div></div></code></pre><div><div></div><div></div></div></figure></div></blockquote></section><section><h5>2. 解压<a href="#2-解压-1"><span>#</span></a></h5><blockquote><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@starrocks software]# tar xvf StarRocks-1.19.2.tar.gz</span></div></div><div><div><div>2</div></div><div><span>[root@starrocks software]# ll</span></div></div><div><div><div>3</div></div><div><span>total 988752</span></div></div><div><div><div>4</div></div><div><span>drwxrwxr-x 6 1007 1007        100 Nov 20 20:29 StarRocks-1.19.2</span></div></div><div><div><div>5</div></div><div><span>-rw-r--r-- 1 root root 1012479814 Nov 22 15:46 StarRocks-1.19.2.tar.gz</span></div></div></code></pre><div><div></div><div></div></div></figure></div></blockquote><p><strong>starrocks 目录结构：</strong></p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>StarRocks-1.19.2</span></div></div><div><div><div>2</div></div><div><span>├── apache_hdfs_broker  # Broker目录</span></div></div><div><div><div>3</div></div><div><span>│   ├── bin</span></div></div><div><div><div>4</div></div><div><span>│   │   ├── start_broker.sh  # Broker启动脚本</span></div></div><div><div><div>5</div></div><div><span>│   │   └── stop_broker.sh  # Broker关闭脚本</span></div></div><div><div><div>6</div></div><div><span>│   ├── conf</span></div></div><div><div><div>7</div></div><div><span>│   │   ├── apache_hdfs_broker.conf  # Broker配置文件</span></div></div><div><div><div>8</div></div><div><span>│   │   ├── hdfs-site.xml</span></div></div><div><div><div>9</div></div><div><span>│   │   └── log4j.properties</span></div></div><div><div><div>10</div></div><div><span>│   └── lib</span></div></div><div><div><div>11</div></div><div><span>│       └── *.jar  # Broker依赖的jar包</span></div></div><div><div><div>12</div></div><div><span>├── be  # BE实例目录</span></div></div><div><div><div>13</div></div><div><span>│   ├── bin</span></div></div><div><div><div>14</div></div><div><span>│   │   ├── common.sh</span></div></div><div><div><div>15</div></div><div><span>│   │   ├── show_be_version.sh  # BE版本查看</span></div></div><div><div><div>16</div></div><div><span>│   │   ├── start_be.sh  # BE启动脚本</span></div></div><div><div><div>17</div></div><div><span>│   │   └── stop_be.sh  # BE关闭脚本</span></div></div><div><div><div>18</div></div><div><span>│   ├── conf</span></div></div><div><div><div>19</div></div><div><span>│   │   ├── be.conf  # BE配置文件</span></div></div><div><div><div>20</div></div><div><span>│   │   └── hadoop_env.sh</span></div></div><div><div><div>21</div></div><div><span>│   ├── lib</span></div></div><div><div><div>22</div></div><div><span>│   │   ├── meta_tool  # Tablet元数据离线管理工具 [1.19版本已合并入starrocks_be]</span></div></div><div><div><div>23</div></div><div><span>│   │   └── starrocks_be  # BE可执行文件（小版本升级时替换即可）</span></div></div><div><div><div>24</div></div><div><span>│   └── www  # BE Web页面文件</span></div></div><div><div><div>25</div></div><div><span>├── fe  # FE实例目录</span></div></div><div><div><div>26</div></div><div><span>│   ├── bin</span></div></div><div><div><div>27</div></div><div><span>│   │   ├── common.sh</span></div></div><div><div><div>28</div></div><div><span>│   │   ├── show_fe_version.sh  # FE版本查看</span></div></div><div><div><div>29</div></div><div><span>│   │   ├── start_fe.sh  # FE启动脚本</span></div></div><div><div><div>30</div></div><div><span>│   │   └── stop_fe.sh  # FE关闭脚本</span></div></div><div><div><div>31</div></div><div><span>│   ├── conf</span></div></div><div><div><div>32</div></div><div><span>│   │   ├── fe.conf  # FE配置文件</span></div></div><div><div><div>33</div></div><div><span>│   │   └── hadoop_env.sh</span></div></div><div><div><div>34</div></div><div><span>│   ├── lib</span></div></div><div><div><div>35</div></div><div><span>│   │   ├── starrocks-fe.jar  # FE jar包（小版本升级时替换即可）</span></div></div><div><div><div>36</div></div><div><span>│   │   └── *.jar  # FE依赖的jar包</span></div></div><div><div><div>37</div></div><div><span>│   ├── log</span></div></div><div><div><div>38</div></div><div><span>│   │   └── *.log</span></div></div><div><div><div>39</div></div><div><span>│   └── webroot # FE Web页面文件</span></div></div><div><div><div>40</div></div><div><span>└── udf # 用户自定义函数目录 [重构中，目前不建议使用]</span></div></div><div><div><div>41</div></div><div><span><span>    </span></span><span>├── include</span></div></div><div><div><div>42</div></div><div><span><span>    </span></span><span>│   ├── uda_test_harness.h</span></div></div><div><div><div>43</div></div><div><span><span>    </span></span><span>│   └── udf.h  # UDF框架头文件</span></div></div><div><div><div>44</div></div><div><span><span>    </span></span><span>└── lib</span></div></div><div><div><div>45</div></div><div><span><span>        </span></span><span>└── libStarRocksUdf.a  # UDF框架静态库文件</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h5>3. 分发部署文件<a href="#3-分发部署文件"><span>#</span></a></h5><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 重命名</span></div></div><div><div><div>2</div></div><div><span>[root@starrocks software]# mv /opt/software/StarRocks-1.19.2 /opt/software/starrocks</span></div></div><div><div><div>3</div></div><div><span># 移动文件到module目录下</span></div></div><div><div><div>4</div></div><div><span>[root@starrocks software]# mv /opt/software/starrocks /opt/module/starrocks/</span></div></div><div><div><div>5</div></div><div><span>[root@starrocks software]# cd /opt/module/starrocks/</span></div></div><div><div><div>6</div></div><div><span>[root@starrocks starrocks]# ll</span></div></div><div><div><div>7</div></div><div><span>total 0</span></div></div><div><div><div>8</div></div><div><span>drwxr-xr-x. 5 1021 1021 40 Nov 22 14:40 apache_hdfs_broker</span></div></div><div><div><div>9</div></div><div><span>drwxr-xr-x. 6 1021 1021 51 Nov 22 14:40 be</span></div></div><div><div><div>10</div></div><div><span>drwxr-xr-x. 8 1021 1021 83 Nov 22 14:52 fe</span></div></div><div><div><div>11</div></div><div><span>drwxr-xr-x. 4 1021 1021 32 Nov 22 14:40 udf</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h5>4. 部署fe<a href="#4-部署fe"><span>#</span></a></h5><ul>
<li>
<p>修改FE配置文件</p>
<p>StarRocks各服务配置文件的默认配置已经足以启动集群，不建议初尝用户修改较多配置。FE的配置文件在测试环境中我们通常只需要关注以下三点：</p>
<p>a、注意默认端口，避免端口冲突，正常情况下不需要修改；</p>
<p>b、绑定IP，避免多网卡情况下服务无法自动匹配到正确的IP。特别注意，绑定ip时，如果不清楚CIDR表示法，可以直接填写完整的ip（不支持别名），例如配置为priority_networks = 172.18.88.54/24;该地址可以使用 <code>ip addr show</code> 的方式查询</p>
<p>c、设置元数据目录，默认目录为fe/meta，我们建议新建目录并修改配置文件。</p>
<p>根据部署设计，创建元数据存储目录：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@starrocks starrocks]# mkdir /opt/meta</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>针对b和c修改配置文件（带#的为注释，红色字体为新增配置）：</p>
<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@starrocks starrocks]# vi /opt/module/starrocks/fe/conf/fe.conf</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span># store metadata, create it if it is not exist.</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># Default value is ${STARROCKS_HOME}/meta</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># meta_dir = ${STARROCKS_HOME}/meta</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span># 修改此处</span></div></div><div><div><div>10</div></div><div><span>meta_dir = /opt/meta</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>…………</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span># Choose one if there are more than one ip except loopback address.</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span># Note that there should at most one ip match this list.</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span># If no ip match this rule, will choose one randomly.</span></div></div><div><div><div>19</div></div><div>
</div></div><div><div><div>20</div></div><div><span># use CIDR format, e.g. 10.10.10.0/24</span></div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span># Default value is empty.</span></div></div><div><div><div>23</div></div><div>
</div></div><div><div><div>24</div></div><div><span># priority_networks = 10.10.10.0/24;192.168.0.0/16</span></div></div><div><div><div>25</div></div><div>
</div></div><div><div><div>26</div></div><div><span># 修改此处</span></div></div><div><div><div>27</div></div><div><span>priority_networks = 192.168.110.98</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
</li>
<li>
<p>配置环境变量</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 配置环境变量</span></div></div><div><div><div>2</div></div><div><span>vim /etc/profile.d/doris.sh</span></div></div><div><div><div>3</div></div><div><span>export DORIS_HOME=Doris根目录 # 例如/opt/doris</span></div></div><div><div><div>4</div></div><div><span>export PATH=$PATH:$DORIS_HOME/fe/bin:$DORIS_HOME/be/bin</span></div></div><div><div><div>5</div></div><div><span># 保存并source</span></div></div><div><div><div>6</div></div><div><span>source /etc/profile.d/doris.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>启动FE</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@starrocks starrocks]# cd /opt/module/starrocks/fe/bin/</span></div></div><div><div><div>2</div></div><div><span># --daemon 后台运行</span></div></div><div><div><div>3</div></div><div><span>[root@starrocks bin]# ./start_fe.sh --daemon</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<blockquote><p>补充：关闭FE的脚本是stop_fe.sh，命令：./stop_fe.sh</p></blockquote>
<p>FE使用Java语言编写，使用jps命令查看java进程，若发现有StarRocksFe进程，即为启动成功：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@starrocks bin]# jps</span></div></div><div><div><div>2</div></div><div><span>5178 Jps</span></div></div><div><div><div>3</div></div><div><span>5164 StarRocksFe</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p><strong>如果进程状态异常可在FE日志目录中查看日志追踪原因，FE的主要日志在fe.log中，所有查询的审计日志在fe.audit.log中。由于是初次启动，如果在操作过程中遇到比较耗时的问题，可以清空FE的元数据目录，再从头开始操作。</strong></p>
</li>
<li>
<p>访问FE</p>
<p>使用mysql-client访问FE，FE查询端口默认为9030，自带用户root，默认密码为空：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@starrocks bin]# mysql -h172.18.88.54 -P9030 -uroot</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>Welcome to the MySQL monitor.  Commands end with ; or \g.</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>Your MySQL connection id is 1</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>Server version: 5.1.0</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>………………</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>mysql&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>确认FE状态</p>
<p>若mysql-client能够正常访问FE，已说明FE状态正常，查询命令：</p>
<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>    </span></span><span>mysql&gt;  show frontends\G</span></div></div><div><div><div>2</div></div><div><span>*************************** 1. row ***************************</span></div></div><div><div><div>3</div></div><div><span><span>             </span></span><span>Name: 172.18.88.54_9010_1651209869733</span></div></div><div><div><div>4</div></div><div><span><span>               </span></span><span>IP: 172.18.88.54</span></div></div><div><div><div>5</div></div><div><span><span>      </span></span><span>EditLogPort: 9010</span></div></div><div><div><div>6</div></div><div><span><span>         </span></span><span>HttpPort: 8030</span></div></div><div><div><div>7</div></div><div><span><span>        </span></span><span>QueryPort: 9030</span></div></div><div><div><div>8</div></div><div><span><span>          </span></span><span>RpcPort: 9020</span></div></div><div><div><div>9</div></div><div><span><span>             </span></span><span>Role: FOLLOWER</span></div></div><div><div><div>10</div></div><div><span><span>         </span></span><span>IsMaster: true</span></div></div><div><div><div>11</div></div><div><span><span>        </span></span><span>ClusterId: 1166088853</span></div></div><div><div><div>12</div></div><div><span><span>             </span></span><span>Join: true</span></div></div><div><div><div>13</div></div><div><span><span>            </span></span><span>Alive: true</span></div></div><div><div><div>14</div></div><div><span>ReplayedJournalId: 803</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>LastHeartbeat: 2022-04-29 14:11:57</span></div></div><div><div><div>16</div></div><div><span><span>         </span></span><span>IsHelper: true</span></div></div><div><div><div>17</div></div><div><span><span>           </span></span><span>ErrMsg:</span></div></div><div><div><div>18</div></div><div><span><span>          </span></span><span>Version: 0.14.0-release-Unknown</span></div></div><div><div><div>19</div></div><div><span>1 row in set (20.04 sec)</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<p><strong>Alive为true即说明FE节点状态正常。</strong></p>
</li>
<li>
<p>校验FE启动是否成功</p>
<blockquote><ol>
<li>检查是否启动成功, JPS 命令下有没有 PaloFe 进程</li>
<li>FE 进程启动后，会⾸先加载元数据，根据 FE ⻆⾊的不同，在⽇志中会看到 transfer from UNKNOWN to MASTER/FOLLOWER/OBSERVER 。最终会看到 thrift server started ⽇志，并且可以通过 mysql 客户端连接到 FE，则 表示 FE 启动成功。</li>
<li>也可以通过如下连接查看是否启动成功： http://fe_host:fe_http_port/api/bootstrap 如果返回： {“status”:“OK”,“msg”:“Success”} 则表示启动成功，其余情况，则可能存在问题。</li>
<li>外⽹环境访问 http://fe_host:fe_http_port 查看是否可以访问WebUI界 ⾯，登录账号默认为root，密码为空</li>
</ol></blockquote>
<blockquote><p><strong>注：如果在 fe.log 中查看不到启动失败的信息，也许在 fe.out 中可以看到。</strong></p></blockquote>
</li>
<li>
<p>添加实例进入集群</p>
<p>我们先将添加BE与Broker实例添加入集群。这里需要说明一下，“启动服务”和“将服务添加入集群”并没有严格的先后顺序，但若先启动服务，在实例未加入集群前，BE的日志中会打印一些提示未加入集群的WARNING信息，例如：Fail to get master client from cache。所以我们可以在FE全部部署完成后，使用mysql-client将集群中其他实例通过SQL添加入集群，然后再逐个部署启动。</p>
<p>添加BE进入集群，端口使用BE的heartbeat_service_port（默认为9050）：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>mysql&gt; alter system add backend '172.18.88.54:9050';</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>Query OK, 0 rows affected (0.10 sec)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>若添加实例进入集群时信息输入有误或出现其他异常，我们可以将其删除后重新添加，删除示例：</p>
<p>从集群中删除BE（当前仅有一个BE实例，故删除时可以直接使用dropp命令删除。删除BE为高风险操作，所以这里的删除命令设计为了dropp）：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>mysql&gt; alter system dropp backend '172.18.88.54:9050';</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>Query OK, 0 rows affected (0.09 sec)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>添加Broker进入集群时需要给Broker设定名称，比如命名为hdfs_broker，端口使用Broker的broker_ipc_port（默认为8000）：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>mysql&gt; alter system add broker hdfs_broker '172.18.88.54:8000';</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>Query OK, 0 rows affected (0.03 sec)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>从集群中删除Broker：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>mysql&gt; alter system drop broker hdfs_broker '172.18.88.54:8000';</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>Query OK, 0 rows affected (0.04 sec)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>暂时退出StarRocks：
mysql&gt; exit</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Bye</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul></section><section><h5>5. 部署BE实例<a href="#5-部署be实例"><span>#</span></a></h5><ul>
<li>
<p>修改BE配置文件</p>
<ul>
<li>BE的配置文件，在测试环境通常也是关注如下三点：</li>
</ul>
<blockquote><ol>
<li>注意默认端口，避免端口冲突，正常情况下不需要修改；</li>
<li>绑定IP，避免多网卡情况下无法自动找到正确的IP（同样，不清楚CIDR就可以直接填写完整的IP）；</li>
<li>设置数据存储目录，默认目录为be/storage，我们建议新建目录并修改配置文件。</li>
</ol></blockquote>
<ul>
<li>新建BE数据存储目录：</li>
</ul>

<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@starrocks bin]# mkdir /opt/storage</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<ul>
<li>针对b和c修改配置文件（带#的为注释，红色字体为新增配置）：</li>
</ul>

<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@starrocks bin]# vi /opt/module/starrocks/be/conf/be.conf</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span># Choose one if there are more than one ip except loopback address.</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># Note that there should at most one ip match this list.</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># If no ip match this rule, will choose one randomly.</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span># use CIDR format, e.g. 10.10.10.0/24</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span># Default value is empty.</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># priority_networks = 10.10.10.0/24;192.168.0.0/16</span></div></div><div><div><div>14</div></div><div><span># 修改此处</span></div></div><div><div><div>15</div></div><div><span>priority_networks = 172.18.88.54/24</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>…………</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span># you also can specify the properties by setting '&lt;property&gt;:&lt;value&gt;', seperate by ','</span></div></div><div><div><div>20</div></div><div>
</div></div><div><div><div>21</div></div><div><span># property 'medium' has a higher priority than the extension of path</span></div></div><div><div><div>22</div></div><div>
</div></div><div><div><div>23</div></div><div><span>#</span></div></div><div><div><div>24</div></div><div>
</div></div><div><div><div>25</div></div><div><span># Default value is ${STARROCKS_HOME}/storage, you should create it by hand.</span></div></div><div><div><div>26</div></div><div>
</div></div><div><div><div>27</div></div><div><span># storage_root_path = ${STARROCKS_HOME}/storage</span></div></div><div><div><div>28</div></div><div><span># 修改此处</span></div></div><div><div><div>29</div></div><div><span>storage_root_path = /opt/storage</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
</li>
<li>
<p>启动BE</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@starrocks bin]# cd /opt/module/starrocks/be/bin/</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>[root@starrocks bin]# ./start_be.sh --daemon</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p><strong>补充：关闭BE脚本为stop_be.sh，命令：./stop_be.sh</strong></p>
<blockquote><p>BE使用C++编写，使用ps命令查看进程，若发现有starrocks_be进程，即为启动成功：</p></blockquote>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@starrocks bin]# ps -ef | grep starrocks_be</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>root       6670      1  1 19:46 pts/0    00:00:00 /opt/module/starrocks/be/lib/starrocks_be</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p><strong>如果进程状态异常可在BE日志目录中查看日志追踪原因，BE的主要日志在be.INFO中，其他的日志在be.out中。</strong></p>
</li>
<li>
<p>查看BE状态</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@starrocks bin]# mysql -h127.0.0.1 -P9030 -uroot</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>mysql&gt; show backends\G</span></div></div><div><div><div>2</div></div><div><span>*************************** 1. row ***************************</span></div></div><div><div><div>3</div></div><div><span><span>            </span></span><span>BackendId: 11001</span></div></div><div><div><div>4</div></div><div><span><span>              </span></span><span>Cluster: default_cluster</span></div></div><div><div><div>5</div></div><div><span><span>                   </span></span><span>IP: 172.18.88.54</span></div></div><div><div><div>6</div></div><div><span><span>        </span></span><span>HeartbeatPort: 9050</span></div></div><div><div><div>7</div></div><div><span><span>               </span></span><span>BePort: 9060</span></div></div><div><div><div>8</div></div><div><span><span>             </span></span><span>HttpPort: 8040</span></div></div><div><div><div>9</div></div><div><span><span>             </span></span><span>BrpcPort: 8060</span></div></div><div><div><div>10</div></div><div><span><span>        </span></span><span>LastStartTime: 2022-04-29 14:01:04</span></div></div><div><div><div>11</div></div><div><span><span>        </span></span><span>LastHeartbeat: 2022-04-29 14:02:11</span></div></div><div><div><div>12</div></div><div><span><span>                </span></span><span>Alive: true</span></div></div><div><div><div>13</div></div><div><span><span> </span></span><span>SystemDecommissioned: false</span></div></div><div><div><div>14</div></div><div><span>ClusterDecommissioned: false</span></div></div><div><div><div>15</div></div><div><span><span>            </span></span><span>TabletNum: 0</span></div></div><div><div><div>16</div></div><div><span><span>     </span></span><span>DataUsedCapacity: .000</span></div></div><div><div><div>17</div></div><div><span><span>        </span></span><span>AvailCapacity: 34.793 GB</span></div></div><div><div><div>18</div></div><div><span><span>        </span></span><span>TotalCapacity: 49.976 GB</span></div></div><div><div><div>19</div></div><div><span><span>              </span></span><span>UsedPct: 30.38 %</span></div></div><div><div><div>20</div></div><div><span><span>       </span></span><span>MaxDiskUsedPct: 30.38 %</span></div></div><div><div><div>21</div></div><div><span><span>               </span></span><span>ErrMsg:</span></div></div><div><div><div>22</div></div><div><span><span>              </span></span><span>Version: 0.14.0-release-Unknown</span></div></div><div><div><div>23</div></div><div><span><span>               </span></span><span>Status: {"lastSuccessReportTabletsTime":"2022-04-29 14:02:10"}</span></div></div><div><div><div>24</div></div><div><span>1 row in set (20.04 sec)</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<p><strong>一般Alive为true即为状态正常，若为false，可根据日志排查问题。同样的，因为当前BE为初次启动，如果出现无法快速定位的问题，可以清空storage数据目录，重新启动服务。</strong></p>
</li>
</ul></section><section><h5>6. 部署Broker<a href="#6-部署broker"><span>#</span></a></h5><p>在部署完FE与BE后，StarRocks主要服务已经部署完成。Broker是StarRocks与外部HDFS/对象存储等外部数据对接的中转服务，若不需要可以不部署。Broker本身是无状态的进程，可以随意启停，不影响集群。</p><ul>
<li>
<p>修改Broker配置文件</p>
<blockquote><p>Broker的配置文件通常不需要修改。与FE实例和BE实例不同，Broker当前没有也不需要priority_networks这个选项。Broker的服务默认绑定在0.0.0.0上，我们只需在前面4.5节 ADD BROKER时，输入正确可访问的BROKER IP即可。</p></blockquote>
</li>
<li>
<p>启动Broker</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@starrocks bin]# cd /opt/module/starrocks/apache_hdfs_broker/bin/</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>[root@starrocks bin]# ./start_broker.sh --daemon</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p><strong>补充：关闭Broker脚本为stop_broker.sh，命令：./stop_broker.sh</strong></p>
<blockquote><p>查看java进程，若发现有BrokerBootstrap即为启动成功：</p></blockquote>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@starrocks bin]# jps | grep BrokerBootstrap</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>7594 BrokerBootstrap</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>Broker日志在apache_hdfs_broker.log中，如果进程状态异常可查看日志追踪原因。</p>
</li>
<li>
<p>查看Broker状态</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@starrocks bin]# mysql -h127.0.0.1 -P9030 -uroot</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>mysql&gt; show broker\G</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>*************************** 1. row ***************************</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span><span>          </span></span><span>Name: hdfs_broker</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span><span>            </span></span><span>IP: 172.18.88.54</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span><span>          </span></span><span>Port: 8000</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span><span>         </span></span><span>Alive: true</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span><span> </span></span><span>LastStartTime: 2021-11-25 20:19:56</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>LastUpdateTime: 2021-11-25 20:21:31</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span><span>        </span></span><span>ErrMsg:</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>1 row in set (0.01 sec)</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
<p><em>Alive为true即为状态正常，如果状态异常可以根据日志定位问题。</em></p>
</li>
</ul></section></section><section><h4>4、简单使用<a href="#4简单使用"><span>#</span></a></h4><section><h5>1. 修改root账户密码<a href="#1-修改root账户密码"><span>#</span></a></h5><p>例如修改root密码也为root：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>mysql&gt; set password=password('root');</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>Query OK, 0 rows affected (0.02 sec)</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h5>2. 建库建表<a href="#2-建库建表"><span>#</span></a></h5><p>StarRocks的副本数是不能大于BE节点数的，由于当前仅有一个BE节点，我们建表时<strong>务必注意指定数据为单副本</strong>，示例如下：
新建一个starrocks数据库：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>mysql&gt; create database starrocks;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>Query OK, 0 rows affected (0.01 sec)</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>mysql&gt; use starrocks;</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>Database changed</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/bec8364e/</id>
      <title type="text">【Linux】Vim命令合集</title>
      <published>2024-05-21T08:31:13.000Z</published>
      <updated>2024-05-21T08:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/bec8364e/"/>
      <summary type="text">本文《【Linux】Vim命令合集》详细总结了Vim编辑器的各种常用命令和技巧。每个命令都配有详细的说明和使用示例，适合初学者和进阶用户学习和参考。文章最后还提供了Vim教程的启动方法和一些参考文档。</summary>
      <content type="html"><![CDATA[<section><h2>命令历史<a href="#命令历史"><span>#</span></a></h2><blockquote><p>以&lt;和&gt;/开头的命令都有历史纪录，可以首先键入&lt;或&gt;/然后按上下箭头来选择某个历史命令。</p></blockquote></section>
<section><h2>启动vim<a href="#启动vim"><span>#</span></a></h2><blockquote><p>在命令行窗口中输入以下命令即可</p><p>vim 直接启动vim</p><p>vim filename 打开vim并创建名为filename的文件</p></blockquote></section>
<section><h2>文件命令<a href="#文件命令"><span>#</span></a></h2><blockquote><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 打开单个文件</span></div></div><div><div><div>2</div></div><div><span>vim</span><span> </span><span>file</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 同时打开多个文件</span></div></div><div><div><div>5</div></div><div><span>vim</span><span> </span><span>file1</span><span> </span><span>file2</span><span> </span><span>file3</span><span> </span><span>...</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 在vim窗口中打开一个新文件</span></div></div><div><div><div>8</div></div><div><span>:open</span><span> </span><span>file</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 在新窗口中打开文件</span></div></div><div><div><div>11</div></div><div><span>:split</span><span> </span><span>file</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># 切换到下一个文件</span></div></div><div><div><div>14</div></div><div><span>:bn</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span># 切换到上一个文件</span></div></div><div><div><div>17</div></div><div><span>:bp</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span># 查看当前打开的文件列表，当前正在编辑的文件会用[]括起来。</span></div></div><div><div><div>20</div></div><div><span>:args</span></div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span># 打开远程文件，比如ftp或者share folder</span></div></div><div><div><div>23</div></div><div><span>:e</span><span> </span><span>ftp://192.168.10.76/abc.txt</span></div></div><div><div><div>24</div></div><div><span>:e</span><span> </span><span>\\</span><span>qadrive</span><span>\t</span><span>est</span><span>\1</span><span>.txt</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></blockquote></section>
<section><h2>vim的模式<a href="#vim的模式"><span>#</span></a></h2><section><h3>导航命令<a href="#导航命令"><span>#</span></a></h3><p>% 括号匹配</p></section><section><h3>插入命令<a href="#插入命令"><span>#</span></a></h3><p>i 在当前位置生前插入</p><p>I 在当前行首插入</p><p>a 在当前位置后插入</p><p>A 在当前行尾插入</p><p>o 在当前行之后插入一行</p><p>O 在当前行之前插入一行</p></section><section><h3>查找命令<a href="#查找命令"><span>#</span></a></h3><p><code> /text　　</code>查找text，按n健查找下一个，按N健查找前一个。</p><p><code> ?text　</code>　查找text，反向查找，按n健查找下一个，按N健查找前一个。</p><p>vim中有一些特殊字符在查找时需要转义　　.*[]^%/?~$</p><p><code> :set ignorecase</code>　　忽略大小写的查找</p><p><code> :set noignorecase</code>　　不忽略大小写的查找</p><p>查找很长的词，如果一个词很长，键入麻烦，可以将光标移动到该词上，按*或#键即可以该单词进行搜索，相当于/搜索。而#命令相当于?搜索。</p><p><code>:set hlsearch</code>　　高亮搜索结果，所有结果都高亮显示，而不是只显示一个匹配。</p><p><code> :set nohlsearch</code>　关闭高亮搜索显示</p><p><code> :nohlsearch</code>　　关闭当前的高亮显示，如果再次搜索或者按下n或N键，则会再次高亮。</p><p><code> :set incsearch</code>　　逐步搜索模式，对当前键入的字符进行搜索而不必等待键入完成。</p><p><code> :set wrapscan</code>　　重新搜索，在搜索到文件头或尾时，返回继续搜索，默认开启。</p></section><section><h3>替换命令<a href="#替换命令"><span>#</span></a></h3><p><code> ra</code> 将当前字符替换为a，当期字符即光标所在字符。</p><p><code> s/old/new/</code> 用old替换new，替换当前行的第一个匹配</p><p><code>s/old/new/g</code>用old替换new，替换当前行的所有匹配</p><p><code> %s/old/new/</code> 用old替换new，替换所有行的第一个匹配</p><p><code>%s/old/new/g</code>用old替换new，替换整个文件的所有匹配</p><p><code>:10,20 s/^/  /g</code>在第10行知第20行每行前面加四个空格，用于缩进。</p><p><code>ddp</code> 交换光标所在行和其下紧邻的一行。</p></section><section><h3>移动命令<a href="#移动命令"><span>#</span></a></h3><p><code>h</code> 左移一个字符
l 右移一个字符，这个命令很少用，一般用w代替。
<code>k</code> 上移一个字符
<code>j</code> 下移一个字符
以上四个命令可以配合数字使用，比如20j就是向下移动20行，5h就是向左移动5个字符，在Vim中，很多命令都可以配合数字使用，比如删除10个字符10x，在当前位置后插入3个！，3a！&lt;Esc&gt;，这里的Esc是必须的，否则命令不生效。</p><p><code>w</code> 向前移动一个单词（光标停在单词首部），如果已到行尾，则转至下一行行首。此命令快，可以代替l命令。</p><p><code>b</code> 向后移动一个单词 2b 向后移动2个单词</p><p><code>e</code>，同w，只不过是光标停在单词尾部</p><p><code>ge</code>，同b，光标停在单词尾部。</p><p><code>^</code> 移动到本行第一个非空白字符上。</p><p><code>0</code>（数字0）移动到本行第一个字符上，</p><p>&lt;HOME&gt; 移动到本行第一个字符。同0健。</p><p><code>$ 移动到行尾 3$</code> 移动到下面3行的行尾</p><p><code>gg</code> 移动到文件头。 = [[</p><p><code>G</code>（shift + g） 移动到文件尾。 = ]]</p><p><code>f（find）</code>命令也可以用于移动，fx将找到光标后第一个为x的字符，3fd将找到第三个为d的字符。</p><p>F 同f，反向查找。</p><p>跳到指定行，冒号+行号，回车，比如跳到240行就是 &lt;240回车&gt;。另一个方法是行号+G，比如230G跳到230行。</p><p><code>Ctrl + e</code> 向下滚动一行</p><p><code>Ctrl + y</code> 向上滚动一行</p><p><code>Ctrl + d</code> 向下滚动半屏</p><p><code>Ctrl + u</code> 向上滚动半屏</p><p><code>Ctrl + f</code> 向下滚动一屏</p><p><code>Ctrl + b</code> 向上滚动一屏</p></section><section><h3>撤销和重做<a href="#撤销和重做"><span>#</span></a></h3><p><code>u</code> 撤销（Undo）
<code>U</code> 撤销对整行的操作
<code>Ctrl + r</code> 重做（Redo），即撤销的撤销。</p></section><section><h3>删除命令<a href="#删除命令"><span>#</span></a></h3><p><code>x</code> 删除当前字符</p><p><code>3x</code> 删除当前光标开始向后三个字符</p><p><code>X</code> 删除当前字符的前一个字符。X=dh</p><p><code>dl</code> 删除当前字符， dl=x</p><p><code>dh</code> 删除前一个字符</p><p><code>dd</code> 删除当前行</p><p><code>dj</code> 删除上一行</p><p><code>dk</code> 删除下一行</p><p><code>10d</code> 删除当前行开始的10行。</p><p><code>D</code> 删除当前字符至行尾。D=d$</p><p><code>d</code>$ 删除当前字符之后的所有字符（本行）</p><p><code>kdgg</code> 删除当前行之前所有行（不包括当前行）</p><p><code>jdG</code>（jd shift + g）  删除当前行之后所有行（不包括当前行）</p><p><code>:1,10d</code> 删除1-10行</p><p><code>:11,\$d</code> 删除11行及以后所有的行</p><p><code>:1,\$d</code> 删除所有行</p><p><code>J(shift + j)</code>　　删除两行之间的空行，实际上是合并两行。</p></section><section><h3>拷贝和粘贴<a href="#拷贝和粘贴"><span>#</span></a></h3><p><code>yy</code> 拷贝当前行</p><p><code>nyy</code> 拷贝当前后开始的n行，比如2yy拷贝当前行及其下一行。</p><p><code>p</code> 在当前光标后粘贴,如果之前使用了yy命令来复制一行，那么就在当前行的下一行粘贴。</p><p><code>shift+p</code> 在当前行前粘贴</p><p><code>:1,10 co 20</code> 将1-10行插入到第20行之后。</p><p><code>:1,$co$</code> 将整个文件复制一份并添加到文件尾部。</p><p>正常模式下按v（逐字）或V（逐行）进入可视模式，然后用jklh命令移动即可选择某些行或字符，再按y即可复制</p><p><code>ddp</code>交换当前行和其下一行</p><p><code>xp</code>交换当前字符和其后一个字符</p></section><section><h3>剪切命令<a href="#剪切命令"><span>#</span></a></h3><p>正常模式下按v（逐字）或V（逐行）进入可视模式，然后用jklh命令移动即可选择某些行或字符，再按d即可剪切</p><p>ndd 剪切当前行之后的n行。利用p命令可以对剪切的内容进行粘贴</p><p><code>:1,10d</code> 将1-10行剪切。利用p命令可将剪切后的内容进行粘贴。</p><p><code>:1, 10 m 20</code> 将第1-10行移动到第20行之后。</p></section><section><h3>退出命令<a href="#退出命令"><span>#</span></a></h3><p><code>:wq</code> 保存并退出</p><p><code>ZZ</code> 保存并退出</p><p><code>:q!</code> 强制退出并忽略所有更改</p><p><code>:e!</code> 放弃所有修改，并打开原来文件。</p></section><section><h3>窗口命令<a href="#窗口命令"><span>#</span></a></h3><p><code>:split或new</code> 打开一个新窗口，光标停在顶层的窗口上</p><p><code>:split file或\:new file</code> 用新窗口打开文件</p><p><code>split</code>打开的窗口都是横向的，使用vsplit可以纵向打开窗口。</p><p><code>Ctrl+ww</code> 移动到下一个窗口</p><p><code>Ctrl+wj</code> 移动到下方的窗口</p><p><code>Ctrl+wk</code> 移动到上方的窗口</p><p>关闭窗口</p><p><code>:close</code> 最后一个窗口不能使用此命令，可以防止意外退出vim。</p><p><code>:q</code> 如果是最后一个被关闭的窗口，那么将退出vim。</p><p><code>ZZ</code> 保存并退出。</p><p>关闭所有窗口，只保留当前窗口</p><p>:only</p><p>录制宏</p><p>按q键加任意字母开始录制，再按q键结束录制（这意味着vim中的宏不可嵌套），使用的时候@加宏名，比如qa。。。q录制名为a的宏，@a使用这个宏。</p></section><section><h3>执行shell命令<a href="#执行shell命令"><span>#</span></a></h3><p>:!command</p><p>:!ls 列出当前目录下文件</p><p>:!perl -c script.pl 检查perl脚本语法，可以不用退出vim，非常方便。</p><p>:!perl script.pl 执行perl脚本，可以不用退出vim，非常方便。</p><p>:suspend或Ctrl - Z 挂起vim，回到shell，按fg可以返回vim。</p></section><section><h3>注释命令<a href="#注释命令"><span>#</span></a></h3><p>perl程序中#开始的行为注释，所以要注释某些行，只需在行首加入#</p><p>3,5 s/^/#/g 注释第3-5行</p><p>3,5 s/^#//g 解除3-5行的注释</p><p>1,$ s/^/#/g 注释整个文档。</p><p>:%s/^/#/g 注释整个文档，此法更快。</p></section><section><h3>帮助命令<a href="#帮助命令"><span>#</span></a></h3><p>:help or F1 显示整个帮助
:help xxx 显示xxx的帮助，比如 :help i, :help CTRL-[（即Ctrl+[的帮助）。
:help ‘number’ Vim选项的帮助用单引号括起
:help &lt;Esc&gt; 特殊键的帮助用&lt;&gt;扩起
:help -t Vim启动参数的帮助用-
：help i_&lt;Esc&gt; 插入模式下Esc的帮助，某个模式下的帮助用模式_主题的模式
帮助文件中位于||之间的内容是超链接，可以用Ctrl+]进入链接，Ctrl+o（Ctrl + t）返回</p></section><section><h3>其他非编辑命令<a href="#其他非编辑命令"><span>#</span></a></h3><p>. 重复前一次命令</p><p>:set ruler?　　查看是否设置了ruler，在.vimrc中，使用set命令设制的选项都可以通过这个命令查看</p><p>:scriptnames　　查看vim脚本文件的位置，比如.vimrc文件，语法文件及plugin等。</p><p>:set list 显示非打印字符，如tab，空格，行尾等。如果tab无法显示，请确定用set lcs=tab:&gt;-命令设置了.vimrc文件，并确保你的文件中的确有tab，如果开启了expendtab，那么tab将被扩展为空格。</p><p>Vim教程
在Unix系统上
$ vimtutor
在Windows系统上
:help tutor</p><p>:syntax 列出已经定义的语法项
:syntax clear 清除已定义的语法规则
:syntax case match 大小写敏感，int和Int将视为不同的语法元素
:syntax case ignore 大小写无关，int和Int将视为相同的语法元素，并使用同样的配色方案</p><p><strong>参考文档：</strong></p><ul>
<li><a href="https://www.cnblogs.com/softwaretesting/archive/2011/07/12/2104435.html" target="_blank">Vim命令合集</a></li>
</ul></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/bf223232/</id>
      <title type="text">【Linux】Linux环境下运行jar包的几种方式</title>
      <published>2024-05-21T08:31:13.000Z</published>
      <updated>2024-05-21T08:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/bf223232/"/>
      <summary type="text">在Linux系统中启动Java应用程序的多种方法。提供了一个启动、停止和管理多个Java应用的Shell脚本示例，以及如何设置服务开机自启的步骤，最后简要介绍了通过Systemd服务配置实现更高级的服务管理。这些内容对于希望在Linux环境中高效部署和管理Java应用的开发人员非常实用。</summary>
      <content type="html"><![CDATA[<section><h2>方式一(java -jar jar包名)<a href="#方式一java--jar-jar包名"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>    </span><span># 命令格式：java -jar jar包名</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>[root@localhost test_jar]# java -jar test_jar-1.0-SNAPSHOT.jar</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p><strong>分析：</strong> 执行此命令的时候，当前窗口被锁定，无法进行其它操作，直到main方法执行完毕，当前窗口才解除锁定。<br />
<strong>缺点：</strong> 锁定窗口。当然，我可以通过CTRL + C打断程序运行，或直接关闭窗口，程序退出，不过在实际的工作环境中，是绝对不会允许这种粗暴的方式终止的运行，毕竟我们的项目都是给用户提供服务的，程序要是退出了，公司还营不营业了。</p></blockquote></section>
<section><h2>方式二(java -jar jar包名 &amp;)<a href="#方式二java--jar-jar包名-"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>    </span><span>命令格式：java</span><span> </span><span>-jar</span><span> </span><span>jar包名</span><span> &amp;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>[root@localhost test_jar]# java -jar test_jar-1.0-SNAPSHOT.jar &amp;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p><strong>分析：</strong> &amp;代表在后台运行。优点是当前ssh窗口不被锁定，但是当窗口关闭时，程序终止运行。<br />
那么我们就会想，如何继续改进，让窗口关闭时，程序仍然运行呢？</p></blockquote></section>
<section><h2>方式三<a href="#方式三"><span>#</span></a></h2><blockquote><p>方式三主要是引入nohup命令，具体使用主要包括下面三种方式。</p></blockquote><section><h3>命令格式：nohup java -jar jar包名 &amp;<a href="#命令格式nohup-java--jar-jar包名-"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 命令格式：nohup java -jar jar包名 &amp;</span></div></div><div><div><div>2</div></div><div><span>[root@localhost test_jar]# nohup java -jar test_jar-1.0-SNAPSHOT.jar &amp;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>nohup 意思是不挂断运行命令 ，当账户退出或终端关闭时，程序仍然运行。<br />
当用 nohup 命令运行jar包时，缺省情况下该应用的所有输出被重定向到nohup.out的文件中，除非另外指定了输出文件。</p></blockquote></section><section><h3>命令格式:nohup java -jar jar包名 &gt; 文件名 &amp;<a href="#命令格式nohup-java--jar-jar包名--文件名-"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># nohup java -jar jar包名 &gt; 文件名 &amp;</span></div></div><div><div><div>2</div></div><div><span>[root@localhost test_jar]# nohup java -jar test_jar-1.0-SNAPSHOT.jar &gt; test.txt &amp;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>command &gt;test.file 是将commandd test.flie文件，即输出内容不打印到屏幕上，而是输出到 test.file文件中</p></blockquote></section><section><h3>命令格式: nohup java -jar jar包名 &gt;output 2&gt;&amp;1 &amp;<a href="#命令格式-nohup-java--jar-jar包名-output-21-"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># nohup java -jar jar包名 &gt;output 2&gt;&amp;1 &amp;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>[root@localhost test_jar]# nohup java -jar test_jar-1.0-SNAPSHOT.jar &gt;output 2&gt;&amp;1 &amp;</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>命令格式：nohup java -jar spring-boot-demo.jar &gt; /dev/null 2&gt;&amp;1 &amp;<a href="#命令格式nohup-java--jar-spring-boot-demojar--devnull-21-"><span>#</span></a></h3><blockquote><p>不输出日志</p></blockquote></section></section>
<section><h2>方式四：脚本方式<a href="#方式四脚本方式"><span>#</span></a></h2><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/bin/bash</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>#这里可替换为你自己的执行程序，其他代码无需更改</span></div></div><div><div><div>4</div></div><div><span>APP_NAME</span><span>=</span><span>test_jar-1.0-SNAPSHOT.jar</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>#使用说明，用来提示输入参数</span></div></div><div><div><div>8</div></div><div><span>usage</span><span>() {</span></div></div><div><div><div>9</div></div><div><span>    </span><span>echo</span><span> </span><span>"Usage: sh 脚本名.sh [start|stop|restart|status]"</span></div></div><div><div><div>10</div></div><div><span>    </span><span>exit</span><span> </span><span>1</span></div></div><div><div><div>11</div></div><div><span>}</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>#检查程序是否在运行</span></div></div><div><div><div>14</div></div><div><span>is_exist</span><span>(){</span></div></div><div><div><div>15</div></div><div><span>  </span><span>pid</span><span>=</span><span>`</span><span>ps</span><span> </span><span>-ef</span><span>|</span><span>grep</span><span> </span><span>$APP_NAME</span><span>|</span><span>grep</span><span> </span><span>-v</span><span> grep</span><span>|</span><span>awk</span><span> '{print $2}' `</span></div></div><div><div><div>16</div></div><div><span>  </span><span>#如果不存在返回1，存在返回0</span></div></div><div><div><div>17</div></div><div><span>  </span><span>if</span><span><span> [ </span><span>-z</span><span> </span></span><span>"</span><span><span>${</span><span>pid</span><span>}</span></span><span>"</span><span> ]; </span><span>then</span></div></div><div><div><div>18</div></div><div><span>   </span><span>return</span><span> </span><span>1</span></div></div><div><div><div>19</div></div><div><span>  </span><span>else</span></div></div><div><div><div>20</div></div><div><span>    </span><span>return</span><span> </span><span>0</span></div></div><div><div><div>21</div></div><div><span>  </span><span>fi</span></div></div><div><div><div>22</div></div><div><span>}</span></div></div><div><div><div>23</div></div><div>
</div></div><div><div><div>24</div></div><div><span>#启动方法</span></div></div><div><div><div>25</div></div><div><span>start</span><span>(){</span></div></div><div><div><div>26</div></div><div><span>  </span><span>is_exist</span></div></div><div><div><div>27</div></div><div><span>  </span><span>if</span><span> [ </span><span>$?</span><span><span> </span><span>-eq</span><span> </span></span><span>"0"</span><span> ]; </span><span>then</span></div></div><div><div><div>28</div></div><div><span>    </span><span>echo</span><span> </span><span>"</span><span><span>${</span><span>APP_NAME</span><span>}</span></span><span> is already running. pid=</span><span><span>${</span><span>pid</span><span>}</span></span><span> ."</span></div></div><div><div><div>29</div></div><div><span>  </span><span>else</span></div></div><div><div><div>30</div></div><div><span>    </span><span>nohup</span><span> </span><span>java</span><span> </span><span>-Xmx512m</span><span> </span><span>-Xms512m</span><span> </span><span>-jar</span><span> </span><span>$APP_NAME</span><span>  &gt; </span><span>./logs/`</span><span>log+%Y-%m-%d</span><span>`</span><span>.txt</span><span> 2&gt;&amp;1 &amp;</span></div></div><div><div><div>31</div></div><div><span>    </span><span>echo</span><span> </span><span>"</span><span><span>${</span><span>APP_NAME</span><span>}</span></span><span> start success"</span></div></div><div><div><div>32</div></div><div><span>  </span><span>fi</span></div></div><div><div><div>33</div></div><div><span>}</span></div></div><div><div><div>34</div></div><div>
</div></div><div><div><div>35</div></div><div><span>#停止方法</span></div></div><div><div><div>36</div></div><div><span>stop</span><span>(){</span></div></div><div><div><div>37</div></div><div><span>  </span><span>is_exist</span></div></div><div><div><div>38</div></div><div><span>  </span><span>if</span><span> [ </span><span>$?</span><span><span> </span><span>-eq</span><span> </span></span><span>"0"</span><span> ]; </span><span>then</span></div></div><div><div><div>39</div></div><div><span>    </span><span>kill</span><span> </span><span>-9</span><span> </span><span>$pid</span></div></div><div><div><div>40</div></div><div><span>  </span><span>else</span></div></div><div><div><div>41</div></div><div><span>    </span><span>echo</span><span> </span><span>"</span><span><span>${</span><span>APP_NAME</span><span>}</span></span><span> is not running"</span></div></div><div><div><div>42</div></div><div><span>  </span><span>fi</span></div></div><div><div><div>43</div></div><div><span>}</span></div></div><div><div><div>44</div></div><div>
</div></div><div><div><div>45</div></div><div><span>#输出运行状态</span></div></div><div><div><div>46</div></div><div><span>status</span><span>(){</span></div></div><div><div><div>47</div></div><div><span>  </span><span>is_exist</span></div></div><div><div><div>48</div></div><div><span>  </span><span>if</span><span> [ </span><span>$?</span><span><span> </span><span>-eq</span><span> </span></span><span>"0"</span><span> ]; </span><span>then</span></div></div><div><div><div>49</div></div><div><span>    </span><span>echo</span><span> </span><span>"</span><span><span>${</span><span>APP_NAME</span><span>}</span></span><span> is running. Pid is </span><span><span>${</span><span>pid</span><span>}</span></span><span>"</span></div></div><div><div><div>50</div></div><div><span>  </span><span>else</span></div></div><div><div><div>51</div></div><div><span>    </span><span>echo</span><span> </span><span>"</span><span><span>${</span><span>APP_NAME</span><span>}</span></span><span> is NOT running."</span></div></div><div><div><div>52</div></div><div><span>  </span><span>fi</span></div></div><div><div><div>53</div></div><div><span>}</span></div></div><div><div><div>54</div></div><div>
</div></div><div><div><div>55</div></div><div><span>#重启</span></div></div><div><div><div>56</div></div><div><span>restart</span><span>(){</span></div></div><div><div><div>57</div></div><div><span>  </span><span>stop</span></div></div><div><div><div>58</div></div><div><span>  </span><span>start</span></div></div><div><div><div>59</div></div><div><span>}</span></div></div><div><div><div>60</div></div><div>
</div></div><div><div><div>61</div></div><div><span>#根据输入参数，选择执行对应方法，不输入则执行使用说明</span></div></div><div><div><div>62</div></div><div><span>case</span><span> </span><span>"</span><span>$1</span><span>"</span><span> </span><span>in</span></div></div><div><div><div>63</div></div><div><span>  </span><span>"start"</span><span>)</span></div></div><div><div><div>64</div></div><div><span>    </span><span>start</span></div></div><div><div><div>65</div></div><div><span><span>    </span></span><span>;;</span></div></div><div><div><div>66</div></div><div><span>  </span><span>"stop"</span><span>)</span></div></div><div><div><div>67</div></div><div><span>    </span><span>stop</span></div></div><div><div><div>68</div></div><div><span><span>    </span></span><span>;;</span></div></div><div><div><div>69</div></div><div><span>  </span><span>"status"</span><span>)</span></div></div><div><div><div>70</div></div><div><span>    </span><span>status</span></div></div><div><div><div>71</div></div><div><span><span>    </span></span><span>;;</span></div></div><div><div><div>72</div></div><div><span>  </span><span>"restart"</span><span>)</span></div></div><div><div><div>73</div></div><div><span>    </span><span>restart</span></div></div><div><div><div>74</div></div><div><span><span>    </span></span><span>;;</span></div></div><div><div><div>75</div></div><div><span><span>  </span></span><span>*)</span></div></div><div><div><div>76</div></div><div><span>    </span><span>usage</span></div></div><div><div><div>77</div></div><div><span><span>    </span></span><span>;;</span></div></div><div><div><div>78</div></div><div><span>esac</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>
<section><h2>附录一： nohup 和 &amp;<a href="#附录一-nohup-和-"><span>#</span></a></h2><blockquote><p>使用 <code>&amp;</code> 后台运行程序:</p><ul>
<li>结果会输出到终端</li>
<li>使用Ctrl + C，程序免疫</li>
<li>关闭session，程序关闭</li>
</ul></blockquote><blockquote><p>使用<code>nohup</code>运行程序</p><ul>
<li>结果默认会输出到nohup.out</li>
<li>使用Ctrl + C，程序关闭</li>
<li>关闭session，程序免疫</li>
</ul></blockquote><blockquote><p>平日线上经常使用nohup和&amp;配合来启动程序</p></blockquote></section>
<section><h2>附录二：<code>&gt;</code> <code>/dev/null</code> <code>2&gt;&amp;1</code><a href="#附录二-devnull-21"><span>#</span></a></h2><blockquote><ul>
<li><code>&gt;</code> 标准重定向符，允许我们创建一个 0KB的空文件。它通常用于重定向一个命令的输出到一个新文件中。在没有命令的情况下使用重定向符号时，它会创建一个文件。</li>
<li><code>/dev/null</code> 可以看作黑洞，等价于一个只写文件。所有写入它的内容都会永远丢失，尝试从它那儿读取内容则什么也读不到。也就是将所有产生的日志将被丢弃</li>
<li><code>2&gt;&amp;1</code>符号&gt;&amp;是一个整体代表将标准错误2重定向到标准输出1,如果是2&gt;1的话，代表将标准错误输出到文件1，而不是重定向到标准输出流</li>
</ul></blockquote><blockquote><p>先了解下1和2在Linux中代表什么<br />
当Linux执行一个程序时，会自动打开三个流</p><ul>
<li>0：标准输入流（默认是键盘）</li>
<li>1：标准输出流（默认是屏幕）</li>
<li>2：标准错误流（默认是屏幕）</li>
</ul></blockquote>

<table><thead><tr><th>名称</th><th>代码</th><th>操作符</th><th>java中表示</th><th>Linux中文件描述符</th></tr></thead><tbody><tr><td>标准输入(stdin)</td><td>0</td><td>&lt; 或 &lt;&lt;</td><td>System.in</td><td>/dev/stdin -&gt; /proc/self/fd/0 -&gt; /dev/pts/0</td></tr><tr><td>标准输出(stdout)</td><td>1</td><td>&gt;, &gt;&gt;, 1&gt; 或 1&gt;&gt;</td><td>System.out</td><td>/dev/stdout -&gt; /proc/self/fd/1 -&gt; /dev/pts/0</td></tr><tr><td>标准错误输出(stderr)</td><td>2</td><td>2&gt; 或 2&gt;&gt;</td><td>System.err</td><td>/dev/stderr -&gt; /proc/self/fd/2 -&gt; /dev/pts/0</td></tr></tbody></table></section>
<section><h2>批量启动、停止jar包<a href="#批量启动停止jar包"><span>#</span></a></h2><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/bin/bash</span></div></div><div><div><div>2</div></div><div><span># 端口号</span></div></div><div><div><div>3</div></div><div><span>PORTS</span><span><span>=</span><span>(</span></span><span>9500</span><span> </span><span>9600</span><span> </span><span>9801</span><span> </span><span>9802</span><span> </span><span>9803</span><span> </span><span>9804</span><span> </span><span>9805</span><span> </span><span>9901</span><span> </span><span>9902</span><span>)</span></div></div><div><div><div>4</div></div><div><span># 系统模块</span></div></div><div><div><div>5</div></div><div><span>MODULES</span><span><span>=</span><span>(</span></span><span>gateway</span><span> </span><span>auth</span><span> </span><span>system</span><span> </span><span>job</span><span> </span><span>gen</span><span> </span><span>file</span><span> </span><span>risk</span><span> </span><span>supervise</span><span> </span><span>ssologin</span><span>)</span></div></div><div><div><div>6</div></div><div><span># 系统模块名称</span></div></div><div><div><div>7</div></div><div><span>MODULE_NAMES</span><span><span>=</span><span>(</span></span><span>网关模块</span><span> </span><span>鉴权模块</span><span> </span><span>系统管理模块</span><span> </span><span>定时任务模块</span><span> </span><span>代码生成模块</span><span> </span><span>文件管理模块</span><span> </span><span>风险预警模块</span><span>)</span></div></div><div><div><div>8</div></div><div><span># jar包数组</span></div></div><div><div><div>9</div></div><div><span>JARS</span><span><span>=</span><span>(</span></span><span>catsticloud-gateway.jar</span><span> </span><span>catsticloud-auth.jar</span><span> </span><span>catsticloud-modules-system.jar</span><span> </span><span>catsticloud-modules-job.jar</span><span> </span><span>catsticloud-modules-gen.jar</span><span> </span><span>catsticloud-modules-file.jar</span><span> </span><span>catsticloud-modules-risk.jar</span><span> </span><span>catsticloud-supervise.jar</span><span> </span><span>catsticloud-modules-ssologin.jar</span><span>)</span></div></div><div><div><div>10</div></div><div><span># jar包路径</span></div></div><div><div><div>11</div></div><div><span>JAR_PATH</span><span>=</span><span>'/home/yunwei/gonggonganquan/jar'</span></div></div><div><div><div>12</div></div><div><span># 日志路径</span></div></div><div><div><div>13</div></div><div><span>LOG_PATH</span><span>=</span><span>'/home/yunwei/gonggonganquan/jar/logs'</span></div></div><div><div><div>14</div></div><div><span>start</span><span>() {</span></div></div><div><div><div>15</div></div><div><span>  </span><span>local</span><span> </span><span>MODULE</span><span>=</span></div></div><div><div><div>16</div></div><div><span>  </span><span>local</span><span> </span><span>MODULE_NAME</span><span>=</span></div></div><div><div><div>17</div></div><div><span>  </span><span>local</span><span> </span><span>JAR_NAME</span><span>=</span></div></div><div><div><div>18</div></div><div><span>  </span><span>local</span><span> </span><span>command</span><span>=</span><span>"</span><span>$1</span><span>"</span></div></div><div><div><div>19</div></div><div><span>  </span><span>local</span><span> </span><span>commandOk</span><span>=</span><span>0</span></div></div><div><div><div>20</div></div><div><span>  </span><span>local</span><span> </span><span>count</span><span>=</span><span>0</span></div></div><div><div><div>21</div></div><div><span>  </span><span>local</span><span> </span><span>okCount</span><span>=</span><span>0</span></div></div><div><div><div>22</div></div><div><span>  </span><span>local</span><span> </span><span>port</span><span>=</span><span>0</span></div></div><div><div><div>23</div></div><div><span>  </span><span>for</span><span>((</span><span>i</span><span>=</span><span>0</span><span>;</span><span>i</span><span>&lt;</span><span>${</span><span>#</span><span>MODULES</span><span>[@]</span><span>}</span><span>;</span><span>i</span><span><span>++</span><span>))</span></span></div></div><div><div><div>24</div></div><div><span>  </span><span>do</span></div></div><div><div><div>25</div></div><div><span>    </span><span>MODULE</span><span>=</span><span><span>${</span><span>MODULES</span></span><span>[</span><span>$i</span><span>]</span><span>}</span></div></div><div><div><div>26</div></div><div><span>    </span><span>MODULE_NAME</span><span>=</span><span><span>${</span><span>MODULE_NAMES</span></span><span>[</span><span>$i</span><span>]</span><span>}</span></div></div><div><div><div>27</div></div><div><span>    </span><span>JAR_NAME</span><span>=</span><span><span>${</span><span>JARS</span></span><span>[</span><span>$i</span><span>]</span><span>}</span></div></div><div><div><div>28</div></div><div><span>    </span><span>PORT</span><span>=</span><span><span>${</span><span>PORTS</span></span><span>[</span><span>$i</span><span>]</span><span>}</span></div></div><div><div><div>29</div></div><div><span>    </span><span>if</span><span> [ </span><span>"</span><span>$command</span><span>"</span><span><span> </span><span>==</span><span> </span></span><span>"all"</span><span> ] || [ </span><span>"</span><span>$command</span><span>"</span><span><span> </span><span>==</span><span> </span></span><span>"</span><span>$MODULE</span><span>"</span><span> ];</span><span>then</span></div></div><div><div><div>30</div></div><div><span>      </span><span>commandOk</span><span>=</span><span>1</span></div></div><div><div><div>31</div></div><div><span>      </span><span>count</span><span>=</span><span>0</span></div></div><div><div><div>32</div></div><div><span>      </span><span>PID</span><span>=</span><span>`</span><span>ps</span><span> </span><span>-ef</span><span> </span><span>|</span><span>grep</span><span> $(</span><span>echo</span><span> </span><span>$JAR_NAME</span><span> </span><span>|</span><span> </span><span>awk</span><span> </span><span>-F/</span><span> '{print $NF}') </span><span>|</span><span> </span><span>grep</span><span> </span><span>-v</span><span> grep </span><span>|</span><span> </span><span>awk</span><span> '{print $2}'`</span></div></div><div><div><div>33</div></div><div><span>      </span><span>if</span><span><span> [ </span><span>-n</span><span> </span></span><span>"</span><span>$PID</span><span>"</span><span> ];</span><span>then</span></div></div><div><div><div>34</div></div><div><span>        </span><span>echo</span><span> </span><span>"</span><span>$MODULE</span><span>---</span><span>$MODULE_NAME</span><span>:已经运行,PID=</span><span>$PID</span><span>"</span></div></div><div><div><div>35</div></div><div><span>      </span><span>else</span></div></div><div><div><div>36</div></div><div><span>        </span><span>exec</span><span> </span><span>nohup</span><span> </span><span>java</span><span> </span><span>-jar</span><span> </span><span>$JAR_PATH</span><span>/</span><span>$JAR_NAME</span><span> &gt; </span><span>/dev/null</span><span>  2&gt;&amp;1 &amp;</span></div></div><div><div><div>37</div></div><div><span>        </span><span>PID</span><span>=</span><span>`</span><span>netstat</span><span> </span><span>-apn</span><span> </span><span>|</span><span> </span><span>grep</span><span> </span><span>$PORT</span><span> </span><span>|</span><span> </span><span>awk</span><span> '{print $7}' </span><span>|</span><span> </span><span>cut</span><span> </span><span>-d/</span><span> </span><span>-f</span><span> </span><span>1</span><span>`</span></div></div><div><div><div>38</div></div><div><span>        </span><span>while</span><span> </span><span>[</span><span> </span><span>-z</span><span> </span><span>"</span><span>$PID</span><span>"</span><span> ]</span></div></div><div><div><div>39</div></div><div><span>        </span><span>do</span></div></div><div><div><div>40</div></div><div><span>          </span><span>if</span><span> ((</span><span>$count</span><span><span> </span><span>==</span><span> </span></span><span>30</span><span>));</span><span>then</span></div></div><div><div><div>41</div></div><div><span>            </span><span>echo</span><span> </span><span>"</span><span>$MODULE</span><span>---</span><span>$MODULE_NAME</span><span>:$(</span><span>expr</span><span> </span><span>$count</span><span> </span><span>\*</span><span> </span><span>10</span><span>)秒内未启动,请检查!"</span></div></div><div><div><div>42</div></div><div><span>            </span><span>break</span></div></div><div><div><div>43</div></div><div><span>          </span><span>fi</span></div></div><div><div><div>44</div></div><div><span>          </span><span>count</span><span><span>=</span><span>$((</span></span><span>$count</span><span>+1))</span></div></div><div><div><div>45</div></div><div><span>          </span><span>echo</span><span> </span><span>"</span><span>$MODULE_NAME启动中</span><span>.................."</span></div></div><div><div><div>46</div></div><div><span>          </span><span>sleep</span><span> </span><span>10s</span></div></div><div><div><div>47</div></div><div><span>          </span><span>PID</span><span>=</span><span>`</span><span>netstat</span><span> </span><span>-apn</span><span> </span><span>|</span><span> </span><span>grep</span><span> </span><span>$PORT</span><span> </span><span>|</span><span> </span><span>awk</span><span> '{print $7}' </span><span>|</span><span> </span><span>cut</span><span> </span><span>-d/</span><span> </span><span>-f</span><span> </span><span>1</span><span>`</span></div></div><div><div><div>48</div></div><div><span>        </span><span>done</span></div></div><div><div><div>49</div></div><div><span>        </span><span>okCount</span><span><span>=</span><span>$((</span></span><span>$okCount</span><span>+1))</span></div></div><div><div><div>50</div></div><div><span>        </span><span>echo</span><span> </span><span>"</span><span>$MODULE</span><span>---</span><span>$MODULE_NAME</span><span>:已经启动成功,PID=</span><span>$PID</span><span>"</span></div></div><div><div><div>51</div></div><div><span>      </span><span>fi</span></div></div><div><div><div>52</div></div><div><span>    </span><span>fi</span></div></div><div><div><div>53</div></div><div><span>  </span><span>done</span></div></div><div><div><div>54</div></div><div><span><span>  </span></span><span>if((</span><span>$commandOk</span><span><span> </span><span>==</span><span> </span></span><span>0</span><span>));</span><span>then</span></div></div><div><div><div>55</div></div><div><span>    </span><span>echo</span><span> </span><span>"第二个参数请输入:all|gateway|auth|system|job|gen|file|risk|supervise|ssologin"</span></div></div><div><div><div>56</div></div><div><span>  </span><span>else</span></div></div><div><div><div>57</div></div><div><span>    </span><span>echo</span><span> </span><span>"............本次共启动:</span><span>$okCount个服务</span><span>..........."</span></div></div><div><div><div>58</div></div><div><span>  </span><span>fi</span></div></div><div><div><div>59</div></div><div><span>}</span></div></div><div><div><div>60</div></div><div>
</div></div><div><div><div>61</div></div><div><span>stop</span><span>() {</span></div></div><div><div><div>62</div></div><div><span>  </span><span>local</span><span> </span><span>MODULE</span><span>=</span></div></div><div><div><div>63</div></div><div><span>  </span><span>local</span><span> </span><span>MODULE_NAME</span><span>=</span></div></div><div><div><div>64</div></div><div><span>  </span><span>local</span><span> </span><span>JAR_NAME</span><span>=</span></div></div><div><div><div>65</div></div><div><span>  </span><span>local</span><span> </span><span>command</span><span>=</span><span>"</span><span>$1</span><span>"</span></div></div><div><div><div>66</div></div><div><span>  </span><span>local</span><span> </span><span>commandOk</span><span>=</span><span>0</span></div></div><div><div><div>67</div></div><div><span>  </span><span>local</span><span> </span><span>okCount</span><span>=</span><span>0</span></div></div><div><div><div>68</div></div><div><span>  </span><span>for</span><span>((</span><span>i</span><span>=</span><span>0</span><span>;</span><span>i</span><span>&lt;</span><span>${</span><span>#</span><span>MODULES</span><span>[@]</span><span>}</span><span>;</span><span>i</span><span><span>++</span><span>))</span></span></div></div><div><div><div>69</div></div><div><span>  </span><span>do</span></div></div><div><div><div>70</div></div><div><span>    </span><span>MODULE</span><span>=</span><span><span>${</span><span>MODULES</span></span><span>[</span><span>$i</span><span>]</span><span>}</span></div></div><div><div><div>71</div></div><div><span>    </span><span>MODULE_NAME</span><span>=</span><span><span>${</span><span>MODULE_NAMES</span></span><span>[</span><span>$i</span><span>]</span><span>}</span></div></div><div><div><div>72</div></div><div><span>    </span><span>JAR_NAME</span><span>=</span><span><span>${</span><span>JARS</span></span><span>[</span><span>$i</span><span>]</span><span>}</span></div></div><div><div><div>73</div></div><div><span>    </span><span>if</span><span> [ </span><span>"</span><span>$command</span><span>"</span><span><span> </span><span>=</span><span> </span></span><span>"all"</span><span> ] || [ </span><span>"</span><span>$command</span><span>"</span><span><span> </span><span>=</span><span> </span></span><span>"</span><span>$MODULE</span><span>"</span><span> ];</span><span>then</span></div></div><div><div><div>74</div></div><div><span>      </span><span>commandOk</span><span>=</span><span>1</span></div></div><div><div><div>75</div></div><div><span>      </span><span>PID</span><span>=</span><span>`</span><span>ps</span><span> </span><span>-ef</span><span> </span><span>|</span><span>grep</span><span> $(</span><span>echo</span><span> </span><span>$JAR_NAME</span><span> </span><span>|</span><span> </span><span>awk</span><span> </span><span>-F/</span><span> '{print $NF}') </span><span>|</span><span> </span><span>grep</span><span> </span><span>-v</span><span> grep </span><span>|</span><span> </span><span>awk</span><span> '{print $2}'`</span></div></div><div><div><div>76</div></div><div><span>      </span><span>if</span><span><span> [ </span><span>-n</span><span> </span></span><span>"</span><span>$PID</span><span>"</span><span> ];</span><span>then</span></div></div><div><div><div>77</div></div><div><span>        </span><span>echo</span><span> </span><span>"</span><span>$MODULE</span><span>---</span><span>$MODULE_NAME</span><span>:准备结束,PID=</span><span>$PID</span><span>"</span></div></div><div><div><div>78</div></div><div><span>        </span><span>kill</span><span> </span><span>-9</span><span> </span><span>$PID</span></div></div><div><div><div>79</div></div><div><span>        </span><span>PID</span><span>=</span><span>`</span><span>ps</span><span> </span><span>-ef</span><span> </span><span>|</span><span>grep</span><span> $(</span><span>echo</span><span> </span><span>$JAR_NAME</span><span> </span><span>|</span><span> </span><span>awk</span><span> </span><span>-F/</span><span> '{print $NF}') </span><span>|</span><span> </span><span>grep</span><span> </span><span>-v</span><span> grep </span><span>|</span><span> </span><span>awk</span><span> '{print $2}'`</span></div></div><div><div><div>80</div></div><div><span>        </span><span>while</span><span> </span><span>[</span><span> </span><span>-n</span><span> </span><span>"</span><span>$PID</span><span>"</span><span> ]</span></div></div><div><div><div>81</div></div><div><span>        </span><span>do</span></div></div><div><div><div>82</div></div><div><span>          </span><span>sleep</span><span> </span><span>3s</span></div></div><div><div><div>83</div></div><div><span>          </span><span>PID</span><span>=</span><span>`</span><span>ps</span><span> </span><span>-ef</span><span> </span><span>|</span><span>grep</span><span> $(</span><span>echo</span><span> </span><span>$JAR_NAME</span><span> </span><span>|</span><span> </span><span>awk</span><span> </span><span>-F/</span><span> '{print $NF}') </span><span>|</span><span> </span><span>grep</span><span> </span><span>-v</span><span> grep </span><span>|</span><span> </span><span>awk</span><span> '{print $2}'`</span></div></div><div><div><div>84</div></div><div><span>        </span><span>done</span></div></div><div><div><div>85</div></div><div><span>        </span><span>echo</span><span> </span><span>"</span><span>$MODULE</span><span>---</span><span>$MODULE_NAME</span><span>:成功结束"</span></div></div><div><div><div>86</div></div><div><span>        </span><span>okCount</span><span><span>=</span><span>$((</span></span><span>$okCount</span><span>+1))</span></div></div><div><div><div>87</div></div><div><span>      </span><span>else</span></div></div><div><div><div>88</div></div><div><span>        </span><span>echo</span><span> </span><span>"</span><span>$MODULE</span><span>---</span><span>$MODULE_NAME</span><span>:未运行"</span></div></div><div><div><div>89</div></div><div><span>      </span><span>fi</span></div></div><div><div><div>90</div></div><div><span>    </span><span>fi</span></div></div><div><div><div>91</div></div><div><span>  </span><span>done</span></div></div><div><div><div>92</div></div><div><span>  </span><span>if</span><span> ((</span><span>$commandOk</span><span><span> </span><span>==</span><span> </span></span><span>0</span><span>));</span><span>then</span></div></div><div><div><div>93</div></div><div><span>    </span><span>echo</span><span> </span><span>"第二个参数请输入:all|gateway|auth|system|job|gen|file|risk|supervise|ssologin"</span></div></div><div><div><div>94</div></div><div><span>  </span><span>else</span></div></div><div><div><div>95</div></div><div><span>    </span><span>echo</span><span> </span><span>"............本次共停止:</span><span>$okCount个服务</span><span>............"</span></div></div><div><div><div>96</div></div><div><span>  </span><span>fi</span></div></div><div><div><div>97</div></div><div><span>}</span></div></div><div><div><div>98</div></div><div><span>status</span><span>() {</span></div></div><div><div><div>99</div></div><div><span>  </span><span>local</span><span> </span><span>MODULE</span><span>=</span></div></div><div><div><div>100</div></div><div><span>  </span><span>local</span><span> </span><span>MODULE_NAME</span><span>=</span></div></div><div><div><div>101</div></div><div><span>  </span><span>local</span><span> </span><span>JAR_NAME</span><span>=</span></div></div><div><div><div>102</div></div><div><span>  </span><span>local</span><span> </span><span>command</span><span>=</span><span>"</span><span>$1</span><span>"</span></div></div><div><div><div>103</div></div><div><span>  </span><span>local</span><span> </span><span>commandOk</span><span>=</span><span>0</span></div></div><div><div><div>104</div></div><div><span>  </span><span>local</span><span> </span><span>count</span><span>=</span><span>0</span></div></div><div><div><div>105</div></div><div><span>  </span><span>local</span><span> </span><span>okCount</span><span>=</span><span>0</span></div></div><div><div><div>106</div></div><div><span>  </span><span>local</span><span> </span><span>port</span><span>=</span><span>0</span></div></div><div><div><div>107</div></div><div><span>  </span><span>for</span><span>((</span><span>i</span><span>=</span><span>0</span><span>;</span><span>i</span><span>&lt;</span><span>${</span><span>#</span><span>MODULES</span><span>[@]</span><span>}</span><span>;</span><span>i</span><span><span>++</span><span>))</span></span></div></div><div><div><div>108</div></div><div><span>  </span><span>do</span></div></div><div><div><div>109</div></div><div><span>    </span><span>MODULE</span><span>=</span><span><span>${</span><span>MODULES</span></span><span>[</span><span>$i</span><span>]</span><span>}</span></div></div><div><div><div>110</div></div><div><span>    </span><span>MODULE_NAME</span><span>=</span><span><span>${</span><span>MODULE_NAMES</span></span><span>[</span><span>$i</span><span>]</span><span>}</span></div></div><div><div><div>111</div></div><div><span>    </span><span>JAR_NAME</span><span>=</span><span><span>${</span><span>JARS</span></span><span>[</span><span>$i</span><span>]</span><span>}</span></div></div><div><div><div>112</div></div><div><span>    </span><span>PORT</span><span>=</span><span><span>${</span><span>PORTS</span></span><span>[</span><span>$i</span><span>]</span><span>}</span></div></div><div><div><div>113</div></div><div><span>    </span><span>if</span><span> [ </span><span>"</span><span>$command</span><span>"</span><span><span> </span><span>==</span><span> </span></span><span>"all"</span><span> ] || [ </span><span>"</span><span>$command</span><span>"</span><span><span> </span><span>==</span><span> </span></span><span>"</span><span>$MODULE</span><span>"</span><span> ];</span><span>then</span></div></div><div><div><div>114</div></div><div><span>      </span><span>commandOk</span><span>=</span><span>1</span></div></div><div><div><div>115</div></div><div><span>      </span><span>count</span><span><span>=</span><span>$((</span></span><span>$i</span><span>+1))</span></div></div><div><div><div>116</div></div><div><span>      </span><span>PID</span><span>=</span><span>`</span><span>ps</span><span> </span><span>-ef</span><span> </span><span>|</span><span>grep</span><span> $(</span><span>echo</span><span> </span><span>$JAR_NAME</span><span> </span><span>|</span><span> </span><span>awk</span><span> </span><span>-F/</span><span> '{print $NF}') </span><span>|</span><span> </span><span>grep</span><span> </span><span>-v</span><span> grep </span><span>|</span><span> </span><span>awk</span><span> '{print $2}'`</span></div></div><div><div><div>117</div></div><div><span>      </span><span>if</span><span><span> [ </span><span>-n</span><span> </span></span><span>"</span><span>$PID</span><span>"</span><span> ];</span><span>then</span></div></div><div><div><div>118</div></div><div><span>        </span><span>echo</span><span> </span><span>"</span><span>$MODULE</span><span>---</span><span>$MODULE_NAME</span><span>:已经运行,PID=</span><span>$PID</span><span>"</span></div></div><div><div><div>119</div></div><div><span>        </span><span>okCount</span><span><span>=</span><span>$((</span></span><span>$okCount</span><span>+1))</span></div></div><div><div><div>120</div></div><div><span>      </span><span>else</span></div></div><div><div><div>121</div></div><div><span>        </span><span>echo</span><span> </span><span>"</span><span>$MODULE</span><span>---</span><span>$MODULE_NAME</span><span>:未运行"</span></div></div><div><div><div>122</div></div><div><span>      </span><span>fi</span></div></div><div><div><div>123</div></div><div><span>    </span><span>fi</span></div></div><div><div><div>124</div></div><div><span>  </span><span>done</span></div></div><div><div><div>125</div></div><div><span><span>  </span></span><span>if((</span><span>$commandOk</span><span><span> </span><span>==</span><span> </span></span><span>0</span><span>));</span><span>then</span></div></div><div><div><div>126</div></div><div><span>    </span><span>echo</span><span> </span><span>"第二个参数请输入:all|gateway|auth|system|job|gen|file|risk|supervise|ssologin"</span></div></div><div><div><div>127</div></div><div><span>  </span><span>else</span></div></div><div><div><div>128</div></div><div><span>    </span><span>echo</span><span> </span><span>"............共:</span><span>$count</span><span> 个服务,运行中</span><span>$okCount个服务</span><span>..........."</span></div></div><div><div><div>129</div></div><div><span>  </span><span>fi</span></div></div><div><div><div>130</div></div><div><span>}</span></div></div><div><div><div>131</div></div><div>
</div></div><div><div><div>132</div></div><div><span>case</span><span> </span><span>"</span><span>$1</span><span>"</span><span> </span><span>in</span></div></div><div><div><div>133</div></div><div><span>  </span><span>start</span><span>)</span></div></div><div><div><div>134</div></div><div><span>    </span><span>start</span><span> </span><span>"</span><span>$2</span><span>"</span></div></div><div><div><div>135</div></div><div><span><span>  </span></span><span>;;</span></div></div><div><div><div>136</div></div><div><span>  </span><span>stop</span><span>)</span></div></div><div><div><div>137</div></div><div><span>    </span><span>stop</span><span> </span><span>"</span><span>$2</span><span>"</span></div></div><div><div><div>138</div></div><div><span><span>  </span></span><span>;;</span></div></div><div><div><div>139</div></div><div><span>  </span><span>status</span><span>)</span></div></div><div><div><div>140</div></div><div><span>    </span><span>status</span><span> </span><span>"</span><span>$2</span><span>"</span></div></div><div><div><div>141</div></div><div><span><span>  </span></span><span>;;</span></div></div><div><div><div>142</div></div><div><span>  </span><span>restart</span><span>)</span></div></div><div><div><div>143</div></div><div><span>    </span><span>stop</span><span> </span><span>"</span><span>$2</span><span>"</span></div></div><div><div><div>144</div></div><div><span>    </span><span>sleep</span><span> </span><span>3s</span></div></div><div><div><div>145</div></div><div><span>    </span><span>start</span><span> </span><span>"</span><span>$2</span><span>"</span></div></div><div><div><div>146</div></div><div><span><span>  </span></span><span>;;</span></div></div><div><div><div>147</div></div><div><span><span>  </span></span><span>*)</span></div></div><div><div><div>148</div></div><div><span>    </span><span>echo</span><span> </span><span>"第一个参数请输入:start|stop|restart|status"</span></div></div><div><div><div>149</div></div><div><span>    </span><span>exit</span><span> </span><span>1</span></div></div><div><div><div>150</div></div><div><span><span>  </span></span><span>;;</span></div></div><div><div><div>151</div></div><div><span>esac</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><blockquote><p>启动：</p></blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>## 启动所有</span></div></div><div><div><div>2</div></div><div><span>./start.sh</span><span> </span><span>start</span><span> </span><span>all</span></div></div><div><div><div>3</div></div><div><span>## 停止所有</span></div></div><div><div><div>4</div></div><div><span>./start.sh</span><span> </span><span>stop</span><span> </span><span>all</span></div></div><div><div><div>5</div></div><div><span>## 重启所有</span></div></div><div><div><div>6</div></div><div><span>./start.sh</span><span> </span><span>restart</span><span> </span><span>all</span></div></div><div><div><div>7</div></div><div><span>## 启动某一个 这里的gateway与sh中的module中定义的一样即可</span></div></div><div><div><div>8</div></div><div><span>./start.sh</span><span> </span><span>restart</span><span> </span><span>gateway</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>问题1：<code>-bash: ./start.sh: Permission denied\</code>
<strong>原因:</strong> 无权限
<strong>解决方法：</strong>
<code>chmod +x ./文件名.sh</code></p></blockquote><blockquote><p>问题2：<code>bad interpreter\:No such file or directory</code>的错误</p></blockquote><blockquote><p><strong>原因：</strong>
.sh脚本在windows系统下编写的，所以可能有不可见字符，从上图错误提示来看，很有可能脚本文件是DOS格式的，即每一行的行尾以\r\n来标识, 其ASCII码分别是0x0D, 0x0A。
<strong>解决方法：</strong></p><ul>
<li>通过<code>vim filename</code> 或者<code>vi filename</code> 进入编辑，即我这是<code>vim startup\_heartbeat.sh</code></li>
<li>然后通过<code>shift+：</code>进入命令模式。接着通过命令<code>set ff</code> 或者 <code>set fileformat</code> 查看文件格式，即我这如下图：从中可以看到我这文件格式是dos</li>
<li>修改文件格式dos为unix。通过命令<code>set ff=unix</code> 或 <code>set fileformat=unix</code>修改，然后再执行<code>set ff</code> 或者 <code>set fileformat</code>，查看是否修改成功。即如下图所示</li>
<li>启动命令，发现正常启动，至此完毕。</li>
</ul></blockquote></section>
<section><h2> 服务开机自启<a href="#-服务开机自启"><span>#</span></a></h2><p>一、新建jar包启动sh文件
新建<code>startup.sh</code>脚本文件，启动项目jar包</p><p><code>nohup java -jar test.jar &gt;/dev/null 2&gt;&amp;1 &amp;</code></p><p>二、设置自动启动命令
1.进入rc.d目录
执行<code>cd /etc/rc.d</code> 命令，进入rc.d目录</p><p>如图所示（示例）：</p><p>2.修改<code>rc.local</code>文件内容
执行命令 <code>vi rc.local</code>，然后按下键盘上的【i】键进入修改模式</p><p>在末尾加上如下命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>#进入项目目录</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>/home/test`</span></div></div><div><div><div>3</div></div><div><span>#执行sh文件</span></div></div><div><div><div>4</div></div><div><span>sh</span><span> /home/test/startup.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后先按下【esc】键，再按下【:】键，在光标闪烁处输入<code>:wq</code>。按回车，完成修改后，执行相应命令，设置执行权限，重启服务器，验证即可。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>chmod</span><span> </span><span>+x</span><span> </span><span>/etc/rc.d/rc.local</span></div></div><div><div><div>2</div></div><div><span>chmod</span><span> </span><span>+x</span><span> </span><span>/home/test/startup.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>有时服务器重启服务很多时，可能需要延迟启动，可以在之前的命令前加上sleep 60命令延迟启动</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sleep</span><span> </span><span>60</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>/home/test</span></div></div><div><div><div>3</div></div><div><span>sh</span><span> </span><span>/home/test/startup.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2> 服务方式启动<a href="#-服务方式启动"><span>#</span></a></h2><blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>可以添加一个</span><span> </span><span>systemd的服务</span><span>  </span><span>基本上可以如图进行设置</span></div></div><div><div><div>2</div></div><div><span>一般位于</span><span> </span><span>/etc/systemd/system/</span><span> </span><span>下面</span></div></div><div><div><div>3</div></div><div><span>比如可以建立一个文件为</span><span> </span><span>app.service</span></div></div><div><div><div>4</div></div><div><span>可以使用</span><span> </span><span>systemctl</span><span>  </span><span>enable</span><span> </span><span>app</span><span> </span><span>设置开机自动启动</span></div></div><div><div><div>5</div></div><div><span>然后使用systemctl</span><span> </span><span>start</span><span> </span><span>app</span><span> </span><span>来启动服务</span></div></div></code></pre><div><div></div><div></div></div></figure></div></blockquote><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[Unit]</span></div></div><div><div><div>2</div></div><div><span>Description</span><span> </span><span>=</span><span> </span><span>Redis</span><span> </span><span>Server</span></div></div><div><div><div>3</div></div><div><span>After</span><span> </span><span>=</span><span> </span><span>network.target</span></div></div><div><div><div>4</div></div><div><span>[Service]</span></div></div><div><div><div>5</div></div><div><span>ExecStart</span><span>=</span><span>/app/startup.sh</span></div></div><div><div><div>6</div></div><div><span>ExecStop</span><span>=</span><span>/usr/bin/kill</span><span> </span><span>-15</span><span> </span><span>$MAINPID</span></div></div><div><div><div>7</div></div><div><span>Restart</span><span> </span><span>=</span><span> </span><span>always</span></div></div><div><div><div>8</div></div><div><span>[Install]</span></div></div><div><div><div>9</div></div><div><span>WantedBy</span><span> </span><span>=</span><span> </span><span>multi-user.target</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/ec0b08ff/</id>
      <title type="text">Hexo主题安装</title>
      <published>2024-05-18T20:31:13.000Z</published>
      <updated>2024-05-18T20:31:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/ec0b08ff/"/>
      <summary type="text">如何在Hexo博客框架中安装和配置多个热门主题，包括Butterfly、yun、Fluid和shoka。以shoka主题为例，详细说明了下载、配置主题的步骤，以及安装必要插件的具体操作。最后，提供了检查主题是否工作正常的步骤，确保读者能够顺利使用这些主题。</summary>
      <content type="html"><![CDATA[<section><h2>一、Butterfly<a href="#一butterfly"><span>#</span></a></h2><p><a href="https://cdn.jsdelivr.net/gh/lixiaomuicon/photo_bed@main/blog/202306102320371.png" target="_blank"></a></p><figure><a href="https://cdn.jsdelivr.net/gh/lixiaomuicon/photo_bed@main/blog/202306102320371.png" target="_blank"><img src="https://cdn.jsdelivr.net/gh/lixiaomuicon/photo_bed@main/blog/202306102320371.png" alt="Butterfly" /><figcaption>Butterfly</figcaption></a></figure><p></p><ul>
<li>在线演示：<a href="https://crazywong.com/" target="_blank">CrazyWong</a></li>
<li>魔改标杆：
<ul>
<li><a href="https://akilar.top/" target="_blank">Akilarの糖果屋 - Akilar.top</a></li>
<li><a href="https://blog.zhheo.com/" target="_blank">张洪Heo - 分享设计与科技生活 (zhheo.com)</a></li>
<li><a href="https://sunguoqi.com/" target="_blank">小孙同学 (sunguoqi.com)</a></li>
</ul>
</li>
<li>魔改教程：<a href="https://butterfly.zhheo.com/docs/" target="_blank">人人都可以去自定义 | Butterfly主题美化教程 (zhheo.com)</a></li>
<li>主题仓库：<a href="https://github.com/jerryc127/hexo-theme-butterfly" target="_blank">https://github.com/jerryc127/hexo-theme-butterfly</a></li>
<li>使用文档：<a href="https://butterfly.js.org/" target="_blank">Butterfly - A Simple and Card UI Design theme for Hexo</a></li>
<li>推荐值：⭐⭐⭐⭐⭐</li>
</ul></section>
<section><h2>二、yun<a href="#二yun"><span>#</span></a></h2><p><a href="https://cdn.jsdelivr.net/gh/lixiaomuicon/photo_bed@main/blog/202306102311804.png" target="_blank"></a></p><figure><a href="https://cdn.jsdelivr.net/gh/lixiaomuicon/photo_bed@main/blog/202306102311804.png" target="_blank"><img src="https://cdn.jsdelivr.net/gh/lixiaomuicon/photo_bed@main/blog/202306102311804.png" alt="yun" /><figcaption>yun</figcaption></a></figure><p></p><ul>
<li>在线演示：<a href="https://www.yunyoujun.cn/" target="_blank">云游君的小站 (yunyoujun.cn)</a></li>
<li>主题仓库：<a href="https://github.com/YunYouJun/valaxy/tree/main/packages/valaxy-theme-yun" target="_blank">valaxy/packages/valaxy-theme-yun at main · YunYouJun/valaxy · GitHub</a></li>
<li>使用文档：<a href="https://github.com/YunYouJun/valaxy/tree/main/packages/valaxy-theme-yun/docs/zh-CN" target="_blank">valaxy/packages/valaxy-theme-yun/docs/zh-CN at main · YunYouJun/valaxy · GitHub</a></li>
<li>推荐值：⭐⭐⭐⭐</li>
</ul></section>
<section><h2>三、Fluid<a href="#三fluid"><span>#</span></a></h2><p></p><figure><img src="https://pic3.zhimg.com/80/v2-4e688c1cd9975a236588a0aa56221102_720w.webp" alt="img" /><figcaption>img</figcaption></figure><p></p><ul>
<li>Github 地址：<a href="https://link.zhihu.com/?target=https%3A//github.com/fluid-dev/hexo-theme-fluid" target="_blank">https://github.com/fluid-dev/hexo-theme-fluid</a></li>
<li>在线演示：<strong><a href="https://link.zhihu.com/?target=https%3A//hexo.fluid-dev.com/" target="_blank">https://hexo.fluid-dev.com/</a></strong></li>
</ul><ul>
<li>推荐值：⭐⭐⭐⭐</li>
</ul></section>
<section><h2>四、shoka<a href="#四shoka"><span>#</span></a></h2><ul>
<li>Github 地址：<a href="https://github.com/amehime/hexo-theme-shoka.git" target="_blank">https://github.com/amehime/hexo-theme-shoka.git</a></li>
<li>在线演示：<strong>本站使用这个主题</strong></li>
</ul><ul>
<li>推荐值：⭐⭐⭐⭐⭐</li>
</ul></section>
<section><h2>五、示例<a href="#五示例"><span>#</span></a></h2><blockquote><p>以 <code>shoka</code> 主题为例，其他主题不保证可以适用。</p></blockquote><section><h3>下载主题以及配置主题<a href="#下载主题以及配置主题"><span>#</span></a></h3><ol>
<li>下载主题以及配置主题</li>
</ol><p>在博客文件夹根目录下使用下述命令进行安装</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>#cd your-blog</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/amehime/hexo-theme-shoka.git</span><span> </span><span>./themes/shoka</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>需要知道的几点：</p><ul>
<li>shoka 拉取下来后里面有一个 example 目录，这个目录里面都是例子代码，并不会配置了对项目生效的 😪</li>
<li>其中 example 下的 package.json 是 hexo 目录中的 package.json 的参考文件，_config.yml 是 hexo 目录中的 _config.yml 参考文件， _config.shoka.yml 是 shok 中的 _config.yml 参考文件。注意不要混淆！</li>
<li>建议将 shoka 中的 example 中的配置文件与 hexo 的配置文件内容放到 hexo 的配置文件中，避免重复的设置项 不然会报错的</li>
</ul></blockquote><ol>
<li>
<p>下载完成后，文件会在 博客路径下的<code>theme </code>下 比如这里，我的博客根路径为 <code>D:\Doc\example\ </code>，那么 shoka 的主题文件就在 <code>D:\Doc\example\theme\shoka\</code> 下</p>
</li>
<li>
<p>编辑博客根目录下的 <code>_config.yml</code> , 搜索 <code>theme</code> ，修改为：</p>
</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>theme</span><span>: </span><span>shoka</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>删除 <code>_config.landscape.yml </code>，这是 hexo 默认主题的配置文件，建议删除</li>
</ol></section><section><h3>安装 shoka 主题所需的必要插件<a href="#安装-shoka-主题所需的必要插件"><span>#</span></a></h3>

<table><thead><tr><th><strong>插件名称</strong></th><th>npm地址</th><th>功能</th><th>依赖程度</th></tr></thead><tbody><tr><td>hexo-renderer-multi-markdown-it</td><td><a href="https://www.npmjs.com/package/hexo-renderer-multi-markdown-it" target="_blank">https://www.npmjs.com/package/hexo-renderer-multi-markdown-it</a></td><td>md 文件渲染器，压缩 css/js/html</td><td>必需</td></tr><tr><td>hexo-autoprefixer</td><td><a href="https://www.npmjs.com/package/hexo-autoprefixer" target="_blank">https://www.npmjs.com/package/hexo-autoprefixer</a></td><td>给生成的 css 文件们添加浏览器前缀</td><td>必需</td></tr><tr><td>hexo-algoliasearch</td><td><a href="https://www.npmjs.com/package/hexo-algoliasearch" target="_blank">https://www.npmjs.com/package/hexo-algoliasearch</a></td><td>站内搜索功能</td><td>搜索按钮失灵</td></tr><tr><td>hexo-symbols-count-time</td><td><a href="https://www.npmjs.com/package/hexo-symbols-count-time" target="_blank">https://www.npmjs.com/package/hexo-symbols-count-time</a></td><td>文章或站点字数及阅读时间统计</td><td>统计没有</td></tr><tr><td>hexo-feed</td><td><a href="https://www.npmjs.com/package/hexo-feed" target="_blank">https://www.npmjs.com/package/hexo-feed</a></td><td>生成 Feed 文件</td><td>Feed 文件没有</td></tr></tbody></table><section><h4>安装 hexo-renderer-multi-markdown-it<a href="#安装-hexo-renderer-multi-markdown-it"><span>#</span></a></h4><ol>
<li>卸载掉默认的 hexo-renderer-marked ，以及别的 markdown 文件渲染器。</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>un</span><span> </span><span>hexo-renderer-marked</span><span> </span><span>--save</span></div></div><div><div><div>2</div></div><div><span># 或者</span></div></div><div><div><div>3</div></div><div><span>yarn</span><span> </span><span>remove</span><span> </span><span>hexo-renderer-marked</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>在博客根目录下用如下命令进行插件安装</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>i</span><span> </span><span>hexo-renderer-multi-markdown-it</span><span> </span><span>--save</span></div></div><div><div><div>2</div></div><div><span># 或者</span></div></div><div><div><div>3</div></div><div><span>yarn</span><span> </span><span>add</span><span> </span><span>hexo-renderer-multi-markdown-it</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>编辑 <code>_config.yml</code> , 配置插件参数，在合适位置添加</li>
</ol><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>markdown</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>render</span><span>: </span><span># 渲染器设置</span></div></div><div><div><div>3</div></div><div><span>    </span><span>html</span><span>: </span><span>false</span><span> </span><span># 过滤 HTML 标签</span></div></div><div><div><div>4</div></div><div><span>    </span><span>xhtmlOut</span><span>: </span><span>true</span><span> </span><span># 使用 '/' 来闭合单标签 （比如 &lt;br /&gt;）。</span></div></div><div><div><div>5</div></div><div><span>    </span><span>breaks</span><span>: </span><span>true</span><span> </span><span># 转换段落里的 '\n' 到 &lt;br&gt;。</span></div></div><div><div><div>6</div></div><div><span>    </span><span>linkify</span><span>: </span><span>true</span><span> </span><span># 将类似 URL 的文本自动转换为链接。</span></div></div><div><div><div>7</div></div><div><span>    </span><span>typographer</span><span>:</span></div></div><div><div><div>8</div></div><div><span>    </span><span>quotes</span><span>: </span><span>'“”‘’'</span></div></div><div><div><div>9</div></div><div><span>  </span><span>plugins</span><span>: </span><span># markdown-it 插件设置</span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>- </span><span>plugin</span><span>:</span></div></div><div><div><div>11</div></div><div><span>        </span><span>name</span><span>: </span><span>markdown-it-toc-and-anchor</span></div></div><div><div><div>12</div></div><div><span>        </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>13</div></div><div><span>        </span><span>options</span><span>: </span><span># 文章目录以及锚点应用的 class 名称，shoka 主题必须设置成这样</span></div></div><div><div><div>14</div></div><div><span>          </span><span>tocClassName</span><span>: </span><span>'toc'</span></div></div><div><div><div>15</div></div><div><span>          </span><span>anchorClassName</span><span>: </span><span>'anchor'</span></div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>- </span><span>plugin</span><span>:</span></div></div><div><div><div>17</div></div><div><span>        </span><span>name</span><span>: </span><span>markdown-it-multimd-table</span></div></div><div><div><div>18</div></div><div><span>        </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>19</div></div><div><span>        </span><span>options</span><span>:</span></div></div><div><div><div>20</div></div><div><span>          </span><span>multiline</span><span>: </span><span>true</span></div></div><div><div><div>21</div></div><div><span>          </span><span>rowspan</span><span>: </span><span>true</span></div></div><div><div><div>22</div></div><div><span>          </span><span>headerless</span><span>: </span><span>true</span></div></div><div><div><div>23</div></div><div><span><span>    </span></span><span>- </span><span>plugin</span><span>:</span></div></div><div><div><div>24</div></div><div><span>        </span><span>name</span><span>: </span><span>./markdown-it-furigana</span></div></div><div><div><div>25</div></div><div><span>        </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>26</div></div><div><span>        </span><span>options</span><span>:</span></div></div><div><div><div>27</div></div><div><span>          </span><span>fallbackParens</span><span>: </span><span>"()"</span></div></div><div><div><div>28</div></div><div><span><span>    </span></span><span>- </span><span>plugin</span><span>:</span></div></div><div><div><div>29</div></div><div><span>        </span><span>name</span><span>: </span><span>./markdown-it-spoiler</span></div></div><div><div><div>30</div></div><div><span>        </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>31</div></div><div><span>        </span><span>options</span><span>:</span></div></div><div><div><div>32</div></div><div><span>          </span><span>title</span><span>: </span><span>"你知道得太多了"</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><ol>
<li>继续编辑 <code>_config.yml</code> , 找到如下字段</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>highlight</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span># 将 enable: true 改成 enable: false</span></div></div><div><div><div>3</div></div><div><span>  </span><span>enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>  </span><span>line_number</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>  </span><span>auto_detect</span><span>: </span><span>false</span></div></div><div><div><div>6</div></div><div><span>  </span><span>tab_replace</span><span>: </span><span>''</span></div></div><div><div><div>7</div></div><div><span>  </span><span>wrap</span><span>: </span><span>true</span></div></div><div><div><div>8</div></div><div><span>  </span><span>hljs</span><span>: </span><span>false</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>
<p>如果直接下载上面的插件可能导致 页面的 代码块 显示有问题 这是 版本问题所导致的解决问题如下：修改 <code>package.json</code> 文件</p>
</li>
<li>
<p>修改 hexo 的 package.json 的文件内容，将 shoka 的 example 目录中的 package.json 文件的内容拷贝到 hexo 的 package.json 中即可</p>
</li>
<li>
<p>修改完 package.json 文件内容后执行下面的命令降级 hexo</p>
<ul>
<li>
<p>重新全局安装 hexo 5.4.2</p>
</li>
<li>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>npm install -g hexo@5.4.2</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>然后在 hexo 目录下更新依赖</p>
</li>
<li>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>npm install</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>然后重新生成就可以解决问题了</p>
</li>
<li>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>hexo clean &amp;&amp; hexo g &amp;&amp; hexo s</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul>
</li>
</ol><p>​	注意：浏览器可能有缓存，记得刷新缓存</p></section><section><h4>hexo-autoprefixer<a href="#hexo-autoprefixer"><span>#</span></a></h4><ol>
<li>同上，通过命令安装</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>install</span><span> </span><span>hexo-autoprefixer</span><span> </span><span>--save</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>编辑 <code>_config.yml</code> ，合适位置加入</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>autoprefixer</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>exclude</span><span>:</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>- </span><span>'*.min.css'</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h3>检查主题是否工作正常<a href="#检查主题是否工作正常"><span>#</span></a></h3><ol>
<li>
<p>使用 <code>hexo clean</code> , <code>hexo g</code> , <code>hexo s</code> 三连</p>
</li>
<li>
<p>浏览器输入 <code>localhost:4000</code> ，点开默认的博文 <code>hello world</code> ，查看网页是否渲染正常（为防止网页缓存导致显示异常，建议打开无痕窗口进行浏览）</p>
</li>
<li>
<p>如果不正常请挨个检查上述步骤中的配置</p>
</li>
</ol></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/c3c198d3/</id>
      <title type="text">Hexo基本使用</title>
      <published>2024-05-18T20:01:13.000Z</published>
      <updated>2024-05-18T20:01:13.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/c3c198d3/"/>
      <summary type="text">Hexo的基本使用方法，Hexo是一个快速、简洁且高效的博客框架。它使用Markdown（或其他标记语言）解析文章，并在几秒内生成静态网页。文章详细讲解了如何安装和配置Hexo，以及如何使用不同的主题和插件来丰富博客的功能和外观。适合初学者快速上手Hexo，搭建自己的个人博客。</summary>
      <content type="html"><![CDATA[<section><h2>什么是 Hexo？<a href="#什么是-hexo"><span>#</span></a></h2><p>Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 <a href="http://daringfireball.net/projects/markdown/" target="_blank">Markdown</a>（或其他标记语言）解析文章，在几秒内，即可利用靓丽的主题生成静态网页。</p></section>
<section><h2>开始使用<a href="#开始使用"><span>#</span></a></h2><section><h3>安装<a href="#安装"><span>#</span></a></h3><p>安装 Hexo 只需几分钟时间，若您在安装过程中遇到问题或无法找到解决方式，请 <a href="https://github.com/hexojs/hexo/issues" target="_blank">提交问题</a>，我们会尽力解决您的问题。</p><section><h4>安装前提<a href="#安装前提"><span>#</span></a></h4><p>安装 Hexo 相当简单，只需要先安装下列应用程序即可：</p><ul>
<li><a href="http://nodejs.org/" target="_blank">Node.js</a> (Node.js 版本需不低于 10.13，建议使用 Node.js 12.0 及以上版本)</li>
<li><a href="http://git-scm.com/" target="_blank">Git</a></li>
</ul><p>如果您的电脑中已经安装上述必备程序，那么恭喜您！你可以直接前往 <a href="https://hexo.io/zh-cn/docs/#%E5%AE%89%E8%A3%85-Hexo" target="_blank">安装 Hexo</a> 步骤。</p><p>如果您的电脑中尚未安装所需要的程序，请根据以下安装指示完成安装。</p></section><section><h4>安装 Git<a href="#安装-git"><span>#</span></a></h4><ul>
<li>Windows：下载并安装 <a href="https://git-scm.com/download/win" target="_blank">git</a>。</li>
<li>Mac：使用 <a href="http://mxcl.github.com/homebrew/" target="_blank">Homebrew</a>, <a href="http://www.macports.org/" target="_blank">MacPorts</a> 或者下载 <a href="http://sourceforge.net/projects/git-osx-installer/" target="_blank">安装程序</a>。</li>
<li>Linux (Ubuntu, Debian)：<code>sudo apt-get install git-core</code></li>
<li>Linux (Fedora, Red Hat, CentOS)：<code>sudo yum install git-core</code></li>
</ul><blockquote><p>Mac 用户</p><p>如果在编译时可能会遇到问题，请先到 App Store 安装 Xcode，Xcode 完成后，启动并进入 <strong>Preferences -&gt; Download -&gt; Command Line Tools -&gt; Install</strong> 安装命令行工具。</p></blockquote><blockquote><p>Windows 用户</p><p>对于中国大陆地区用户，可以前往 <a href="https://npmmirror.com/mirrors/git-for-windows/" target="_blank">淘宝 Git for Windows 镜像</a> 下载 git 安装包。</p></blockquote></section><section><h4>安装 Node.js<a href="#安装-nodejs"><span>#</span></a></h4><p>Node.js 为大多数平台提供了官方的 <a href="https://nodejs.org/zh-cn/download/" target="_blank">安装程序</a>。对于中国大陆地区用户，可以前往 <a href="https://npmmirror.com/mirrors/node/" target="_blank">淘宝 Node.js 镜像</a> 下载。</p><p>其它的安装方法：</p><ul>
<li>Windows：通过 <a href="https://github.com/jasongin/nvs/" target="_blank">nvs</a>（推荐）或者 <a href="https://github.com/nvm-sh/nvm" target="_blank">nvm</a> 安装。</li>
<li>Mac：使用 <a href="https://brew.sh/" target="_blank">Homebrew</a> 或 <a href="http://www.macports.org/" target="_blank">MacPorts</a> 安装。</li>
<li>Linux（DEB/RPM-based）：从 <a href="https://github.com/nodesource/distributions" target="_blank">NodeSource</a> 安装。</li>
<li>其它：使用相应的软件包管理器进行安装，可以参考由 Node.js 提供的 <a href="https://nodejs.org/en/download/package-manager/" target="_blank">指导</a>。</li>
</ul><p>对于 Mac 和 Linux 同样建议使用 nvs 或者 nvm，以避免可能会出现的权限问题。</p><blockquote><p>Windows 用户</p><p>使用 Node.js 官方安装程序时，请确保勾选 <strong>Add to PATH</strong> 选项（默认已勾选）</p></blockquote><blockquote><p>For Mac / Linux 用户</p><p>如果在尝试安装 Hexo 的过程中出现 <code>EACCES</code> 权限错误，请遵循 <a href="https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally" target="_blank">由 npmjs 发布的指导</a> 修复该问题。强烈建议 <strong>不要</strong> 使用 root、sudo 等方法覆盖权限</p></blockquote><blockquote><p>Linux</p><p>如果您使用 Snap 来安装 Node.js，在 <a href="https://hexo.io/zh-cn/docs/commands#init" target="_blank">初始化</a> 博客时您可能需要手动在目标文件夹中执行 <code>npm install</code>。</p></blockquote></section><section><h4>安装 Hexo<a href="#安装-hexo"><span>#</span></a></h4><p>所有必备的应用程序安装完成后，即可使用 npm 安装 Hexo。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>npm</span><span> </span><span>install</span><span> </span><span>-g</span><span> </span><span>hexo-cli</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>进阶安装和使用<a href="#进阶安装和使用"><span>#</span></a></h4><p>对于熟悉 npm 的进阶用户，可以仅局部安装 <code>hexo</code> 包。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>npm</span><span> </span><span>install</span><span> </span><span>hexo</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>安装以后，可以使用以下两种方式执行 Hexo：</p><ol>
<li><code>npx hexo &lt;command&gt;</code></li>
<li>Linux 用户可以将 Hexo 所在的目录下的 <code>node_modules</code> 添加到环境变量之中即可直接使用 <code>hexo &lt;command&gt;</code>：</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>echo</span><span> </span><span>'PATH="$PATH:./node_modules/.bin"'</span><span> &gt;&gt; </span><span>~/.profile</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>Node.js 版本限制<a href="#nodejs-版本限制"><span>#</span></a></h4><p>如果你坚持使用旧的 Node.js，你可以考虑安装 Hexo 的过去版本。</p><p>请注意，我们不提供对过去版本 Hexo 的错误修复。</p><p>我们强烈建议永远安装 <a href="https://www.npmjs.com/package/hexo?activeTab=versions" target="_blank">最新版本</a> 的 Hexo，以及 <a href="https://hexo.io/zh-cn/docs/#%E5%AE%89%E8%A3%85%E5%89%8D%E6%8F%90" target="_blank">推荐的 Node.js 版本</a>。</p>

<table><thead><tr><th>Hexo 版本</th><th>最低版本 (Node.js 版本)</th><th>最高版本 (Node.js 版本)</th></tr></thead><tbody><tr><td>7.0+</td><td>14.0.0</td><td>latest</td></tr><tr><td>6.2+</td><td>12.13.0</td><td>latest</td></tr><tr><td>6.0+</td><td>12.13.0</td><td>18.5.0</td></tr><tr><td>5.0+</td><td>10.13.0</td><td>12.0.0</td></tr><tr><td>4.1 - 4.2</td><td>8.10</td><td>10.0.0</td></tr><tr><td>4.0</td><td>8.6</td><td>8.10.0</td></tr><tr><td>3.3 - 3.9</td><td>6.9</td><td>8.0.0</td></tr><tr><td>3.2 - 3.3</td><td>0.12</td><td>未知</td></tr><tr><td>3.0 - 3.1</td><td>0.10 或 iojs</td><td>未知</td></tr><tr><td>0.0.1 - 2.8</td><td>0.10</td><td>未知</td></tr></tbody></table></section></section><section><h3>建站<a href="#建站"><span>#</span></a></h3><p>安装 Hexo 完成后，请执行下列命令，Hexo 将会在指定文件夹中新建所需要的文件。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>init</span><span> </span><span>&lt;folder&gt;</span></div></div><div><div><div>2</div></div><div><span>$</span><span> </span><span>cd</span><span> </span><span>&lt;folder&gt;</span></div></div><div><div><div>3</div></div><div><span>$</span><span> </span><span>npm</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>新建完成后，指定文件夹的目录如下：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>.</span></div></div><div><div><div>2</div></div><div><span>├── _config.yml</span></div></div><div><div><div>3</div></div><div><span>├── package.json</span></div></div><div><div><div>4</div></div><div><span>├── scaffolds</span></div></div><div><div><div>5</div></div><div><span>├── source</span></div></div><div><div><div>6</div></div><div><span>|   ├── _drafts</span></div></div><div><div><div>7</div></div><div><span>|   └── _posts</span></div></div><div><div><div>8</div></div><div><span>└── themes</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h4>_config.yml<a href="#_configyml"><span>#</span></a></h4><p>网站的 <a href="https://hexo.io/zh-cn/docs/configuration" target="_blank">配置</a> 信息，您可以在此配置大部分的参数。</p></section><section><h4>package.json<a href="#packagejson"><span>#</span></a></h4><p>应用程序的信息。<a href="https://ejs.co/" target="_blank">EJS</a>, <a href="http://learnboost.github.io/stylus/" target="_blank">Stylus</a> 和 <a href="http://daringfireball.net/projects/markdown/" target="_blank">Markdown</a> 渲染引擎 已默认安装，您可以自由移除。</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"name"</span><span>: </span><span>"hexo-site"</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>"version"</span><span>: </span><span>"0.0.0"</span><span>,</span></div></div><div><div><div>4</div></div><div><span>  </span><span>"private"</span><span>: </span><span>true</span><span>,</span></div></div><div><div><div>5</div></div><div><span>  </span><span>"hexo"</span><span>: {</span></div></div><div><div><div>6</div></div><div><span>    </span><span>"version"</span><span>: </span><span>""</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>8</div></div><div><span>  </span><span>"dependencies"</span><span>: {</span></div></div><div><div><div>9</div></div><div><span>    </span><span>"hexo"</span><span>: </span><span>"^7.0.0"</span><span>,</span></div></div><div><div><div>10</div></div><div><span>    </span><span>"hexo-generator-archive"</span><span>: </span><span>"^2.0.0"</span><span>,</span></div></div><div><div><div>11</div></div><div><span>    </span><span>"hexo-generator-category"</span><span>: </span><span>"^2.0.0"</span><span>,</span></div></div><div><div><div>12</div></div><div><span>    </span><span>"hexo-generator-index"</span><span>: </span><span>"^3.0.0"</span><span>,</span></div></div><div><div><div>13</div></div><div><span>    </span><span>"hexo-generator-tag"</span><span>: </span><span>"^2.0.0"</span><span>,</span></div></div><div><div><div>14</div></div><div><span>    </span><span>"hexo-renderer-ejs"</span><span>: </span><span>"^2.0.0"</span><span>,</span></div></div><div><div><div>15</div></div><div><span>    </span><span>"hexo-renderer-stylus"</span><span>: </span><span>"^3.0.0"</span><span>,</span></div></div><div><div><div>16</div></div><div><span>    </span><span>"hexo-renderer-marked"</span><span>: </span><span>"^6.0.0"</span><span>,</span></div></div><div><div><div>17</div></div><div><span>    </span><span>"hexo-server"</span><span>: </span><span>"^3.0.0"</span><span>,</span></div></div><div><div><div>18</div></div><div><span>    </span><span>"hexo-theme-landscape"</span><span>: </span><span>"^1.0.0"</span></div></div><div><div><div>19</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>20</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>scaffolds<a href="#scaffolds"><span>#</span></a></h4><p><a href="https://hexo.io/zh-cn/docs/writing#%E6%A8%A1%E7%89%88%EF%BC%88Scaffold%EF%BC%89" target="_blank">模版</a> 文件夹。当您新建文章时，Hexo 会根据 scaffold 来创建文件。</p><p>Hexo 的模板是指在新建的文章文件中默认填充的内容。例如，如果您修改 <code>scaffold/post.md</code> 中的 Front-matter 内容，那么每次新建一篇文章时都会包含这个修改。</p></section><section><h4>source<a href="#source"><span>#</span></a></h4><p>资源文件夹是存放用户资源的地方。除 <code>_posts</code> 文件夹之外，开头命名为 <code>_</code> (下划线)的文件 / 文件夹和隐藏的文件将会被忽略。Markdown 和 HTML 文件会被解析并放到 <code>public</code> 文件夹，而其他文件会被拷贝过去。</p></section><section><h4>themes<a href="#themes"><span>#</span></a></h4><p><a href="https://hexo.io/zh-cn/docs/themes" target="_blank">主题</a> 文件夹。Hexo 会根据主题来生成静态页面。</p></section></section><section><h3>配置<a href="#配置"><span>#</span></a></h3><p>您可以在 <code>_config.yml</code> 或 <a href="https://hexo.io/zh-cn/docs/configuration#%E4%BD%BF%E7%94%A8%E4%BB%A3%E6%9B%BF%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6" target="_blank">代替配置文件</a> 中修改大部分的配置。</p><section><h4>网站<a href="#网站"><span>#</span></a></h4>

<table><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td><code>title</code></td><td>网站标题</td></tr><tr><td><code>subtitle</code></td><td>网站副标题</td></tr><tr><td><code>description</code></td><td>网站描述</td></tr><tr><td><code>keywords</code></td><td>网站的关键词。支持多个关键词。</td></tr><tr><td><code>author</code></td><td>您的名字</td></tr><tr><td><code>language</code></td><td>网站使用的语言。对于简体中文用户来说，使用不同的主题可能需要设置成不同的值，请参考你的主题的文档自行设置，常见的有 <code>zh-Hans</code>和 <code>zh-CN</code>。</td></tr><tr><td><code>timezone</code></td><td>网站时区。Hexo 默认使用您电脑的时区。请参考 <a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones" target="_blank">时区列表</a> 进行设置，如 <code>America/New_York</code>, <code>Japan</code>, 和 <code>UTC</code> 。一般的，对于中国大陆地区可以使用 <code>Asia/Shanghai</code>。</td></tr></tbody></table><p>其中，<code>description</code> 主要用于SEO，告诉搜索引擎一个关于您站点的简单描述，通常建议在其中包含您网站的关键词。<code>author</code> 参数用于主题显示文章的作者。</p></section><section><h4>网址<a href="#网址"><span>#</span></a></h4>

<table><thead><tr><th>参数</th><th>描述</th><th>默认值</th></tr></thead><tbody><tr><td><code>url</code></td><td>网址, 必须以 <code>http://</code> 或 <code>https://</code> 开头</td><td></td></tr><tr><td><code>root</code></td><td>网站根目录</td><td><code>url's pathname</code></td></tr><tr><td><code>permalink</code></td><td>文章的 <a href="https://hexo.io/zh-cn/docs/permalinks" target="_blank">永久链接</a> 格式</td><td><code>:year/:month/:day/:title/</code></td></tr><tr><td><code>permalink_defaults</code></td><td>永久链接中各部分的默认值</td><td></td></tr><tr><td><code>pretty_urls</code></td><td>改写 <a href="https://hexo.io/zh-cn/docs/variables" target="_blank"><code>permalink</code></a> 的值来美化 URL</td><td></td></tr><tr><td><code>pretty_urls.trailing_index</code></td><td>是否在永久链接中保留尾部的 <code>index.html</code>，设置为 <code>false</code> 时去除</td><td><code>true</code></td></tr><tr><td><code>pretty_urls.trailing_html</code></td><td>是否在永久链接中保留尾部的 <code>.html</code>, 设置为 <code>false</code> 时去除 (<em>对尾部的 <code>index.html</code>无效</em>)</td><td><code>true</code></td></tr></tbody></table><blockquote><p>网站存放在子目录</p><p>如果您的网站存放在子目录中，例如 <code>http://example.com/blog</code>，则请将您的 <code>url</code> 设为 <code>http://example.com/blog</code> 并把 <code>root</code> 设为 <code>/blog/</code>。</p></blockquote><p>例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 比如，一个页面的永久链接是 http://example.com/foo/bar/index.html</span></div></div><div><div><div>2</div></div><div><span>pretty_urls</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>trailing_index</span><span>: </span><span>false</span></div></div><div><div><div>4</div></div><div><span># 此时页面的永久链接会变为 http://example.com/foo/bar/</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>目录<a href="#目录"><span>#</span></a></h4>

<table><thead><tr><th>参数</th><th>描述</th><th>默认值</th></tr></thead><tbody><tr><td><code>source_dir</code></td><td>资源文件夹，这个文件夹用来存放内容。</td><td><code>source</code></td></tr><tr><td><code>public_dir</code></td><td>公共文件夹，这个文件夹用于存放生成的站点文件。</td><td><code>public</code></td></tr><tr><td><code>tag_dir</code></td><td>标签文件夹</td><td><code>tags</code></td></tr><tr><td><code>archive_dir</code></td><td>归档文件夹</td><td><code>archives</code></td></tr><tr><td><code>category_dir</code></td><td>分类文件夹</td><td><code>categories</code></td></tr><tr><td><code>code_dir</code></td><td>Include code 文件夹，<code>source_dir</code> 下的子目录</td><td><code>downloads/code</code></td></tr><tr><td><code>i18n_dir</code></td><td>国际化（i18n）文件夹</td><td><code>:lang</code></td></tr><tr><td><code>skip_render</code></td><td>跳过指定文件的渲染。匹配到的文件将会被不做改动地复制到 <code>public</code> 目录中。您可使用 <a href="https://github.com/micromatch/micromatch#extended-globbing" target="_blank">glob 表达式</a>来匹配路径。</td><td></td></tr></tbody></table><p>例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>skip_render</span><span>: </span><span>"mypage/**/*"</span></div></div><div><div><div>2</div></div><div><span># 将会直接将 `source/mypage/index.html` 和 `source/mypage/code.js` 不做改动地输出到 'public' 目录</span></div></div><div><div><div>3</div></div><div><span># 你也可以用这种方法来跳过对指定文章文件的渲染</span></div></div><div><div><div>4</div></div><div><span>skip_render</span><span>: </span><span>"_posts/test-post.md"</span></div></div><div><div><div>5</div></div><div><span># 这将会忽略对 'test-post.md' 的渲染</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>提示</p><p>如果您刚刚开始接触 Hexo，通常没有必要修改这一部分的值。</p></blockquote></section><section><h4>文章<a href="#文章"><span>#</span></a></h4>

<table><thead><tr><th>参数</th><th>描述</th><th>默认值</th></tr></thead><tbody><tr><td><code>new_post_name</code></td><td>新文章的文件名称</td><td><code>:title.md</code></td></tr><tr><td><code>default_layout</code></td><td>预设布局</td><td><code>post</code></td></tr><tr><td><code>auto_spacing</code></td><td>在中文和英文之间加入空格</td><td><code>false</code></td></tr><tr><td><code>titlecase</code></td><td>把标题转换为 title case</td><td><code>false</code></td></tr><tr><td><code>external_link</code></td><td>在新标签中打开链接</td><td><code>true</code></td></tr><tr><td><code>external_link.enable</code></td><td>在新标签中打开链接</td><td><code>true</code></td></tr><tr><td><code>external_link.field</code></td><td>对整个网站（<code>site</code>）生效或仅对文章（<code>post</code>）生效</td><td><code>site</code></td></tr><tr><td><code>external_link.exclude</code></td><td>需要排除的域名。主域名和子域名如 <code>www</code> 需分别配置</td><td><code>[]</code></td></tr><tr><td><code>filename_case</code></td><td>把文件名称转换为 (1) 小写或 (2) 大写</td><td><code>0</code></td></tr><tr><td><code>render_drafts</code></td><td>显示草稿</td><td><code>false</code></td></tr><tr><td><code>post_asset_folder</code></td><td>启用 <a href="https://hexo.io/zh-cn/docs/asset-folders" target="_blank">资源文件夹</a></td><td><code>false</code></td></tr><tr><td><code>relative_link</code></td><td>把链接改为与根目录的相对位址</td><td><code>false</code></td></tr><tr><td><code>future</code></td><td>显示未来的文章</td><td><code>true</code></td></tr><tr><td><code>syntax_highlighter</code></td><td>代码块的设置, 请参考 <a href="https://hexo.io/zh-cn/docs/syntax-highlight" target="_blank">代码高亮</a> 进行设置</td><td><code>highlight.js</code></td></tr><tr><td><code>highlight</code></td><td>代码块的设置, 请参考 <a href="https://hexo.io/zh-cn/docs/syntax-highlight#Highlight-js" target="_blank">Highlight.js</a> 进行设置</td><td></td></tr><tr><td><code>prismjs</code></td><td>代码块的设置, 请参考 <a href="https://hexo.io/zh-cn/docs/syntax-highlight#PrismJS" target="_blank">PrismJS</a> 进行设置</td><td></td></tr></tbody></table><blockquote><p>相对地址</p><p>默认情况下，Hexo 生成的超链接都是绝对地址。例如，如果您的网站域名为 <code>example.com</code>，您有一篇文章名为 <code>hello</code>，那么绝对链接可能像这样：<code>http://example.com/hello.html</code>，它是<strong>绝对</strong>于域名的。相对链接像这样：<code>/hello.html</code>，也就是说，无论用什么域名访问该站点，都没有关系，这在进行反向代理时可能用到。通常情况下，建议使用绝对地址。</p></blockquote></section><section><h4>分类 &amp; 标签<a href="#分类--标签"><span>#</span></a></h4>

<table><thead><tr><th>参数</th><th>描述</th><th>默认值</th></tr></thead><tbody><tr><td><code>default_category</code></td><td>默认分类</td><td><code>uncategorized</code></td></tr><tr><td><code>category_map</code></td><td>分类别名</td><td></td></tr><tr><td><code>tag_map</code></td><td>标签别名</td><td></td></tr></tbody></table></section><section><h4>日期 / 时间格式<a href="#日期--时间格式"><span>#</span></a></h4><p>Hexo 使用 <a href="http://momentjs.com/" target="_blank">Moment.js</a> 来解析和显示时间。</p>

<table><thead><tr><th>参数</th><th>描述</th><th>默认值</th></tr></thead><tbody><tr><td><code>date_format</code></td><td>日期格式</td><td><code>YYYY-MM-DD</code></td></tr><tr><td><code>time_format</code></td><td>时间格式</td><td><code>HH:mm:ss</code></td></tr><tr><td><code>updated_option</code></td><td>当 Front Matter 中没有指定 <a href="https://hexo.io/zh-cn/docs/variables#%E9%A1%B5%E9%9D%A2%E5%8F%98%E9%87%8F" target="_blank"><code>updated</code></a> 时 <code>updated</code> 的取值</td><td><code>mtime</code></td></tr></tbody></table><blockquote><p>updated_option</p><p><code>updated_option</code> 控制了当 Front Matter 中没有指定 <code>updated</code> 时，<code>updated</code> 如何取值：</p><ul>
<li><code>mtime</code>: 使用文件的最后修改时间。这是从 Hexo 3.0.0 开始的默认行为。</li>
<li><code>date</code>: 使用 <code>date</code> 作为 <code>updated</code> 的值。可被用于 Git 工作流之中，因为使用 Git 管理站点时，文件的最后修改日期常常会发生改变</li>
<li><code>empty</code>: 直接删除 <code>updated</code>。使用这一选项可能会导致大部分主题和插件无法正常工作。</li>
</ul><p><code>use_date_for_updated</code> 选项已经在 v7.0.0+ 中被移除。请改为使用 <code>updated_option: 'date'</code>。</p></blockquote></section><section><h4>分页<a href="#分页"><span>#</span></a></h4>

<table><thead><tr><th>参数</th><th>描述</th><th>默认值</th></tr></thead><tbody><tr><td><code>per_page</code></td><td>每页显示的文章量 (0 = 关闭分页功能)</td><td><code>10</code></td></tr><tr><td><code>pagination_dir</code></td><td>分页目录</td><td><code>page</code></td></tr></tbody></table><p>例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>pagination_dir</span><span>: </span><span>'page'</span></div></div><div><div><div>2</div></div><div><span># http://example.com/page/2</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>pagination_dir</span><span>: </span><span>'awesome-page'</span></div></div><div><div><div>5</div></div><div><span># http://example.com/awesome-page/2</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>扩展<a href="#扩展"><span>#</span></a></h4>

<table><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td><code>theme</code></td><td>当前主题名称。值为<code>false</code>时禁用主题</td></tr><tr><td><code>theme_config</code></td><td>主题的配置文件。在这里放置的配置会覆盖主题目录下的 <code>_config.yml</code> 中的配置</td></tr><tr><td><code>deploy</code></td><td>部署部分的设置</td></tr><tr><td><code>meta_generator</code></td><td><a href="https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/meta#%E5%B1%9E%E6%80%A7" target="_blank">Meta generator</a> 标签。 值为 <code>false</code> 时 Hexo 不会在头部插入该标签</td></tr></tbody></table><section><h5>包括或不包括目录和文件<a href="#包括或不包括目录和文件"><span>#</span></a></h5><p>在 Hexo 配置文件中，通过设置 include/exclude 可以让 Hexo 进行处理或忽略某些目录和文件夹。你可以使用 <a href="https://github.com/isaacs/minimatch" target="_blank">glob 表达式</a> 对目录和文件进行匹配。</p><p><code>include</code> 和 <code>exclude</code> 选项只会应用到 <code>source/</code> ，而 <code>ignore</code> 选项会应用到所有文件夹.</p>

<table><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td><code>include</code></td><td>Hexo 默认会不包括 <code>source/</code> 下的文件和文件夹（包括名称以下划线和 <code>.</code> 开头的文件和文件夹，Hexo 的 <code>_posts</code> 和 <code>_data</code> 等目录除外）。通过设置此字段将使 Hexo 处理他们并将它们复制到 <code>source</code> 目录下。</td></tr><tr><td><code>exclude</code></td><td>Hexo 不包括 <code>source/</code> 下的这些文件和目录</td></tr><tr><td><code>ignore</code></td><td>Hexo 会忽略整个 Hexo 项目下的这些文件夹或文件</td></tr></tbody></table><p>例如：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># 处理或不处理目录或文件</span></div></div><div><div><div>2</div></div><div><span>include</span><span>:</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>- </span><span>".nojekyll"</span></div></div><div><div><div>4</div></div><div><span>  </span><span># 处理 'source/css/_typing.css'</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>- </span><span>"css/_typing.css"</span></div></div><div><div><div>6</div></div><div><span>  </span><span># 处理 'source/_css/' 中的任何文件，但不包括子目录及其其中的文件。</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>- </span><span>"_css/*"</span></div></div><div><div><div>8</div></div><div><span>  </span><span># 处理 'source/_css/' 中的任何文件和子目录下的任何文件</span></div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>- </span><span>"_css/**/*"</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>exclude</span><span>:</span></div></div><div><div><div>12</div></div><div><span>  </span><span># 不处理 'source/js/test.js'</span></div></div><div><div><div>13</div></div><div><span><span>  </span></span><span>- </span><span>"js/test.js"</span></div></div><div><div><div>14</div></div><div><span>  </span><span># 不处理 'source/js/' 中的文件、但包括子目录下的所有目录和文件</span></div></div><div><div><div>15</div></div><div><span><span>  </span></span><span>- </span><span>"js/*"</span></div></div><div><div><div>16</div></div><div><span>  </span><span># 不处理 'source/js/' 中的文件和子目录下的任何文件</span></div></div><div><div><div>17</div></div><div><span><span>  </span></span><span>- </span><span>"js/**/*"</span></div></div><div><div><div>18</div></div><div><span>  </span><span># 不处理 'source/js/' 目录下的所有文件名以 'test' 开头的文件，但包括其它文件和子目录下的单文件</span></div></div><div><div><div>19</div></div><div><span><span>  </span></span><span>- </span><span>"js/test*"</span></div></div><div><div><div>20</div></div><div><span>  </span><span># 不处理 'source/js/' 及其子目录中任何以 'test' 开头的文件</span></div></div><div><div><div>21</div></div><div><span><span>  </span></span><span>- </span><span>"js/**/test*"</span></div></div><div><div><div>22</div></div><div><span>  </span><span># 不要用 exclude 来忽略 'source/_posts/' 中的文件。你应该使用 'skip_render'，或者在要忽略的文件的文件名之前加一个下划线 '_'</span></div></div><div><div><div>23</div></div><div><span>  </span><span># 在这里配置一个 - "_posts/hello-world.md" 是没有用的。</span></div></div><div><div><div>24</div></div><div>
</div></div><div><div><div>25</div></div><div><span>ignore</span><span>:</span></div></div><div><div><div>26</div></div><div><span>  </span><span># 忽略任何一个名叫 'foo' 的文件夹</span></div></div><div><div><div>27</div></div><div><span><span>  </span></span><span>- </span><span>"**/foo"</span></div></div><div><div><div>28</div></div><div><span>  </span><span># 只忽略 'themes/' 下的 'foo' 文件夹</span></div></div><div><div><div>29</div></div><div><span><span>  </span></span><span>- </span><span>"**/themes/*/foo"</span></div></div><div><div><div>30</div></div><div><span>  </span><span># 对 'themes/' 目录下的每个文件夹中忽略名叫 'foo' 的子文件夹</span></div></div><div><div><div>31</div></div><div><span><span>  </span></span><span>- </span><span>"**/themes/**/foo"</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>列表中的每一项都必须用单引号或双引号包裹起来。</p><p><code>include</code> 和 <code>exclude</code> 并不适用于 <code>themes/</code> 目录下的文件。如果需要忽略 <code>themes/</code> 目录下的部分文件或文件夹，可以使用 <code>ignore</code> 或在文件名之前添加下划线 <code>_</code>。</p><ul>
<li><code>source/_posts</code> 文件夹是一个例外，但该文件夹下任何名称以 <code>_</code> 开头的文件或文件夹仍会被忽略。不建议在该文件夹中使用 <code>include</code> 规则。</li>
</ul></section><section><h5>使用代替配置文件<a href="#使用代替配置文件"><span>#</span></a></h5><p>可以在 hexo-cli 中使用 <code>--config</code> 参数来指定自定义配置文件的路径。你可以使用一个 YAML 或 JSON 文件的路径，也可以使用逗号分隔（无空格）的多个 YAML 或 JSON 文件的路径。例如：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 用 'custom.yml' 代替 '_config.yml'</span></div></div><div><div><div>2</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>server</span><span> </span><span>--config</span><span> </span><span>custom.yml</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 使用 'custom.yml' 和 'custom2.json'，优先使用 'custom3.yml'，然后是 'custom2.json'</span></div></div><div><div><div>5</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>generate</span><span> </span><span>--config</span><span> </span><span>custom.yml,custom2.json,custom3.yml</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>当你指定了多个配置文件以后，Hexo 会按顺序将这部分配置文件合并成一个 <code>_multiconfig.yml</code>。如果遇到重复的配置，排在后面的文件的配置会覆盖排在前面的文件的配置。这个原则适用于任意数量、任意深度的 YAML 和 JSON 文件。</p><p>例如，使用 <code>--config</code> 指定了两个自定义配置文件：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>generate</span><span> </span><span>--config</span><span> </span><span>custom.yml,custom2.json</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果 <code>custom.yml</code> 中指定了 <code>foo: bar</code>，在 custom2.json 中指定了 <code>"foo": "dinosaur"</code>，那么在 <code>_multiconfig.yml</code> 中你会得到 <code>foo: dinosaur</code>。</p></section><section><h5>使用代替主题配置文件<a href="#使用代替主题配置文件"><span>#</span></a></h5><p>通常情况下，Hexo 主题是一个独立的项目，并拥有一个独立的 <code>_config.yml</code> 配置文件。</p><p>除了自行维护独立的主题配置文件，你也可以在其它地方对主题进行配置。</p><p><strong>配置文件中的 <code>theme_config</code></strong></p><blockquote><p>该特性自 Hexo 2.8.2 起提供</p></blockquote><div><figure><figcaption><span>_config.yml</span></figcaption><pre><code><div><div><div>1</div></div><div><span>theme</span><span>: </span><span>"my-theme"</span></div></div><div><div><div>2</div></div><div><span>theme_config</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>bio</span><span>: </span><span>"My awesome bio"</span></div></div><div><div><div>4</div></div><div><span>  </span><span>foo</span><span>:</span></div></div><div><div><div>5</div></div><div><span>    </span><span>bar</span><span>: </span><span>'a'</span></div></div><div><div><div>6</div></div><div><span># themes/my-theme/_config.yml</span></div></div><div><div><div>7</div></div><div><span>bio</span><span>: </span><span>"Some generic bio"</span></div></div><div><div><div>8</div></div><div><span>logo</span><span>: </span><span>"a-cool-image.png"</span></div></div><div><div><div>9</div></div><div><span>  </span><span>foo</span><span>:</span></div></div><div><div><div>10</div></div><div><span>    </span><span>baz</span><span>: </span><span>'b'</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>最终主题配置的输出是：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>bio</span><span>: </span><span>"My awesome bio"</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>logo</span><span>: </span><span>"a-cool-image.png"</span><span>,</span></div></div><div><div><div>4</div></div><div><span>  </span><span>foo</span><span>: {</span></div></div><div><div><div>5</div></div><div><span>    </span><span>bar</span><span>: </span><span>"a"</span><span>,</span></div></div><div><div><div>6</div></div><div><span>    </span><span>baz</span><span>: </span><span>"b"</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>8</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>独立的 <code>_config.[theme].yml</code> 文件</strong></p><blockquote><p>该特性自 Hexo 5.0.0 起提供</p></blockquote><p>独立的主题配置文件应放置于站点根目录下，支持 <code>yml</code> 或 <code>json</code> 格式。需要配置站点 <code>_config.yml</code> 文件中的 <code>theme</code> 以供 Hexo 寻找 <code>_config.[theme].yml</code> 文件。</p><div><figure><figcaption><span>_config.yml</span></figcaption><pre><code><div><div><div>1</div></div><div><span>theme</span><span>: </span><span>"my-theme"</span></div></div><div><div><div>2</div></div><div><span># _config.my-theme.yml</span></div></div><div><div><div>3</div></div><div><span>bio</span><span>: </span><span>"My awesome bio"</span></div></div><div><div><div>4</div></div><div><span>foo</span><span>:</span></div></div><div><div><div>5</div></div><div><span>  </span><span>bar</span><span>: </span><span>'a'</span></div></div><div><div><div>6</div></div><div><span># themes/my-theme/_config.yml</span></div></div><div><div><div>7</div></div><div><span>bio</span><span>: </span><span>"Some generic bio"</span></div></div><div><div><div>8</div></div><div><span>logo</span><span>: </span><span>"a-cool-image.png"</span></div></div><div><div><div>9</div></div><div><span>  </span><span>foo</span><span>:</span></div></div><div><div><div>10</div></div><div><span>    </span><span>baz</span><span>: </span><span>'b'</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>最终主题配置的输出是：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>bio</span><span>: </span><span>"My awesome bio"</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>logo</span><span>: </span><span>"a-cool-image.png"</span><span>,</span></div></div><div><div><div>4</div></div><div><span>  </span><span>foo</span><span>: {</span></div></div><div><div><div>5</div></div><div><span>    </span><span>bar</span><span>: </span><span>"a"</span><span>,</span></div></div><div><div><div>6</div></div><div><span>    </span><span>baz</span><span>: </span><span>"b"</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>8</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>我们强烈建议你将所有的主题配置集中在一处。如果你不得不在多处配置你的主题，那么这些信息对你将会非常有用：Hexo 在合并主题配置时，Hexo 配置文件中的 <code>theme_config</code> 的优先级最高，其次是 <code>_config.[theme].yml</code> 文件，最后是位于主题目录下的 <code>_config.yml</code> 文件。</p></blockquote></section></section></section><section><h3>指令<a href="#指令"><span>#</span></a></h3><section><h4>init<a href="#init"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>init</span><span> [folder]</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>新建一个网站。如果没有设置 <code>folder</code> ，Hexo 默认在目前的文件夹建立网站。</p><p>本命令相当于执行了以下几步：</p><ol>
<li>Git clone <a href="https://github.com/hexojs/hexo-starter" target="_blank">hexo-starter</a> 和 <a href="https://github.com/hexojs/hexo-theme-landscape" target="_blank">hexo-theme-landscape</a> 主题到当前目录或指定目录。</li>
<li>使用 <a href="https://classic.yarnpkg.com/lang/en/" target="_blank">Yarn 1</a>、<a href="https://pnpm.io/zh/" target="_blank">pnpm</a> 或 <a href="https://docs.npmjs.com/cli/install" target="_blank">npm</a> 包管理器下载依赖（如有已安装多个，则列在前面的优先）。npm 默认随 <a href="https://hexo.io/zh-cn/docs/index.html#%E5%AE%89%E8%A3%85-Node-js" target="_blank">Node.js</a> 安装。</li>
</ol></section><section><h4>new<a href="#new"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>new</span><span> [layout] &lt;title&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>新建一篇文章。如果没有设置 <code>layout</code> 的话，默认使用 <a href="https://hexo.io/zh-cn/docs/configuration" target="_blank">_config.yml</a> 中的 <code>default_layout</code> 参数代替。如果标题包含空格的话，请使用引号括起来。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>new</span><span> </span><span>"post title with whitespace"</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<table><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td><code>-p</code>, <code>--path</code></td><td>自定义新文章的路径</td></tr><tr><td><code>-r</code>, <code>--replace</code></td><td>如果存在同名文章，将其替换</td></tr><tr><td><code>-s</code>, <code>--slug</code></td><td>文章的 Slug，作为新文章的文件名和发布后的 URL</td></tr></tbody></table><p>默认情况下，Hexo 会使用文章的标题来决定文章文件的路径。对于独立页面来说，Hexo 会创建一个以标题为名字的目录，并在目录中放置一个 <code>index.md</code> 文件。你可以使用 <code>--path</code> 参数来覆盖上述行为、自行决定文件的目录：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>hexo</span><span> </span><span>new</span><span> </span><span>page</span><span> </span><span>--path</span><span> </span><span>about/me</span><span> </span><span>"About me"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>以上命令会创建一个 <code>source/about/me.md</code> 文件，同时 Front Matter 中的 title 为 <code>"About me"</code></p><p>注意！title 是必须指定的！如果你这么做并不能达到你的目的：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>hexo</span><span> </span><span>new</span><span> </span><span>page</span><span> </span><span>--path</span><span> </span><span>about/me</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>此时 Hexo 会创建 <code>source/_posts/about/me.md</code>，同时 <code>me.md</code> 的 Front Matter 中的 title 为 <code>"page"</code>。这是因为在上述命令中，hexo-cli 将 <code>page</code> 视为指定文章的标题、并采用默认的 <code>layout</code>。</p></section><section><h4>generate<a href="#generate"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>generate</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>生成静态文件。</p>

<table><thead><tr><th>选项</th><th>描述</th></tr></thead><tbody><tr><td><code>-d</code>, <code>--deploy</code></td><td>文件生成后立即部署网站</td></tr><tr><td><code>-w</code>, <code>--watch</code></td><td>监视文件变动</td></tr><tr><td><code>-b</code>, <code>--bail</code></td><td>生成过程中如果发生任何未处理的异常则抛出异常</td></tr><tr><td><code>-f</code>, <code>--force</code></td><td>强制重新生成文件 Hexo 引入了差分机制，如果 <code>public</code> 目录存在，那么 <code>hexo g</code> 只会重新生成改动的文件。 使用该参数的效果接近 <code>hexo clean &amp;&amp; hexo generate</code></td></tr><tr><td><code>-c</code>, <code>--concurrency</code></td><td>最大同时生成文件的数量，默认无限制</td></tr></tbody></table><p>该命令可以简写为</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>g</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>publish<a href="#publish"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>publish</span><span> [layout] &lt;filename&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>发表草稿。</p></section><section><h4>server<a href="#server"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>server</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>启动服务器。默认情况下，访问网址为： <code>http://localhost:4000/</code>。</p>

<table><thead><tr><th>选项</th><th>描述</th></tr></thead><tbody><tr><td><code>-p</code>, <code>--port</code></td><td>重设端口</td></tr><tr><td><code>-s</code>, <code>--static</code></td><td>只使用静态文件</td></tr><tr><td><code>-l</code>, <code>--log</code></td><td>启动日记记录，使用覆盖记录格式</td></tr></tbody></table></section><section><h4>deploy<a href="#deploy"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>deploy</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>部署网站。</p>

<table><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td><code>-g</code>, <code>--generate</code></td><td>部署之前预先生成静态文件</td></tr></tbody></table><p>该命令可以简写为：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>d</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>render<a href="#render"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>render</span><span> </span><span>&lt;file1&gt;</span><span> [file2] ...</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>渲染文件。</p>

<table><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td><code>-o</code>, <code>--output</code></td><td>设置输出路径</td></tr></tbody></table></section><section><h4>migrate<a href="#migrate"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>migrate</span><span> </span><span>&lt;type&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>从其他博客系统 <a href="https://hexo.io/zh-cn/docs/migration" target="_blank">迁移内容</a>。</p></section><section><h4>clean<a href="#clean"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>clean</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>清除缓存文件 (<code>db.json</code>) 和已生成的静态文件 (<code>public</code>)。</p><p>在某些情况（尤其是更换主题后），如果发现您对站点的更改无论如何也不生效，您可能需要运行该命令。</p></section><section><h4>list<a href="#list"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>list</span><span> </span><span>&lt;type&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>列出网站数据。</p></section><section><h4>version<a href="#version"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>version</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>显示 Hexo 版本。</p></section><section><h4>config<a href="#config"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>config</span><span> [key] [value]</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>列出网站的配置（<code>_config.yml</code>）。如果指定了 <code>key</code>，则只展示配置中对应 <code>key</code> 的值；如果同时指定了 <code>key</code> 和 <code>value</code>，则将配置中对应的 <code>key</code> 的值修改为 <code>value</code>。</p></section><section><h4>选项<a href="#选项"><span>#</span></a></h4><section><h5>安全模式<a href="#安全模式"><span>#</span></a></h5><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>--safe</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在安全模式下，不会加载插件和脚本。当您在安装新插件遭遇问题时，可以尝试以安全模式重新执行。</p></section><section><h5>调试模式<a href="#调试模式"><span>#</span></a></h5><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>--debug</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在终端中显示调试信息并记录到 <code>debug.log</code>。当您碰到问题时，可以尝试用调试模式重新执行一次，并 <a href="https://github.com/hexojs/hexo/issues/new?assignees=&amp;labels=&amp;projects=&amp;template=bug_report.yml" target="_blank">提交调试信息到 GitHub</a>。</p></section><section><h5>简洁模式<a href="#简洁模式"><span>#</span></a></h5><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>--silent</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>隐藏终端信息。</p></section><section><h5>自定义配置文件的路径<a href="#自定义配置文件的路径"><span>#</span></a></h5><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 使用 custom.yml 代替默认的 _config.yml</span></div></div><div><div><div>2</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>server</span><span> </span><span>--config</span><span> </span><span>custom.yml</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 使用 custom.yml 和 custom2.json，其中 custom2.json 优先级更高</span></div></div><div><div><div>5</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>generate</span><span> </span><span>--config</span><span> </span><span>custom.yml,custom2.json,custom3.yml</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>自定义配置文件的路径，指定这个参数后将不再使用默认的 <code>_config.yml</code>。
你可以使用一个 YAML 或 JSON 文件的路径，也可以使用逗号分隔（无空格）的多个 YAML 或 JSON 文件的路径。例如：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 使用 custom.yml 代替默认的 _config.yml</span></div></div><div><div><div>2</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>server</span><span> </span><span>--config</span><span> </span><span>custom.yml</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 使用 custom.yml, custom2.json 和 custom3.yml，其中 custom3.yml 优先级最高，其次是 custom2.json</span></div></div><div><div><div>5</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>generate</span><span> </span><span>--config</span><span> </span><span>custom.yml,custom2.json,custom3.yml</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>当你指定了多个配置文件以后，Hexo 会按顺序将这部分配置文件合并成一个 <code>_multiconfig.yml</code>。如果遇到重复的配置，排在后面的文件的配置会覆盖排在前面的文件的配置。这个原则适用于任意数量、任意深度的 YAML 和 JSON 文件。</p></section><section><h5>显示草稿<a href="#显示草稿"><span>#</span></a></h5><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>--draft</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>显示 <code>source/_drafts</code> 文件夹中的草稿文章。</p></section><section><h5>自定义 CWD<a href="#自定义-cwd"><span>#</span></a></h5><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>--cwd</span><span> </span><span>/path/to/cwd</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>自定义当前工作目录（Current working directory）的路径。</p></section></section></section></section>
<section><h2>基本操作<a href="#基本操作"><span>#</span></a></h2><section><h3>写作<a href="#写作"><span>#</span></a></h3><p>你可以执行下列命令来创建一篇新文章或者新的页面。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$</span><span> </span><span>hexo</span><span> </span><span>new</span><span> [layout] &lt;title&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>您可以在命令中指定文章的布局（layout），默认为 <code>post</code>，可以通过修改 <code>_config.yml</code> 中的 <code>default_layout</code> 参数来指定默认布局。</p><section><h4>布局（Layout）<a href="#布局layout"><span>#</span></a></h4><p>Hexo 有三种默认布局：<code>post</code>、<code>page</code> 和 <code>draft</code>。在创建这三种不同类型的文件时，它们将会被保存到不同的路径；而您自定义的其他布局和 <code>post</code> 相同，都将储存到 <code>source/_posts</code> 文件夹。</p>

<table><thead><tr><th>布局</th><th>路径</th></tr></thead><tbody><tr><td><code>post</code></td><td><code>source/_posts</code></td></tr><tr><td><code>page</code></td><td><code>source</code></td></tr><tr><td><code>draft</code></td><td><code>source/_drafts</code></td></tr></tbody></table><blockquote><p>禁用布局</p><p>如果你不希望一篇文章（post/page）使用主题处理，请在它的 front-matter 中设置 <code>layout: false</code>。详情请参考<a href="https://hexo.io/zh-cn/docs/front-matter#%E5%B8%83%E5%B1%80" target="_blank">本节</a>。</p></blockquote></section><section><h4>文件名称<a href="#文件名称"><span>#</span></a></h4><p>Hexo 默认以标题做为文件名称，但您可编辑 <code>new_post_name</code> 参数来改变默认的文件名称，举例来说，设为 <code>:year-:month-:day-:title.md</code> 可让您更方便的通过日期来管理文章。你可以使用以下占位符：</p>

<table><thead><tr><th>变量</th><th>描述</th></tr></thead><tbody><tr><td><code>:title</code></td><td>标题（小写，空格将会被替换为短杠）</td></tr><tr><td><code>:year</code></td><td>建立的年份，比如， <code>2015</code></td></tr><tr><td><code>:month</code></td><td>建立的月份（有前导零），比如， <code>04</code></td></tr><tr><td><code>:i_month</code></td><td>建立的月份（无前导零），比如， <code>4</code></td></tr><tr><td><code>:day</code></td><td>建立的日期（有前导零），比如， <code>07</code></td></tr><tr><td><code>:i_day</code></td><td>建立的日期（无前导零），比如， <code>7</code></td></tr></tbody></table></section><section><h4>草稿<a href="#草稿"><span>#</span></a></h4><p>刚刚提到了 Hexo 的一种特殊布局：<code>draft</code>，这种布局在建立时会被保存到 <code>source/_drafts</code> 文件夹，您可通过 <code>publish</code> 命令将草稿移动到 <code>source/_posts</code> 文件夹，该命令的使用方式与 <code>new</code> 十分类似，您也可在命令中指定 <code>layout</code> 来指定布局。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>$ hexo publish [layout] &lt;title&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>草稿默认不会显示在页面中，您可在执行时加上 <code>--draft</code> 参数，或是在 <code>_config.yml</code> 中把 <code>render_drafts</code> 参数设为 <code>true</code> 来预览草稿。</p></section><section><h4>模版（Scaffold）<a href="#模版scaffold"><span>#</span></a></h4><p>在新建文章时，Hexo 会根据 <code>scaffolds</code> 文件夹内相对应的文件来建立文件，例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>$ hexo new photo "My Gallery"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在执行这行指令时，Hexo 会尝试在 <code>scaffolds</code> 文件夹中寻找 <code>photo.md</code>，并根据其内容建立文章，以下是您可以在模版中使用的变量：</p>

<table><thead><tr><th>变量</th><th>描述</th></tr></thead><tbody><tr><td><code>layout</code></td><td>布局</td></tr><tr><td><code>title</code></td><td>标题</td></tr><tr><td><code>date</code></td><td>文件建立日期</td></tr></tbody></table></section><section><h4>支持的格式<a href="#支持的格式"><span>#</span></a></h4><p>Hexo 支持以任何格式书写文章，只要安装了相应的渲染插件。</p><p>例如，Hexo 默认安装了 <code>hexo-renderer-marked</code> 和 <code>hexo-renderer-ejs</code>，因此你不仅可以用 Markdown 写作，你还可以用 EJS 写作。如果你安装了 <code>hexo-renderer-pug</code>，你甚至可以用 Pug 模板语言书写文章。</p><p>只需要将文章的扩展名从 <code>md</code> 改成 <code>ejs</code>，Hexo 就会使用 <code>hexo-renderer-ejs</code> 渲染这个文件，其他格式同理。</p></section></section><section><h3>Front-matter<a href="#front-matter"><span>#</span></a></h3><p>Front-matter 是文件最上方以 <code>---</code> 分隔的区域，用于指定个别文件的变量，举例来说：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title: Hello World</span></div></div><div><div><div>3</div></div><div><span>date: 2013/7/13 20:46:25</span></div></div><div><div><div>4</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>以下是预先定义的参数，您可在模板中使用这些参数值并加以利用。</p>

<table><thead><tr><th>参数</th><th>描述</th><th>默认值</th></tr></thead><tbody><tr><td><code>layout</code></td><td>布局</td><td><a href="https://hexo.io/zh-cn/docs/configuration#%E6%96%87%E7%AB%A0" target="_blank"><code>config.default_layout</code></a></td></tr><tr><td><code>title</code></td><td>标题</td><td>文章的文件名</td></tr><tr><td><code>date</code></td><td>建立日期</td><td>文件建立日期</td></tr><tr><td><code>updated</code></td><td>更新日期</td><td>文件更新日期</td></tr><tr><td><code>comments</code></td><td>开启文章的评论功能</td><td><code>true</code></td></tr><tr><td><code>tags</code></td><td>标签（不适用于分页）</td><td></td></tr><tr><td><code>categories</code></td><td>分类（不适用于分页）</td><td></td></tr><tr><td><code>permalink</code></td><td>覆盖文章的永久链接，永久链接应该以 <code>/</code> 或 <code>.html</code> 结尾</td><td><code>null</code></td></tr><tr><td><code>excerpt</code></td><td>纯文本的页面摘要。使用 <a href="https://hexo.io/zh-cn/docs/tag-plugins#%E6%96%87%E7%AB%A0%E6%91%98%E8%A6%81%E5%92%8C%E6%88%AA%E6%96%AD" target="_blank">该插件</a> 来格式化文本</td><td></td></tr><tr><td><code>disableNunjucks</code></td><td>启用时禁用 Nunjucks 标签 <code>{{ }}</code>/<code>{% %}</code> 和 <a href="https://hexo.io/zh-cn/docs/tag-plugins" target="_blank">标签插件</a> 的渲染功能</td><td>false</td></tr><tr><td><code>lang</code></td><td>设置语言以覆盖 <a href="https://hexo.io/zh-cn/docs/internationalization#%E8%B7%AF%E5%BE%84" target="_blank">自动检测</a></td><td>继承自 <code>_config.yml</code></td></tr><tr><td><code>published</code></td><td>文章是否发布</td><td>对于 <code>_posts</code> 下的文章为 <code>true</code>，对于 <code>_draft</code> 下的文章为 <code>false</code></td></tr></tbody></table><section><h4>布局<a href="#布局"><span>#</span></a></h4><p>根据 <code>_config.yml</code> 中 <a href="https://hexo.io/zh-cn/docs/configuration#%E6%96%87%E7%AB%A0" target="_blank"><code>default_layout</code></a> 的设置，默认布局是 <code>post</code> 。当文章中的布局被禁用(<code>layout: false</code>)，它将不会使用主题处理。然而，它仍然会被任何可用的渲染引擎渲染：如果一篇文章是用 Markdown 写的，并且安装了 Markdown 渲染引擎（比如默认的 <a href="https://github.com/hexojs/hexo-renderer-marked" target="_blank">hexo-renderer-marked</a>)，它将被渲染成HTML。</p><p>除非通过 <code>disableNunjucks</code> 设置或 <a href="https://hexo.io/zh-cn/api/renderer#%E7%A6%81%E7%94%A8-Nunjucks-%E6%A0%87%E7%AD%BE" target="_blank">渲染引擎</a> 禁用，否则无论布局如何，<a href="https://hexo.io/zh-cn/docs/tag-plugins" target="_blank">标签插件</a> 总是被处理。</p></section><section><h4>分类和标签<a href="#分类和标签"><span>#</span></a></h4><p>只有文章支持分类和标签，您可以在 Front-matter 中设置。在其他系统中，分类和标签听起来很接近，但是在 Hexo 中两者有着明显的差别：分类具有顺序性和层次性，也就是说 <code>Foo, Bar</code> 不等于 <code>Bar, Foo</code>；而标签没有顺序和层次。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>category:</span></div></div><div><div><div>2</div></div><div><span>- Diary</span></div></div><div><div><div>3</div></div><div><span>tags:</span></div></div><div><div><div>4</div></div><div><span>- PS3</span></div></div><div><div><div>5</div></div><div><span>- Games</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>分类方法的分歧</p><p>如果您有过使用 WordPress 的经验，就很容易误解 Hexo 的分类方式。WordPress 支持对一篇文章设置多个分类，而且这些分类可以是同级的，也可以是父子分类。但是 Hexo 不支持指定多个同级分类。下面的指定方法：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>category:</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>- Diary</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>- Life</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>会使分类 <code>Life</code> 成为 <code>Diary</code> 的子分类，而不是并列分类。因此，有必要为您的文章选择尽可能准确的分类。</p><p>如果你需要为文章添加多个分类，可以尝试以下 list 中的方法。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>category:</span></div></div><div><div><div>2</div></div><div><span>- [Diary, PlayStation]</span></div></div><div><div><div>3</div></div><div><span>- [Diary, Games]</span></div></div><div><div><div>4</div></div><div><span>- [Life]</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>此时这篇文章同时包括三个分类： <code>PlayStation</code> 和 <code>Games</code> 分别都是父分类 <code>Diary</code> 的子分类，同时 <code>Life</code> 是一个没有子分类的分类。</p></blockquote></section><section><h4>JSON Front-matter<a href="#json-front-matter"><span>#</span></a></h4><p>除了 YAML 外，你也可以使用 JSON 来编写 Front-matter，只要将 <code>---</code> 代换成 <code>;;;</code> 即可。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>"title": "Hello World",</span></div></div><div><div><div>2</div></div><div><span>"date": "2013/7/13 20:46:25"</span></div></div><div><div><div>3</div></div><div><span>;;;</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h3>标签插件（Tag Plugins）<a href="#标签插件tag-plugins"><span>#</span></a></h3><p>标签插件和 Front-matter 中的标签不同，它们是用于在文章中快速插入特定内容的插件。</p><p>虽然你可以使用任何格式书写你的文章，但是标签插件永远可用，且语法也都是一致的。</p><p><em>标签插件不应该被包裹在 Markdown 语法中，例如： <code>[]({% post_path lorem-ipsum %})</code> 是不被支持的。</em></p><section><h4>引用块<a href="#引用块"><span>#</span></a></h4><p>在文章中插入引言，可包含作者、来源和标题。</p><p><strong>别号：</strong> quote</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% blockquote [author[, source]] [link] [source_link_title] %}</span></div></div><div><div><div>2</div></div><div><span>content</span></div></div><div><div><div>3</div></div><div><span>{% endblockquote %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h5>示例<a href="#示例"><span>#</span></a></h5><p><strong>没有提供参数，则只输出普通的 blockquote</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% blockquote %}</span></div></div><div><div><div>2</div></div><div><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque hendrerit lacus ut purus iaculis feugiat. Sed nec tempor elit, quis aliquam neque. Curabitur sed diam eget dolor fermentum semper at eu lorem.</span></div></div><div><div><div>3</div></div><div><span>{% endblockquote %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque hendrerit lacus ut purus iaculis feugiat. Sed nec tempor elit, quis aliquam neque. Curabitur sed diam eget dolor fermentum semper at eu lorem.</p></blockquote><p><strong>引用书上的句子</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% blockquote David Levithan, Wide Awake %}</span></div></div><div><div><div>2</div></div><div><span>Do not just seek happiness for yourself. Seek happiness for all. Through kindness. Through mercy.</span></div></div><div><div><div>3</div></div><div><span>{% endblockquote %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>Do not just seek happiness for yourself. Seek happiness for all. Through kindness. Through mercy.</p><p><strong>David Levithan</strong>Wide Awake</p></blockquote><p><strong>引用 Twitter</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% blockquote @DevDocs https://twitter.com/devdocs/status/356095192085962752 %}</span></div></div><div><div><div>2</div></div><div><span>NEW: DevDocs now comes with syntax highlighting. http://devdocs.io</span></div></div><div><div><div>3</div></div><div><span>{% endblockquote %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>NEW: DevDocs now comes with syntax highlighting. <a href="http://devdocs.io/" target="_blank">http://devdocs.io</a></p><p><strong>@DevDocs</strong><a href="https://twitter.com/devdocs/status/356095192085962752" target="_blank">twitter.com/devdocs/status/356095192085962752</a></p></blockquote><p><strong>引用网络上的文章</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% blockquote Seth Godin http://sethgodin.typepad.com/seths_blog/2009/07/welcome-to-island-marketing.html Welcome to Island Marketing %}</span></div></div><div><div><div>2</div></div><div><span>Every interaction is both precious and an opportunity to delight.</span></div></div><div><div><div>3</div></div><div><span>{% endblockquote %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>Every interaction is both precious and an opportunity to delight.</p><p><strong>Seth Godin</strong><a href="http://sethgodin.typepad.com/seths_blog/2009/07/welcome-to-island-marketing.html" target="_blank">Welcome to Island Marketing</a></p></blockquote></section></section><section><h4>代码块<a href="#代码块"><span>#</span></a></h4><p>在文章中插入代码。</p><p><strong>别名：</strong> code</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% codeblock [title] [lang:language] [url] [link text] [additional options] %}</span></div></div><div><div><div>2</div></div><div><span>code snippet</span></div></div><div><div><div>3</div></div><div><span>{% endcodeblock %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>以 <code>option:value</code> 的格式指定额外选项，例如：<code>line_number:false first_line:5</code>。</p>

<table><thead><tr><th>额外选项</th><th>描述</th><th>默认值</th></tr></thead><tbody><tr><td><code>line_number</code></td><td>显示行号</td><td><code>true</code></td></tr><tr><td><code>line_threshold</code></td><td>只有代码块的行数超过该阈值，才显示行数</td><td><code>0</code></td></tr><tr><td><code>highlight</code></td><td>启用代码高亮</td><td><code>true</code></td></tr><tr><td><code>first_line</code></td><td>指定第一个行号</td><td><code>1</code></td></tr><tr><td><code>mark</code></td><td>突出显示特定的行，每个值用逗号分隔。 使用破折号指定数字范围 例如： <code>mark:1,4-7,10</code> 将标记第1、4至7和10行</td><td></td></tr><tr><td><code>wrap</code></td><td>用 <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table" target="_blank">“</a> 包裹代码块</td><td><code>true</code></td></tr></tbody></table><section><h5>示例<a href="#示例-1"><span>#</span></a></h5><p><strong>普通的代码块</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% codeblock %}</span></div></div><div><div><div>2</div></div><div><span>alert('Hello World!');</span></div></div><div><div><div>3</div></div><div><span>{% endcodeblock %}</span></div></div><div><div><div>4</div></div><div><span>alert('Hello World!');</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>指定语言</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% codeblock lang:objc %}</span></div></div><div><div><div>2</div></div><div><span>[rectangle setX: 10 y: 10 width: 20 height: 20];</span></div></div><div><div><div>3</div></div><div><span>{% endcodeblock %}</span></div></div><div><div><div>4</div></div><div><span>[rectangle setX: 10 y: 10 width: 20 height: 20];</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>附加说明</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% codeblock Array.map %}</span></div></div><div><div><div>2</div></div><div><span>array.map(callback[, thisArg])</span></div></div><div><div><div>3</div></div><div><span>{% endcodeblock %}</span></div></div><div><div><div>4</div></div><div><span>Array.maparray.map(callback[, thisArg])</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>附加说明和网址</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% codeblock _.compact http://underscorejs.org/#compact Underscore.js %}</span></div></div><div><div><div>2</div></div><div><span>_.compact([0, 1, false, 2, '', 3]);</span></div></div><div><div><div>3</div></div><div><span>=&gt; [1, 2, 3]</span></div></div><div><div><div>4</div></div><div><span>{% endcodeblock %}</span></div></div><div><div><div>5</div></div><div><span>_.compactUnderscore.js_.compact([0, 1, false, 2, '', 3]);</span></div></div><div><div><div>6</div></div><div><span>=&gt; [1, 2, 3]</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h4>反引号代码块<a href="#反引号代码块"><span>#</span></a></h4><p>另一种形式的代码块，不同的是它使用三个反引号来包裹。</p><p>``` [language] [title] [url] [link text] code snippet ```</p></section><section><h4>Pull Quote<a href="#pull-quote"><span>#</span></a></h4><p>在文章中插入 Pull quote。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% pullquote [class] %}</span></div></div><div><div><div>2</div></div><div><span>content</span></div></div><div><div><div>3</div></div><div><span>{% endpullquote %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>jsFiddle (<code>v7.0.0</code> 中被移除)<a href="#jsfiddle-v700-中被移除"><span>#</span></a></h4><blockquote><p>如果你正在使用 <code>v7.0.0+</code>，请使用 <a href="https://github.com/hexojs/hexo-tag-embed" target="_blank">hexo-tag-embed</a> 替代。</p></blockquote><p>在文章中嵌入 jsFiddle。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% jsfiddle shorttag [tabs] [skin] [width] [height] %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>Gist (<code>v7.0.0</code> 中被移除)<a href="#gist-v700-中被移除"><span>#</span></a></h4><blockquote><p>如果你正在使用 <code>v7.0.0+</code>，请使用 <a href="https://github.com/hexojs/hexo-tag-embed" target="_blank">hexo-tag-embed</a> 替代。</p></blockquote><p>在文章中嵌入 Gist。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% gist gist_id [filename] %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>iframe<a href="#iframe"><span>#</span></a></h4><p>在文章中插入 iframe。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% iframe url [width] [height] %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>Image<a href="#image"><span>#</span></a></h4><p>在文章中插入指定大小的图片。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% img [class names] /path/to/image [width] [height] '"title text" "alt text"' %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>Link<a href="#link"><span>#</span></a></h4><p>在文章中插入链接，并自动给外部链接添加 <code>target="_blank"</code> 属性。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% link text url [external] [title] %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>Include Code<a href="#include-code"><span>#</span></a></h4><p>插入 <code>source/downloads/code</code> 文件夹内的代码文件。<code>source/downloads/code</code> 不是固定的，取决于你在配置文件中 <code>code_dir</code> 的配置。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% include_code [title] [lang:language] [from:line] [to:line] path/to/file %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h5>示例<a href="#示例-2"><span>#</span></a></h5><p><strong>嵌入 test.js 文件全文</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% include_code lang:javascript test.js %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>只嵌入第 3 行</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% include_code lang:javascript from:3 to:3 test.js %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>嵌入第 5 行至第 8 行</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% include_code lang:javascript from:5 to:8 test.js %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>嵌入第 5 行至文件结束</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% include_code lang:javascript from:5 test.js %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>嵌入第 1 行至第 8 行</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% include_code lang:javascript to:8 test.js %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h4>Youtube (<code>v7.0.0</code> 中被移除)<a href="#youtube-v700-中被移除"><span>#</span></a></h4><blockquote><p>如果你正在使用 <code>v7.0.0+</code>，请使用 <a href="https://github.com/hexojs/hexo-tag-embed" target="_blank">hexo-tag-embed</a> 替代。</p></blockquote><p>在文章中插入 Youtube 视频。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% youtube video_id [type] [cookie] %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h5>示例<a href="#示例-3"><span>#</span></a></h5><p><strong>视频</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% youtube lJIrF4YjHfQ %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>播放列表</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% youtube PL9hW1uS6HUfscJ9DHkOSoOX45MjXduUxo 'playlist' %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>隐私模式</strong></p><p>在这种模式下，禁用 YouTube cookie</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% youtube lJIrF4YjHfQ false %}</span></div></div><div><div><div>2</div></div><div><span>{% youtube PL9hW1uS6HUfscJ9DHkOSoOX45MjXduUxo 'playlist' false %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h4>Vimeo (<code>v7.0.0</code> 中被移除)<a href="#vimeo-v700-中被移除"><span>#</span></a></h4><blockquote><p>如果你正在使用 <code>v7.0.0+</code>，请使用 <a href="https://github.com/hexojs/hexo-tag-embed" target="_blank">hexo-tag-embed</a> 替代。</p></blockquote><p>在文章中插入 Vimeo 视频。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% vimeo video_id %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>引用文章<a href="#引用文章"><span>#</span></a></h4><p>引用其他文章的链接。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% post_path filename %}</span></div></div><div><div><div>2</div></div><div><span>{% post_link filename [title] [escape] %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在使用此标签时可以忽略文章文件所在的路径或者文章的永久链接信息、如语言、日期。</p><p>例如，在文章中使用 <code>{% post_link how-to-bake-a-cake %}</code> 时，只需有一个名为 <code>how-to-bake-a-cake.md</code> 的文章文件即可。即使这个文件位于站点文件夹的 <code>source/posts/2015-02-my-family-holiday</code> 目录下、或者文章的永久链接是 <code>2018/en/how-to-bake-a-cake</code>，都没有影响。</p><p>默认链接文字是文章的标题，你也可以自定义要显示的文本。</p><p>默认对文章的标题和自定义标题里的特殊字符进行转义。可以使用 <code>escape</code> 选项，禁止对特殊字符进行转义。</p><p>例如：</p><p><strong>链接使用文章的标题</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% post_link hexo-3-8-released %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><a href="https://hexo.io/news/2018/10/19/hexo-3-8-released/" target="_blank">Hexo 3.8.0 Released</a></p><p><strong>链接使用自定义文字</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% post_link hexo-3-8-released '通往文章的链接' %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><a href="https://hexo.io/news/2018/10/19/hexo-3-8-released/" target="_blank">通往文章的链接</a></p><p><strong>对标题的特殊字符进行转义</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% post_link hexo-4-released 'How to use &lt;b&gt; tag in title' %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><a href="https://hexo.io/news/2019/10/14/hexo-4-released/" target="_blank">How to use  tag in title</a></p><p><strong>禁止对标题的特殊字符进行转义</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% post_link hexo-4-released '&lt;b&gt;bold&lt;/b&gt; custom title' false %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><a href="https://hexo.io/news/2019/10/14/hexo-4-released/" target="_blank"><strong>bold</strong> custom title</a></p></section><section><h4>引用资源<a href="#引用资源"><span>#</span></a></h4><p>引用文章的资源，与 <a href="https://hexo.io/zh-cn/docs/asset-folders" target="_blank">资源文件夹</a> 一起使用。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% asset_path filename %}</span></div></div><div><div><div>2</div></div><div><span>{% asset_img [class names] slug [width] [height] [title text [alt text]] %}</span></div></div><div><div><div>3</div></div><div><span>{% asset_link filename [title] [escape] %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>嵌入图片<a href="#嵌入图片"><span>#</span></a></h4><p><em>hexo-renderer-marked 3.1.0+ 可以（可选）自动解析图片的文章路径，参考 <a href="https://hexo.io/zh-cn/docs/asset-folders#%E4%BD%BF%E7%94%A8-Markdown-%E5%B5%8C%E5%85%A5%E5%9B%BE%E7%89%87" target="_blank">本节</a> 如何启用它。</em></p><p>“foo.jpg” 位于 <code>http://example.com/2020/01/02/hello/foo.jpg</code>。</p><p><strong>默认（无选项）</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% asset_img foo.jpg %}</span></div></div><div><div><div>2</div></div><div><span>&lt;img src="/2020/01/02/hello/foo.jpg"&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>自定义 class 属性</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% asset_img post-image foo.jpg %}</span></div></div><div><div><div>2</div></div><div><span>&lt;img src="/2020/01/02/hello/foo.jpg" class="post-image"&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>展示尺寸</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% asset_img foo.jpg 500 400 %}</span></div></div><div><div><div>2</div></div><div><span>&lt;img src="/2020/01/02/hello/foo.jpg" width="500" height="400"&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>title 和 alt 属性</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% asset_img logo.svg "lorem ipsum'dolor'" %}</span></div></div><div><div><div>2</div></div><div><span>&lt;img src="/2020/01/02/hello/foo.jpg" title="lorem ipsum" alt="dolor"&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>URL<a href="#url"><span>#</span></a></h4><section><h5>url_for (7.0.0+)<a href="#url_for-700"><span>#</span></a></h5><p>返回一个带有根路径前缀的URL。输出将会自动编码。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% url_for text path [relative] %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>示例：</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>_config.yml</span></div></div><div><div><div>2</div></div><div><span>root: /blog/ # example</span></div></div><div><div><div>3</div></div><div><span>{% url_for blog index.html %}</span></div></div><div><div><div>4</div></div><div><span>&lt;a href="/blog/index.html"&gt;blog&lt;/a&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>是否输出相对链接，默认遵循配置文件中 <code>relative_link</code> 的值
例如， post/page 的路径值可能是 <code>/foo/bar/index.html</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>_config.yml</span></div></div><div><div><div>2</div></div><div><span>relative_link: true</span></div></div><div><div><div>3</div></div><div><span>{% url_for blog index.html %}</span></div></div><div><div><div>4</div></div><div><span>&lt;a href="../../index.html"&gt;blog&lt;/a&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>即使配置文件中启用了 <code>relative_link</code>，你也可以使用 <code>relative</code> 参数禁用相对链接输出，反之亦然</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% url_for blog index.html false %}</span></div></div><div><div><div>2</div></div><div><span>&lt;a href="/index.html"&gt;blog&lt;/a&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h5>full_url_for (7.0.0+)<a href="#full_url_for-700"><span>#</span></a></h5><p>返回一个以 <code>config.url</code> 为前缀的URL。输出将会自动编码。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% full_url_for text path %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>示例：</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>_config.yml</span></div></div><div><div><div>2</div></div><div><span>url: https://example.com/blog # example</span></div></div><div><div><div>3</div></div><div><span>{% full_url_for index /a/path %}</span></div></div><div><div><div>4</div></div><div><span>&lt;a href="https://example.com/blog/a/path"&gt;index&lt;/a&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h4>Raw<a href="#raw"><span>#</span></a></h4><p>如果您想在文章中插入 Swig 标签，可以尝试使用 Raw 标签，以免发生解析异常。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% raw %}</span></div></div><div><div><div>2</div></div><div><span>content</span></div></div><div><div><div>3</div></div><div><span>{% endraw %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>文章摘要和截断<a href="#文章摘要和截断"><span>#</span></a></h4><p>在文章中使用 <code>&lt;!-- more --&gt;</code>，那么 <code>&lt;!-- more --&gt;</code> 之前的文字将会被视为摘要。首页中将只出现这部分文字，同时这部分文字也会出现在正文之中。</p><p>例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</span></div></div><div><div><div>2</div></div><div><span>&lt;!-- more --&gt;</span></div></div><div><div><div>3</div></div><div><span>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>首页中将只会出现</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>正文中则会出现</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>注意，摘要可能会被 Front Matter 中的 <code>excerpt</code> 覆盖。</p></section></section><section><h3>资源文件夹<a href="#资源文件夹"><span>#</span></a></h3><section><h4>全局资源文件夹<a href="#全局资源文件夹"><span>#</span></a></h4><p>资源（Asset）代表 <code>source</code> 文件夹中除了文章以外的所有文件，例如图片、CSS、JS 文件等。比方说，如果你的Hexo项目中只有少量图片，那最简单的方法就是将它们放在 <code>source/images</code> 文件夹中。然后通过类似于 <code>![](/images/image.jpg)</code> 的方法访问它们。</p></section><section><h4>文章资源文件夹<a href="#文章资源文件夹"><span>#</span></a></h4><p>对于那些想要更有规律地提供图片和其他资源以及想要将他们的资源分布在各个文章上的人来说，Hexo也提供了更组织化的方式来管理资源。这个稍微有些复杂但是管理资源非常方便的功能可以通过将 <code>config.yml</code> 文件中的 <code>post_asset_folder</code> 选项设为 <code>true</code> 来打开。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>_config.ymlpost_asset_folder: true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>当资源文件管理功能打开后，Hexo将会在你每一次通过 <code>hexo new [layout] &lt;title&gt;</code> 命令创建新文章时自动创建一个文件夹。这个资源文件夹将会有与这个文章文件一样的名字。将所有与你的文章有关的资源放在这个关联文件夹中之后，你可以通过相对路径来引用它们，这样你就得到了一个更简单而且方便得多的工作流。</p></section><section><h4>相对路径引用的标签插件<a href="#相对路径引用的标签插件"><span>#</span></a></h4><p>通过常规的 markdown 语法和相对路径来引用图片和其它资源可能会导致它们在存档页或者主页上显示不正确。在Hexo 2时代，社区创建了很多插件来解决这个问题。但是，随着Hexo 3 的发布，许多新的<a href="https://hexo.io/zh-cn/docs/tag-plugins#%E5%BC%95%E7%94%A8%E8%B5%84%E6%BA%90" target="_blank">标签插件</a>被加入到了核心代码中。这使得你可以更简单地在文章中引用你的资源。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% asset_path slug %}</span></div></div><div><div><div>2</div></div><div><span>{% asset_img slug [title] %}</span></div></div><div><div><div>3</div></div><div><span>{% asset_link slug [title] %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>比如说：当你打开文章资源文件夹功能后，你把一个 <code>example.jpg</code> 图片放在了你的资源文件夹中，如果通过使用相对路径的常规 markdown 语法 <code>![](example.jpg)</code> ，它将 <em>不会</em> 出现在首页上。（但是它会在文章中按你期待的方式工作）</p><p>正确的引用图片方式是使用下列的标签插件而不是 markdown ：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{% asset_img example.jpg This is an example image %}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>通过这种方式，图片将会同时出现在文章和主页以及归档页中。</p></section><section><h4>使用 Markdown 嵌入图片<a href="#使用-markdown-嵌入图片"><span>#</span></a></h4><p><a href="https://github.com/hexojs/hexo-renderer-marked" target="_blank">hexo-renderer-marked</a> 3.1.0 引入了一个新的选项，其允许你无需使用 <code>asset_img</code> 标签插件就可以在 markdown 中嵌入图片</p><p>如需启用：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>_config.ymlpost_asset_folder: true</span></div></div><div><div><div>2</div></div><div><span>marked:</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>prependRoot: true</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>postAsset: true</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>启用后，资源图片将会被自动解析为其对应文章的路径。
例如： <code>image.jpg</code> 位置为 <code>/2020/01/02/foo/image.jpg</code> ，这表示它是 <code>/2020/01/02/foo/</code> 文章的一张资源图片， <code>![](image.jpg)</code> 将会被解析为 <code>&lt;img src="/2020/01/02/foo/image.jpg"&gt;</code> 。</p></section></section><section><h3>数据文件<a href="#数据文件"><span>#</span></a></h3><p>有时您可能需要在主题中使用某些数据，而这些数据并不在文章内，并且是需要重复使用的，那么您可以考虑使用 Hexo 3.0 新增的「数据文件」功能。此功能会加载 <code>source/_data</code> 内的 YAML 或 JSON 文件，如此一来您便能在网站中复用这些文件了。</p><p>举例来说，在 <code>source/_data</code> 文件夹中新建 <code>menu.yml</code> 文件：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Home: /</span></div></div><div><div><div>2</div></div><div><span>Gallery: /gallery/</span></div></div><div><div><div>3</div></div><div><span>Archives: /archives/</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>您就能在模板中使用这些数据：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;% for (var link in site.data.menu) { %&gt;</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>&lt;a href="&lt;%= site.data.menu[link] %&gt;"&gt; &lt;%= link %&gt; &lt;/a&gt;</span></div></div><div><div><div>3</div></div><div><span>&lt;% } %&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>渲染结果如下 :</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;a href="/"&gt; Home &lt;/a&gt;</span></div></div><div><div><div>2</div></div><div><span>&lt;a href="/gallery/"&gt; Gallery &lt;/a&gt;</span></div></div><div><div><div>3</div></div><div><span>&lt;a href="/archives/"&gt; Archives &lt;/a&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>服务器<a href="#服务器"><span>#</span></a></h3><section><h4><a href="https://github.com/hexojs/hexo-server" target="_blank">hexo-server</a><a href="#hexo-server"><span>#</span></a></h4><p>Hexo 3.0 把服务器独立成了个别模块，您必须先安装 <a href="https://github.com/hexojs/hexo-server" target="_blank">hexo-server</a> 才能使用。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>$ npm install hexo-server --save</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>安装完成后，输入以下命令以启动服务器，您的网站会在 <code>http://localhost:4000</code> 下启动。在服务器启动期间，Hexo 会监视文件变动并自动更新，您无须重启服务器。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>$ hexo server</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果您想要更改端口，或是在执行时遇到了 <code>EADDRINUSE</code> 错误，可以在执行时使用 <code>-p</code> 选项指定其他端口，如下：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>$ hexo server -p 5000</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>静态模式<a href="#静态模式"><span>#</span></a></h4><p>在静态模式下，服务器只处理 <code>public</code> 文件夹内的文件，而不会处理文件变动，在执行时，您应该先自行执行 <code>hexo generate</code>，此模式通常用于生产环境（production mode）下。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>$ hexo server -s</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>自定义 IP<a href="#自定义-ip"><span>#</span></a></h4><p>服务器默认运行在 <code>0.0.0.0</code>，您可以覆盖默认的 IP 设置，如下：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>$ hexo server -i 192.168.1.1</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>指定这个参数后，您就只能通过该IP才能访问站点。例如，对于一台使用无线网络的笔记本电脑，除了指向本机的<code>127.0.0.1</code>外，通常还有一个<code>192.168.*.*</code>的局域网IP，如果像上面那样使用<code>-i</code>参数，就不能用<code>127.0.0.1</code>来访问站点了。对于有公网IP的主机，如果您指定一个局域网IP作为<code>-i</code>参数的值，那么就无法通过公网来访问站点。</p></section></section><section><h3>生成文件<a href="#生成文件"><span>#</span></a></h3><p>使用 Hexo 生成静态文件快速而且简单。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>$ hexo generate</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h4>监视文件变动<a href="#监视文件变动"><span>#</span></a></h4><p>Hexo 能够监视文件变动并立即重新生成静态文件，在生成时会比对文件的 SHA1 checksum，只有变动的文件才会写入。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>$ hexo generate --watch</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>完成后部署<a href="#完成后部署"><span>#</span></a></h4><p>您可执行下列的其中一个命令，让 Hexo 在生成完毕后自动部署网站，两个命令的作用是相同的。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>$ hexo generate --deploy</span></div></div><div><div><div>2</div></div><div><span>$ hexo deploy --generate</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>简写</p><p>上面两个命令可以简写为
<span><span>hexog−dhexo g -d</span><span><span><span></span><span>h</span><span>e</span><span>x</span><span>o</span><span>g</span><span></span><span>−</span><span></span></span><span><span></span><span>d</span></span></span></span> hexo d -g</p></blockquote><blockquote><p><strong>注意： 推送操作需要完成以下配置后才可以执行</strong></p></blockquote><ol>
<li>推送网站的相关配置 编辑博客根目录下的 <code>_config.yml</code> , 修改 <code>deploy</code> 项，在文件最后</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span> </span><span># 以下格式可能不符，请主动修改</span></div></div><div><div><div>2</div></div><div><span> </span><span>deploy</span></div></div><div><div><div>3</div></div><div><span>   </span><span>type</span><span>: </span><span>git</span></div></div><div><div><div>4</div></div><div><span>   </span><span>repo</span><span>: </span><span>git@github.com:用户名/仓库名.git</span><span> </span><span># 仓库地址</span></div></div><div><div><div>5</div></div><div><span>   </span><span>branch</span><span>: </span><span>master</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>安装 Git 部署插件，输入命令 npm i hexo-deployer-git —save</li>
<li>此时已经配置完毕，可以使用 hexo d 进行推送</li>
</ol></section></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/guide/firefly-wiki-link/</id>
      <title type="text">Firefly Wiki Link 内部链接示例</title>
      <published>1970-01-03T00:00:00.000Z</published>
      <updated>1970-01-03T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/guide/firefly-wiki-link/"/>
      <summary type="text">在 Firefly 文章中使用 Obsidian 风格的 Wiki Link 内部链接，并自动生成文章链接卡片。</summary>
      <content type="html"><![CDATA[<p>Firefly 支持在 Markdown、MDX 文章中使用 Obsidian 风格的 Wiki Link 内部链接。链接目标填写文章的 slug 或文件路径，都不需要包含扩展名，具体匹配规则见下文「链接目标的三种写法」。</p>
<section><h2>文章链接卡片<a href="#文章链接卡片"><span>#</span></a></h2><p><code>[[slug]]</code> 单独成段时，会自动读取目标文章的标题、描述、发布时间、分类、标签和封面，渲染为链接卡片：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[</span><span>[</span><span>firefly</span><span>]</span><span>]</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>[</span><span>[</span><span>guide/index</span><span>]</span><span>]</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>[</span><span>[</span><span>markdown-extended</span><span>]</span><span>]</span></div></div></code></pre><div><div></div><div></div></div></figure></div><a href="/posts/firefly/"><div><div>Firefly 一款清新美观的 Astro 博客主题模板</div><div>Firefly 是一款基于 Astro 框架和 Fuwari 模板开发的清新美观且现代化个人博客主题模板，专为技术爱好者和内容创作者设计。该主题融合了现代 Web 技术栈，提供了丰富的功能模块和高度可定制的界面，让您能够轻松打造出专业且美观的个人博客网站。</div><div><span>1970-01-01</span><span>Firefly</span><span><span>#Markdown</span><span>#Firefly</span><span>#博客</span><span>#主题</span><span>#模板</span></span></div></div><div><img alt="" loading="lazy" width="480" height="259" src="/_astro/firefly2.dxmXG905_Z2o5m8L.webp" /></div></a><a href="/posts/guide/"><div><div>Firefly 简单使用指南</div><div>如何使用 Firefly 博客模板。</div><div><span>1970-01-02</span><span>Firefly</span><span><span>#Firefly</span><span>#博客</span><span>#Markdown</span><span>#指南</span></span></div></div><div><img alt="" loading="lazy" width="480" height="270" src="/_astro/cover.bDPQizdp_C8GFs.webp" /></div></a><a href="/posts/markdown-extended/"><div><div>Markdown 扩展功能</div><div>了解 Firefly 中的 Markdown 功能</div><div><span>1970-01-01</span><span>Firefly</span><span><span>#演示</span><span>#示例</span><span>#Markdown</span><span>#Firefly</span></span></div></div></a></section>
<section><h2>行内链接<a href="#行内链接"><span>#</span></a></h2><p><code>[[slug]]</code> 出现在正文中间时，渲染为普通链接，链接文字自动使用目标文章的标题</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>请参阅 [</span><span>[</span><span>firefly</span><span>]</span><span>] 了解主题特性。</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>请参阅 <a href="/posts/firefly/">Firefly 一款清新美观的 Astro 博客主题模板</a> 了解主题特性。</p></section>
<section><h2>自定义显示标题<a href="#自定义显示标题"><span>#</span></a></h2><p>在 <code>|</code> 后填写链接的显示文字。行内链接会用它替换文章标题；单独成段时依然渲染为卡片，卡片标题使用自定义文字，描述、时间、分类、标签和封面仍然读取目标文章：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>请参阅 [</span><span>[</span><span>firefly|主题介绍</span><span>]</span><span>] 了解主题特性。</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>[[firefly|Firefly 主题介绍]]</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>请参阅 <a href="/posts/firefly/">主题介绍</a> 了解主题特性。</p><a href="/posts/firefly/"><div><div>Firefly 主题介绍</div><div>Firefly 是一款基于 Astro 框架和 Fuwari 模板开发的清新美观且现代化个人博客主题模板，专为技术爱好者和内容创作者设计。该主题融合了现代 Web 技术栈，提供了丰富的功能模块和高度可定制的界面，让您能够轻松打造出专业且美观的个人博客网站。</div><div><span>1970-01-01</span><span>Firefly</span><span><span>#Markdown</span><span>#Firefly</span><span>#博客</span><span>#主题</span><span>#模板</span></span></div></div><div><img alt="" loading="lazy" width="480" height="259" src="/_astro/firefly2.dxmXG905_Z2o5m8L.webp" /></div></a><p>一个例外：如果 <code>|</code> 后的文字只是把链接目标又抄了一遍（<code>[[guide/index|index]]</code>），会被当作无效别名忽略，仍然显示文章标题。Obsidian 在插入的链接时会自动补上这样的别名，避免笔记里显示一长串路径，这个例外就是为它准备的。</p></section>
<section><h2>链接目标的三种写法<a href="#链接目标的三种写法"><span>#</span></a></h2><p>用 Obsidian 管理文章时，把 <code>src/content/posts</code> 目录本身作为 Obsidian 仓库（vault）打开。下文提到的「仓库根目录」都指这个目录，它正好也是 Firefly 解析链接路径的起点。</p><p>链接目标按以下顺序匹配：</p>

<table><thead><tr><th>写法</th><th>示例</th><th>在 Obsidian 中</th></tr></thead><tbody><tr><td>frontmatter 的 <code>slug</code></td><td><code>[[firefly-wiki-link]]</code></td><td>✗ 不支持</td></tr><tr><td>文件路径（相对仓库根目录）</td><td><code>[[guide/firefly-layout-system]]</code></td><td>✓ 需改设置（推荐）</td></tr><tr><td>裸文件名（仓库内唯一时）</td><td><code>[[firefly-layout-system]]</code></td><td>✓ 默认即是</td></tr></tbody></table><section><h3>第一种：slug<a href="#第一种slug"><span>#</span></a></h3><p><code>slug</code> 写法在 Obsidian 中不支持，<code>slug</code> 是 Firefly 自己的概念，Obsidian 不读取 frontmatter 里的 <code>slug</code>，所以按 slug 写的链接在 Obsidian 里既不会自动补全，也点不动，只有构建出的站点上能正常跳转。如果你主要在 Obsidian 里写作，用下面两种写法。</p></section><section><h3>第二种：文件路径（推荐）<a href="#第二种文件路径推荐"><span>#</span></a></h3><p>文件路径写法需要改 Obsidian 设置，在 <code>设置 → 文件与链接 → 链接 → 内部链接类型</code> 中选择<strong>基于仓库根目录的绝对路径</strong>，Obsidian 插入的链接才会带上目录：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[</span><span>[</span><span>guide/firefly-layout-system|firefly-layout-system</span><span>]</span><span>]</span></div></div></code></pre><div><div></div><div></div></div></figure></div><a href="/posts/guide/firefly-layout-system/"><div><div>Firefly 布局系统详解</div><div>深入了解 Firefly 的布局系统，包括侧边栏布局（左侧/双侧）和文章列表布局（列表/网格），以及自适应网格列数。</div><div><span>1970-01-01</span><span>Firefly</span><span><span>#Firefly</span><span>#布局</span><span>#博客</span><span>#指南</span></span></div></div><div><img alt="" loading="lazy" width="480" height="270" src="/_astro/firefly1.CZCuCN4V_1uGCKh.webp" /></div></a><p>因为仓库根目录就是 <code>src/content/posts</code>，Obsidian 写出的这个路径和 Firefly 需要的路径完全一致，不需要任何额外转换。</p><p>上面这行末尾的 <code>|firefly-layout-system</code> 是 Obsidian 自动补的别名，Firefly 会忽略它，卡片标题仍然取文章的 title，除非你把它修改和文件名不一致，才会变成你修改后的别名。</p><p>内部链接类型下拉框里的<strong>基于当前笔记的相对路径</strong>只在同目录内可用：它给同目录文章生成的是裸文件名，能正常匹配；但跨目录时会生成 <code>../</code> 前缀，Firefly 无法解析，链接会按原文显示。</p></section><section><h3>第三种：裸文件名<a href="#第三种裸文件名"><span>#</span></a></h3><p>「内部链接类型」的默认值就是<strong>尽可能简短的形式</strong>：只要文件名在整个仓库里唯一，Obsidian 插入的链接就只有文件名，不带目录。这种写法不需要改任何设置，效果和写完整路径完全一致：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[</span><span>[</span><span>firefly-layout-system</span><span>]</span><span>]</span></div></div></code></pre><div><div></div><div></div></div></figure></div><a href="/posts/guide/firefly-layout-system/"><div><div>Firefly 布局系统详解</div><div>深入了解 Firefly 的布局系统，包括侧边栏布局（左侧/双侧）和文章列表布局（列表/网格），以及自适应网格列数。</div><div><span>1970-01-01</span><span>Firefly</span><span><span>#Firefly</span><span>#布局</span><span>#博客</span><span>#指南</span></span></div></div><div><img alt="" loading="lazy" width="480" height="270" src="/_astro/firefly1.CZCuCN4V_1uGCKh.webp" /></div></a><p>文件名重名时这种写法会失效，构建日志里会给出提示，改用完整文件路径即可，所以推荐直接修改 Obsidian 内部链接类型设置为<strong>基于仓库根目录的绝对路径</strong>，使用第二种文件路径写法，一劳永逸</p></section></section>
<section><h2>链接到其他文章的标题<a href="#链接到其他文章的标题"><span>#</span></a></h2><p>在文章 slug 后添加 <code>#标题</code>。带标题锚点的链接始终渲染为普通链接：</p><p><a href="/posts/code-examples/#%E8%AF%AD%E6%B3%95%E9%AB%98%E4%BA%AE">查看代码块语法高亮</a></p><p><a href="/posts/guide/firefly-layout-system/#%E7%9B%B8%E5%85%B3%E9%93%BE%E6%8E%A5">Firefly 布局系统详解#相关链接</a></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[</span><span>[</span><span>code-examples#语法高亮|查看代码块语法高亮</span><span>]</span><span>]</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>[</span><span>[</span><span>guide/firefly-layout-system#相关链接|firefly-layout-system</span><span>]</span><span>]</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>标题锚点使用与页面标题相同的 slug 规则，因此中文、空格和大小写都会按页面实际生成的 ID 处理。</p></section>
<section><h2>链接到本页标题<a href="#链接到本页标题"><span>#</span></a></h2><p>省略文章 slug，只填写标题即可链接到当前文章：</p><p><a href="#%E6%9C%AC%E9%A1%B5%E7%9B%AE%E6%A0%87">跳转到本页目标</a></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[</span><span>[</span><span>#本页目标|跳转到本页目标</span><span>]</span><span>]</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>本页目标<a href="#本页目标"><span>#</span></a></h2><p>这是本页 Wiki Link 指向的标题。</p></section>
<section><h2>不支持附件嵌入<a href="#不支持附件嵌入"><span>#</span></a></h2><p>附件嵌入语法目前不会被转换，会按原文显示：</p><p>![[image.png]]</p><p>行内代码和代码块中的 <code>[[firefly]]</code> 也不会被转换。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/guide/</id>
      <title type="text">Firefly 简单使用指南</title>
      <published>1970-01-02T00:00:00.000Z</published>
      <updated>1970-01-02T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/guide/"/>
      <summary type="text">如何使用 Firefly 博客模板。</summary>
      <content type="html"><![CDATA[<p>这个博客模板是基于 <a href="https://astro.build/" target="_blank">Astro</a> 构建的。对于本指南中未提及的内容，您可以在 <a href="https://docs.astro.build/" target="_blank">Astro 文档</a> 中找到答案。</p>
<section><h2>文章的 Front-matter<a href="#文章的-front-matter"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>我的第一篇博客文章</span></div></div><div><div><div>3</div></div><div><span>published</span><span>: </span><span>2023-09-09</span></div></div><div><div><div>4</div></div><div><span>description</span><span>: </span><span>这是我新 Astro 博客的第一篇文章。</span></div></div><div><div><div>5</div></div><div><span>image</span><span>: </span><span>./cover.jpg</span></div></div><div><div><div>6</div></div><div><span>tags</span><span>: [</span><span>前端</span><span>, </span><span>开发</span><span>]</span></div></div><div><div><div>7</div></div><div><span>category</span><span>: </span><span>前端开发</span></div></div><div><div><div>8</div></div><div><span>draft</span><span>: </span><span>false</span></div></div><div><div><div>9</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div>

<table><thead><tr><th>属性</th><th>描述</th></tr></thead><tbody><tr><td><code>title</code></td><td>文章标题。</td></tr><tr><td><code>published</code></td><td>文章发布日期。</td></tr><tr><td><code>updated</code></td><td>文章更新日期。如果未设置，将默认使用发布日期。</td></tr><tr><td><code>pinned</code></td><td>是否将此文章置顶在文章列表顶部。</td></tr><tr><td><code>description</code></td><td>文章的简短描述。显示在首页上。</td></tr><tr><td><code>image</code></td><td>文章封面图片路径。<br />1. 以 <code>http://</code> 或 <code>https://</code> 开头：使用网络图片<br />2. 以 <code>/</code> 开头：<code>public</code> 目录中的图片<br />3. 不带任何前缀：相对于 markdown 文件的路径</td></tr><tr><td><code>tags</code></td><td>文章标签。</td></tr><tr><td><code>category</code></td><td>文章分类。</td></tr><tr><td><code>lang</code></td><td>文章语言代码（如 <code>zh-CN</code>）。仅当文章语言与站点默认语言不同时设置。</td></tr><tr><td><code>licenseName</code></td><td>文章内容的许可证名称。</td></tr><tr><td><code>licenseUrl</code></td><td>文章内容的许可证链接。</td></tr><tr><td><code>author</code></td><td>文章作者。</td></tr><tr><td><code>sourceLink</code></td><td>文章内容的来源链接或参考。</td></tr><tr><td><code>draft</code></td><td>如果这篇文章仍是草稿，则不会显示。</td></tr><tr><td><code>comment</code></td><td>是否启用此文章的评论功能。默认为 <code>true</code>。</td></tr><tr><td><code>slug</code></td><td>自定义文章 URL 路径。如果不设置，将使用文件名作为 URL。</td></tr><tr><td><code>password</code></td><td>文章密码。设置后文章内容将被 AES-256-GCM 加密，访客需输入密码才能查看。</td></tr><tr><td><code>passwordHint</code></td><td>密码提示。显示在密码输入框上方，帮助访客回忆密码，也可以不加。</td></tr></tbody></table></section>
<section><h2>文章文件的放置位置<a href="#文章文件的放置位置"><span>#</span></a></h2><p>您的文章文件应放置在 <code>src/content/posts/</code> 目录中。您也可以创建子目录来更好地组织您的文章和资源。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>src/content/posts/</span></div></div><div><div><div>2</div></div><div><span>├── post-1.md</span></div></div><div><div><div>3</div></div><div><span>└── post-2/</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>├── cover.png</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>└── index.md</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>自定义文章 URL (Slug)<a href="#自定义文章-url-slug"><span>#</span></a></h2><section><h3>什么是 Slug？<a href="#什么是-slug"><span>#</span></a></h3><p>Slug 是文章 URL 路径的自定义部分。如果不设置 slug，系统将使用文件名作为 URL。</p></section><section><h3>Slug 使用示例<a href="#slug-使用示例"><span>#</span></a></h3><section><h4>示例 1：使用文件名作为 URL<a href="#示例-1使用文件名作为-url"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>我的第一篇博客文章</span></div></div><div><div><div>3</div></div><div><span>published</span><span>: </span><span>2023-09-09</span></div></div><div><div><div>4</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>文件：<code>src/content/posts/my-first-blog-post.md</code></p><p>URL：<code>/posts/my-first-blog-post</code></p></section><section><h4>示例 2：自定义 Slug<a href="#示例-2自定义-slug"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>我的第一篇博客文章</span></div></div><div><div><div>3</div></div><div><span>published</span><span>: </span><span>2023-09-09</span></div></div><div><div><div>4</div></div><div><span>slug</span><span>: </span><span>hello-world</span></div></div><div><div><div>5</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>文件：<code>src/content/posts/my-first-blog-post.md</code></p><p>URL：<code>/posts/hello-world</code></p></section><section><h4>示例 3：其他语言文件名使用Slug<a href="#示例-3其他语言文件名使用slug"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>如何使用 Firefly 博客主题</span></div></div><div><div><div>3</div></div><div><span>published</span><span>: </span><span>2023-09-09</span></div></div><div><div><div>4</div></div><div><span>slug</span><span>: </span><span>how-to-use-firefly-blog-theme</span></div></div><div><div><div>5</div></div><div><span>---</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>文件：<code>src/content/posts/如何使用Firefly博客主题.md</code></p><p>URL：<code>/posts/how-to-use-firefly-blog-theme</code></p></section></section><section><h3>Slug 使用建议<a href="#slug-使用建议"><span>#</span></a></h3><ol>
<li><strong>使用英文和连字符</strong>：<code>my-awesome-post</code> 而不是 <code>my awesome post</code></li>
<li><strong>保持简洁</strong>：避免过长的 slug</li>
<li><strong>具有描述性</strong>：让 URL 能够反映文章内容</li>
<li><strong>避免特殊字符</strong>：只使用字母、数字和连字符</li>
<li><strong>保持一致性</strong>：在整个博客中使用相似的命名模式</li>
</ol></section><section><h3>注意事项<a href="#注意事项"><span>#</span></a></h3><ul>
<li>Slug 一旦设置并发布，建议不要随意更改，以免影响 SEO 和已存在的链接</li>
<li>如果多个文章使用相同的 slug，后面的文章会覆盖前面的</li>
<li>Slug 会自动转换为小写</li>
</ul></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/code-examples/</id>
      <title type="text">Firefly 代码块示例</title>
      <published>1970-01-01T00:00:00.000Z</published>
      <updated>1970-01-01T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/code-examples/"/>
      <summary type="text">在Firefly中使用表达性代码的代码块在 Markdown 中的外观。</summary>
      <content type="html"><![CDATA[<p>在这里，我们将探索如何使用 <a href="https://expressive-code.com/" target="_blank">Expressive Code</a> 展示代码块。提供的示例基于官方文档，您可以参考以获取更多详细信息。</p>
<section><h2>表达性代码<a href="#表达性代码"><span>#</span></a></h2><section><h3>语法高亮<a href="#语法高亮"><span>#</span></a></h3><p><a href="https://expressive-code.com/key-features/syntax-highlighting/" target="_blank">语法高亮</a></p><section><h4>常规语法高亮<a href="#常规语法高亮"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>console</span><span>.</span></span><span>log</span><span>(</span><span>'此代码有语法高亮!'</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>渲染 ANSI 转义序列<a href="#渲染-ansi-转义序列"><span>#</span></a></h4><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>Standard ANSI colors:</span></div></div><div><div><div>2</div></div><div><span>- Dimmed:     </span><span> Black </span><span> Red </span><span> Green </span><span> Yellow </span><span> Blue </span><span> Magenta </span><span> Cyan </span><span> White </span></div></div><div><div><div>3</div></div><div><span>- Foreground: </span><span> Black </span><span> Red </span><span> Green </span><span> Yellow </span><span> Blue </span><span> Magenta </span><span> Cyan </span><span> White </span></div></div><div><div><div>4</div></div><div><span>- Background: </span><span> Black </span><span> Red </span><span> Green </span><span> Yellow </span><span> Blue </span><span> Magenta </span><span> Cyan </span><span> White </span></div></div><div><div><div>5</div></div><div><span>- Reversed:   </span><span> Black </span><span> Red </span><span> Green </span><span> Yellow </span><span> Blue </span><span> Magenta </span><span> Cyan </span><span> White </span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>8-bit colors (showing colors 160-171 as an example):</span></div></div><div><div><div>8</div></div><div><span>- Dimmed:     </span><span> 160 </span><span> 161 </span><span> 162 </span><span> 163 </span><span> 164 </span><span> 165 </span><span> 166 </span><span> 167 </span><span> 168 </span><span> 169 </span><span> 170 </span><span> 171 </span></div></div><div><div><div>9</div></div><div><span>- Foreground: </span><span> 160 </span><span> 161 </span><span> 162 </span><span> 163 </span><span> 164 </span><span> 165 </span><span> 166 </span><span> 167 </span><span> 168 </span><span> 169 </span><span> 170 </span><span> 171 </span></div></div><div><div><div>10</div></div><div><span>- Background: </span><span> 160 </span><span> 161 </span><span> 162 </span><span> 163 </span><span> 164 </span><span> 165 </span><span> 166 </span><span> 167 </span><span> 168 </span><span> 169 </span><span> 170 </span><span> 171 </span></div></div><div><div><div>11</div></div><div><span>- Reversed:   </span><span> 160 </span><span> 161 </span><span> 162 </span><span> 163 </span><span> 164 </span><span> 165 </span><span> 166 </span><span> 167 </span><span> 168 </span><span> 169 </span><span> 170 </span><span> 171 </span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>24-bit colors (full RGB):</span></div></div><div><div><div>14</div></div><div><span>- Dimmed:     </span><span> ForestGreen - RGB(34,139,34) </span><span> RebeccaPurple - RGB(102,51,153) </span></div></div><div><div><div>15</div></div><div><span>- Foreground: </span><span> ForestGreen - RGB(34,139,34) </span><span> RebeccaPurple - RGB(102,51,153) </span></div></div><div><div><div>16</div></div><div><span>- Background: </span><span> ForestGreen - RGB(34,139,34) </span><span> RebeccaPurple - RGB(102,51,153) </span></div></div><div><div><div>17</div></div><div><span>- Reversed:   </span><span> ForestGreen - RGB(34,139,34) </span><span> RebeccaPurple - RGB(102,51,153) </span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>Font styles:</span></div></div><div><div><div>20</div></div><div><span>- Default</span></div></div><div><div><div>21</div></div><div><span>- </span><span>Bold</span></div></div><div><div><div>22</div></div><div><span>- </span><span>Dimmed</span></div></div><div><div><div>23</div></div><div><span>- </span><span>Italic</span></div></div><div><div><div>24</div></div><div><span>- </span><span>Underline</span></div></div><div><div><div>25</div></div><div><span>- </span><span>Reversed</span></div></div><div><div><div>26</div></div><div><span>- </span><span>Strikethrough</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section><section><h3>编辑器和终端框架<a href="#编辑器和终端框架"><span>#</span></a></h3><p><a href="https://expressive-code.com/key-features/frames/" target="_blank">编辑器和终端框架</a></p><section><h4>代码编辑器框架<a href="#代码编辑器框架"><span>#</span></a></h4><div><figure><figcaption><span>my-test-file.js</span></figcaption><pre><code><div><div><div>1</div></div><div><span><span>console</span><span>.</span></span><span>log</span><span>(</span><span>'标题属性示例'</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /><div><figure><figcaption><span>src/content/index.html</span></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>div</span><span>&gt;文件名注释示例&lt;/</span><span>div</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>终端框架<a href="#终端框架"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>echo</span><span> </span><span>"此终端框架没有标题"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /><div><figure><figcaption><span>PowerShell 终端示例</span></figcaption><pre><code><div><div><div>1</div></div><div><span>Write-Output</span><span> </span><span>"这个有标题!"</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>覆盖框架类型<a href="#覆盖框架类型"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>echo</span><span> </span><span>"看，没有框架!"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /><div><figure><figcaption><span>PowerShell Profile.ps1</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 如果不覆盖，这将是一个终端框架</span></div></div><div><div><div>2</div></div><div><span>function</span><span> </span><span>Watch-Tail</span><span> { </span><span>Get-Content</span><span><span> </span><span>-</span><span>Tail </span></span><span>20</span><span><span> </span><span>-</span><span>Wait $args }</span></span></div></div><div><div><div>3</div></div><div><span>New-Alias</span><span> tail </span><span>Watch-Tail</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h3>文本和行标记<a href="#文本和行标记"><span>#</span></a></h3><p><a href="https://expressive-code.com/key-features/text-markers/" target="_blank">文本和行标记</a></p><section><h4>标记整行和行范围<a href="#标记整行和行范围"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>// 第1行 - 通过行号定位</span></div></div><div><div><div>2</div></div><div><span>// 第2行</span></div></div><div><div><div>3</div></div><div><span>// 第3行</span></div></div><div><div><div>4</div></div><div><span>// 第4行 - 通过行号定位</span></div></div><div><div><div>5</div></div><div><span>// 第5行</span></div></div><div><div><div>6</div></div><div><span>// 第6行</span></div></div><div><div><div>7</div></div><div><span>// 第7行 - 通过范围 "7-8" 定位</span></div></div><div><div><div>8</div></div><div><span>// 第8行 - 通过范围 "7-8" 定位</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>选择行标记类型 (mark, ins, del)<a href="#选择行标记类型-mark-ins-del"><span>#</span></a></h4><div><figure><figcaption><span>line-markers.js</span></figcaption><pre><code><div><div><div>1</div></div><div><span>function</span><span> </span><span>demo</span><span>() {</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>'此行标记为已删除'</span><span>)</span></div></div><div><div><div>3</div></div><div><span>  </span><span>// 此行和下一行标记为已插入</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>'这是第二个插入行'</span><span>)</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>  </span><span>return</span><span> </span><span>'此行使用中性默认标记类型'</span></div></div><div><div><div>7</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>为行标记添加标签<a href="#为行标记添加标签"><span>#</span></a></h4><div><figure><figcaption><span>labeled-line-markers.jsx</span></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>button</span></div></div><div><div><div>2</div></div><div><span>  </span><span>role</span><span>=</span><span>"button"</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>{</span><span>...</span><span>props</span><span>}</span></div></div><div><div><div>4</div></div><div><span>  </span><span>value</span><span>=</span><span>{</span><span>value</span><span>}</span></div></div><div><div><div>5</div></div><div><span>  </span><span>className</span><span><span>=</span><span>{</span><span>buttonClassName</span><span>}</span></span></div></div><div><div><div>6</div></div><div><span>  </span><span>disabled</span><span>=</span><span>{</span><span>disabled</span><span>}</span></div></div><div><div><div>7</div></div><div><span>  </span><span>active</span><span>=</span><span>{</span><span>active</span><span>}</span></div></div><div><div><div>8</div></div><div><span>&gt;</span></div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>{</span><span>children</span><span> </span><span>&amp;&amp;</span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>!</span><span>active</span><span> </span><span>&amp;&amp;</span></div></div><div><div><div>11</div></div><div><span><span><span>    </span></span><span>(</span></span><span>typeof</span><span> </span><span>children</span><span> </span><span>===</span><span> </span><span>'string'</span><span> </span><span>?</span><span> &lt;</span><span>span</span><span>&gt;</span><span>{</span><span>children</span><span>}</span><span>&lt;/</span><span>span</span><span>&gt; </span><span>:</span><span> </span><span>children</span><span>)</span><span>}</span></div></div><div><div><div>12</div></div><div><span>&lt;/</span><span>button</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>在单独行上添加长标签<a href="#在单独行上添加长标签"><span>#</span></a></h4><div><div><div><figure><figcaption><span>labeled-line-markers.jsx</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>button</span></div></div><div><div><div>2</div></div><div><span>  </span><span>role</span><span>=</span><span>"button"</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>{</span><span>...</span><span>props</span><span>}</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>  </span><span>value</span><span>=</span><span>{</span><span>value</span><span>}</span></div></div><div><div><div>6</div></div><div><span>  </span><span>className</span><span><span>=</span><span>{</span><span>buttonClassName</span><span>}</span></span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span>  </span><span>disabled</span><span>=</span><span>{</span><span>disabled</span><span>}</span></div></div><div><div><div>9</div></div><div><span>  </span><span>active</span><span>=</span><span>{</span><span>active</span><span>}</span></div></div><div><div><div>10</div></div><div><span>&gt;</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span><span>  </span></span><span>{</span><span>children</span><span> </span><span>&amp;&amp;</span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>!</span><span>active</span><span> </span><span>&amp;&amp;</span></div></div><div><div><div>14</div></div><div><span><span><span>    </span></span><span>(</span></span><span>typeof</span><span> </span><span>children</span><span> </span><span>===</span><span> </span><span>'string'</span><span> </span><span>?</span><span> &lt;</span><span>span</span><span>&gt;</span><span>{</span><span>children</span><span>}</span><span>&lt;/</span><span>span</span><span>&gt; </span><span>:</span><span> </span><span>children</span><span>)</span><span>}</span></div></div><div><div><div>15</div></div><div><span>&lt;/</span><span>button</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>使用类似 diff 的语法<a href="#使用类似-diff-的语法"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>此行将标记为已插入</span></div></div><div><div><div>2</div></div><div><span>此行将标记为已删除</span></div></div><div><div><div>3</div></div><div><span>这是常规行</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>--- a/README.md</span></div></div><div><div><div>2</div></div><div><span>+++ b/README.md</span></div></div><div><div><div>3</div></div><div><span>@@ -1,3 +1,4 @@</span></div></div><div><div><div>4</div></div><div><span>+this is an actual diff file</span></div></div><div><div><div>5</div></div><div><span>-all contents will remain unmodified</span></div></div><div><div><div>6</div></div><div><span><span> </span></span><span>no whitespace will be removed either</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>结合语法高亮和类似 diff 的语法<a href="#结合语法高亮和类似-diff-的语法"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>function</span><span> </span><span>thisIsJavaScript</span><span>() {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>// 整个块都会以 JavaScript 高亮显示，</span></div></div><div><div><div>3</div></div><div><span>  </span><span>// 并且我们仍然可以为其添加 diff 标记！</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>'要删除的旧代码'</span><span>)</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>'新的闪亮代码！'</span><span>)</span></div></div><div><div><div>6</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>标记行内的单独文本<a href="#标记行内的单独文本"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>function</span><span> </span><span>demo</span><span>() {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>// 标记行内的任何给定文本</span></div></div><div><div><div>3</div></div><div><span>  </span><span>return</span><span> </span><span>'支持给定文本的多个匹配项'</span><span>;</span></div></div><div><div><div>4</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>正则表达式<a href="#正则表达式"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>console</span><span>.</span></span><span>log</span><span>(</span><span>'单词 </span><mark><span>yes</span></mark><span> 和 </span><mark><span>yep</span></mark><span> 将被标记。'</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>转义正斜杠<a href="#转义正斜杠"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>echo</span><span> </span><span>"Test"</span><span> &gt; </span><mark><span>/home/</span></mark><span>test.txt</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>选择内联标记类型 (mark, ins, del)<a href="#选择内联标记类型-mark-ins-del"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>function</span><span> </span><span>demo</span><span>() {</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>'这些是插入和删除的标记类型'</span><span>);</span></div></div><div><div><div>3</div></div><div><span>  </span><span>// return 语句使用默认标记类型</span></div></div><div><div><div>4</div></div><div><span>  </span><mark><span>return</span><span> </span><span>true</span><span>;</span></mark></div></div><div><div><div>5</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h3>自动换行<a href="#自动换行"><span>#</span></a></h3><p><a href="https://expressive-code.com/key-features/word-wrap/" target="_blank">自动换行</a></p><section><h4>为每个块配置自动换行<a href="#为每个块配置自动换行"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>// 启用换行的示例</span></div></div><div><div><div>2</div></div><div><span>function</span><span> </span><span>getLongString</span><span>() {</span></div></div><div><div><div>3</div></div><div><span>  </span><span>return</span><span> </span><span>'这是一个非常长的字符串，除非容器极宽，否则很可能无法适应可用空间'</span></div></div><div><div><div>4</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>// wrap=false 的示例</span></div></div><div><div><div>2</div></div><div><span>function</span><span> </span><span>getLongString</span><span>() {</span></div></div><div><div><div>3</div></div><div><span>  </span><span>return</span><span> </span><span>'这是一个非常长的字符串，除非容器极宽，否则很可能无法适应可用空间'</span></div></div><div><div><div>4</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>配置换行的缩进<a href="#配置换行的缩进"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>// preserveIndent 示例（默认启用）</span></div></div><div><div><div>2</div></div><div><span>function</span><span> </span><span>getLongString</span><span>() {</span></div></div><div><div><div>3</div></div><div><span>  </span><span>return</span><span> </span><span>'这是一个非常长的字符串，除非容器极宽，否则很可能无法适应可用空间'</span></div></div><div><div><div>4</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>// preserveIndent=false 的示例</span></div></div><div><div><div>2</div></div><div><span>function</span><span> </span><span>getLongString</span><span>() {</span></div></div><div><div><div>3</div></div><div><span>  </span><span>return</span><span> </span><span>'这是一个非常长的字符串，除非容器极宽，否则很可能无法适应可用空间'</span></div></div><div><div><div>4</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section>
<section><h2>可折叠部分<a href="#可折叠部分"><span>#</span></a></h2><p><a href="https://expressive-code.com/plugins/collapsible-sections/" target="_blank">可折叠部分</a></p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div></div></div><div><span></span><span></span><span>5 collapsed lines</span></div></div><div><div><div>1</div></div><div><span>// 所有这些样板设置代码将被折叠</span></div></div><div><div><div>2</div></div><div><span>import</span><span> { </span><span>someBoilerplateEngine</span><span> } </span><span>from</span><span> </span><span>'@example/some-boilerplate'</span></div></div><div><div><div>3</div></div><div><span>import</span><span> { </span><span>evenMoreBoilerplate</span><span> } </span><span>from</span><span> </span><span>'@example/even-more-boilerplate'</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>const</span><span> </span><span>engine</span><span> </span><span>=</span><span> </span><span>someBoilerplateEngine</span><span>(</span><span>evenMoreBoilerplate</span><span>())</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>// 这部分代码默认可见</span></div></div><div><div><div>8</div></div><div><span><span>engine</span><span>.</span></span><span>doSomething</span><span>(</span><span>1</span><span>, </span><span>2</span><span>, </span><span>3</span><span><span>, </span><span>calcFn</span><span>)</span></span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>function</span><span> </span><span>calcFn</span><span>() {</span></div></div><div><div><div>11</div></div><div><span>  </span><span>// 您可以有多个折叠部分</span></div></div><div><div><div></div></div><div><span></span><span></span><span>3 collapsed lines</span></div></div><div><div><div>12</div></div><div><span>  </span><span>const</span><span> </span><span>a</span><span> </span><span>=</span><span> </span><span>1</span></div></div><div><div><div>13</div></div><div><span>  </span><span>const</span><span> </span><span>b</span><span> </span><span>=</span><span> </span><span>2</span></div></div><div><div><div>14</div></div><div><span>  </span><span>const</span><span> </span><span>c</span><span> </span><span>=</span><span><span> </span><span>a</span><span> </span></span><span>+</span><span><span> </span><span>b</span></span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span>  </span><span>// 这将保持可见</span></div></div><div><div><div>17</div></div><div><span><span>  </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>`计算结果: </span><span>${</span><span>a</span><span>}</span><span> + </span><span>${</span><span>b</span><span>}</span><span> = </span><span>${</span><span>c</span><span>}</span><span>`</span><span>)</span></div></div><div><div><div>18</div></div><div><span>  </span><span>return</span><span><span> </span><span>c</span></span></div></div><div><div><div>19</div></div><div><span>}</span></div></div><div><div><div>20</div></div><div>
</div></div><div><div><div></div></div><div><span></span><span></span><span>4 collapsed lines</span></div></div><div><div><div>21</div></div><div><span>// 直到块末尾的所有代码将再次被折叠</span></div></div><div><div><div>22</div></div><div><span><span>engine</span><span>.</span></span><span>closeConnection</span><span>()</span></div></div><div><div><div>23</div></div><div><span><span>engine</span><span>.</span></span><span>freeMemory</span><span>()</span></div></div><div><div><div>24</div></div><div><span><span>engine</span><span>.</span></span><span>shutdown</span><span>({ </span><span>reason</span><span>:</span><span> </span><span>'示例样板代码结束'</span><span> })</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>
<section><h2>行号<a href="#行号"><span>#</span></a></h2><p><a href="https://expressive-code.com/plugins/line-numbers/" target="_blank">行号</a></p><section><h3>为每个块显示行号<a href="#为每个块显示行号"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>// 此代码块将显示行号</span></div></div><div><div><div>2</div></div><div><span><span>console</span><span>.</span></span><span>log</span><span>(</span><span>'来自第2行的问候!'</span><span>)</span></div></div><div><div><div>3</div></div><div><span><span>console</span><span>.</span></span><span>log</span><span>(</span><span>'我在第3行'</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /><div><figure><figcaption></figcaption><pre><code><div><div><span>// 此块禁用行号</span></div></div><div><div><span><span>console</span><span>.</span></span><span>log</span><span>(</span><span>'你好?'</span><span>)</span></div></div><div><div><span><span>console</span><span>.</span></span><span>log</span><span>(</span><span>'抱歉，你知道我在第几行吗?'</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>更改起始行号<a href="#更改起始行号"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>5</div></div><div><span><span>console</span><span>.</span></span><span>log</span><span>(</span><span>'来自第5行的问候!'</span><span>)</span></div></div><div><div><div>6</div></div><div><span><span>console</span><span>.</span></span><span>log</span><span>(</span><span>'我在第6行'</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>Tab 代码块<a href="#tab-代码块"><span>#</span></a></h2><p>由 <a href="https://github.com/ITZSHOAIB/rehype-code-group" target="_blank">rehype-code-group</a> 提供，语法与 <a href="https://vitepress.dev/guide/markdown#code-groups" target="_blank">VitePress 代码组</a> 一致：用 <code>::: code-group labels=[...]</code> 包裹多个代码块，即可合并成一组标签页。</p><div><div><div></div><div>Note</div></div><div><p><code>labels=[...]</code> 中的标签按顺序对应组内的代码块，用英文逗号分隔；<code>:::</code> 与 <code>code-group</code> 之间的空格不能省略。</p></div></div><section><h3>基本用法<a href="#基本用法"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>::: code-group labels=[code.js, code.py, code.html]</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>```js</span></div></div><div><div><div>4</div></div><div><span>export</span><span> </span><span>function</span><span> </span><span>greet</span><span><span>(</span><span>name</span><span>) {</span></span></div></div><div><div><div>5</div></div><div><span>  </span><span>return</span><span> </span><span>`Hello, </span><span>${</span><span>name</span><span>}</span><span>!`</span><span>;</span></div></div><div><div><div>6</div></div><div><span>}</span></div></div><div><div><div>7</div></div><div><span>```</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>```py</span></div></div><div><div><div>10</div></div><div><span>def</span><span> </span><span>greet</span><span><span>(</span><span>name</span><span>):</span></span></div></div><div><div><div>11</div></div><div><span>    </span><span>return</span><span> </span><span>f</span><span>"Hello, </span><span>{</span><span>name</span><span>}</span><span>!"</span></div></div><div><div><div>12</div></div><div><span>```</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>```html</span></div></div><div><div><div>15</div></div><div><span>&lt;</span><span>p</span><span>&gt;Hello, world!&lt;/</span><span>p</span><span>&gt;</span></div></div><div><div><div>16</div></div><div><span>```</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>:::</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>渲染效果：</p><div><div>code.jscode.pycode.html</div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>export</span><span> </span><span>function</span><span> </span><span>greet</span><span><span>(</span><span>name</span><span>) {</span></span></div></div><div><div><div>2</div></div><div><span>  </span><span>return</span><span> </span><span>`Hello, </span><span>${</span><span>name</span><span>}</span><span>!`</span><span>;</span></div></div><div><div><div>3</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>def</span><span> </span><span>greet</span><span>(</span><span>name</span><span>):</span></div></div><div><div><div>2</div></div><div><span>    </span><span>return</span><span> </span><span>f</span><span>"Hello, </span><span>{</span><span>name</span><span>}</span><span>!"</span></div></div></code></pre><div><div></div><div></div></div></figure></div></div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>p</span><span>&gt;Hello, world!&lt;/</span><span>p</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div></div></div></section><section><h3>标签中使用 Emoji<a href="#标签中使用-emoji"><span>#</span></a></h3><p>标签支持 <a href="https://github.com/omnidan/node-emoji#readme" target="_blank">emoji 短代码</a>，构建时会自动转换成 emoji：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>::: code-group labels=[:package: npm, :package: pnpm, :yarn: yarn]</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><div>📦 npm📦 pnpm🧶 yarn</div><div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>create</span><span> </span><span>astro@latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div></div><div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>pnpm</span><span> </span><span>create</span><span> </span><span>astro@latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div></div><div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>yarn</span><span> </span><span>create</span><span> </span><span>astro</span></div></div></code></pre><div><div></div><div></div></div></figure></div></div></div></section><section><h3>与其他代码块特性组合<a href="#与其他代码块特性组合"><span>#</span></a></h3><p>组内仍是普通的 Expressive Code 代码块，标题、行号、行标记、折叠、终端框架等特性都可以照常使用。</p><div><div>配置文件终端折叠</div><div><div><figure><figcaption><span>astro.config.mjs</span></figcaption><pre><code><div><div><div>1</div></div><div><span>export</span><span> </span><span>default</span><span> {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>theme</span><span>:</span><span> </span><span>"firefly"</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>codeGroup</span><span>:</span><span> </span><span>true</span><span>,</span></div></div><div><div><div>4</div></div><div><span>};</span></div></div></code></pre><div><div></div><div></div></div></figure></div></div><div><div><figure><figcaption><span>部署</span></figcaption><pre><code><div><div><div>1</div></div><div><span>pnpm</span><span> </span><span>build</span><span> &amp;&amp; </span><span>pnpm</span><span> </span><span>preview</span></div></div></code></pre><div><div></div><div></div></div></figure></div></div><div><div><figure><figcaption></figcaption><pre><code><div><div><div></div></div><div><span></span><span></span><span>3 collapsed lines</span></div></div><div><div><div>1</div></div><div><span>// 这三行默认折叠</span></div></div><div><div><div>2</div></div><div><span>import</span><span> { </span><span>a</span><span> } </span><span>from</span><span> </span><span>"a"</span><span>;</span></div></div><div><div><div>3</div></div><div><span>import</span><span> { </span><span>b</span><span> } </span><span>from</span><span> </span><span>"b"</span><span>;</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span><span>console</span><span>.</span></span><span>log</span><span><span>(</span><span>a</span><span>, </span><span>b</span><span>);</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div></div></div></section><section><h3>不止是代码块<a href="#不止是代码块"><span>#</span></a></h3><p>标签页内可以放任意内容，例如文字、列表或图片：</p><div><div>说明列表</div><div><p>这是一段普通的段落内容。</p></div><div><ul>
<li>列表项一</li>
<li>列表项二</li>
</ul></div></div><div><div><div></div><div>Tip</div></div><div><p>标签栏在构建期生成，默认展开第一项；支持鼠标点击与键盘 <kbd>←</kbd> / <kbd>→</kbd> / <kbd>Home</kbd> / <kbd>End</kbd> 切换。</p></div></div></section><section><h3>在提醒框内使用（MDX 组件）<a href="#在提醒框内使用mdx-组件"><span>#</span></a></h3><p><code>::: code-group</code> 和 <code>::: tip</code> 等 Docusaurus 风格提醒框都使用 <code>:::</code> 容器语法，而 micromark-directive 规定父子容器的冒号数必须不同，因此 <code>::: code-group</code> <strong>无法嵌套在 <code>::: tip</code> 等提醒框内</strong>（整块会失效）。</p><p>这种情况改用 MDX 组件 <a href="@/components/common/TabGroup.svelte"><code>TabGroup</code></a>：MDX 组件不经过 <code>:::</code> 指令解析，在提醒框内外都能正常使用，也方便日后扩展更多 UI 组件。把文章后缀改为 <code>.mdx</code>，从统一入口 <a href="@/components/firefly-mdx.ts"><code>@/components/firefly-mdx</code></a> 引入（可一次引入多个组件）：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> { </span><span>TabGroup</span><span> } </span><span>from</span><span> </span><span>"@/components/firefly-mdx"</span><span>;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>:::tip</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>&lt;</span><span>TabGroup</span><span> </span><span>labels</span><span>=</span><span>{</span><span>[</span><span>"test.js"</span><span>, </span><span>"test.py"</span><span>]</span><span>}</span><span> </span><span>client</span><span>:</span><span>load</span><span>&gt;</span></div></div><div><div><div>6</div></div><div><span>  </span><span>```</span><span>js</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>1</span><span>)</span></div></div><div><div><div>8</div></div><div><span>  </span><span>```</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>  </span><span>```</span><span>py</span></div></div><div><div><div>11</div></div><div><span>  </span><span>print</span><span>(</span><span>"hello world"</span><span>)</span></div></div><div><div><div>12</div></div><div><span>  </span><span>```</span></div></div><div><div><div>13</div></div><div><span>&lt;/</span><span>TabGroup</span><span>&gt;</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>:::</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><div><div><div></div><div>Tip</div></div><div><ul>
<li><code>labels</code> 数组给每个代码块声明标签，顺序一一对应</li>
<li>组件用 <code>client:load</code> 激活标签切换</li>
</ul></div></div></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/encrypted-demo/</id>
      <title type="text">Firefly 文章加密</title>
      <published>1970-01-01T00:00:00.000Z</published>
      <updated>1970-01-01T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/encrypted-demo/"/>
      <summary type="text">这是一篇密码保护的示例文章，用于演示文章加密功能。</summary>
      <content type="html"><![CDATA[本文已加密保护，请访问网站查看。]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/firefly/</id>
      <title type="text">Firefly 一款清新美观的 Astro 博客主题模板</title>
      <published>1970-01-01T00:00:00.000Z</published>
      <updated>1970-01-01T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/firefly/"/>
      <summary type="text">Firefly 是一款基于 Astro 框架和 Fuwari 模板开发的清新美观且现代化个人博客主题模板，专为技术爱好者和内容创作者设计。该主题融合了现代 Web 技术栈，提供了丰富的功能模块和高度可定制的界面，让您能够轻松打造出专业且美观的个人博客网站。</summary>
      <content type="html"><![CDATA[<section><h2>🌟 项目概述<a href="#-项目概述"><span>#</span></a></h2><p><strong>Firefly</strong> 是一款基于 Astro 框架和 Fuwari 模板开发的清新美观且现代化个人博客主题模板，专为技术爱好者和内容创作者设计。该主题融合了现代 Web 技术栈，提供了丰富的功能模块和高度可定制的界面，让您能够轻松打造出专业且美观的个人博客网站。</p><p><strong>🖥️在线预览： <a href="https://firefly.cuteleaf.cn/" target="_blank">Firefly - Demo site</a></strong></p><p><strong>📝Firefly使用文档： <a href="https://docs-firefly.cuteleaf.cn/" target="_blank">https://docs-firefly.cuteleaf.cn</a></strong></p><p><strong>⭐Firefly开源地址：<a href="https://github.com/CuteLeaf/Firefly" target="_blank">https://github.com/CuteLeaf/Firefly</a></strong></p><p><strong>⭐Fuwari开源地址：<a href="https://github.com/saicaca/fuwari" target="_blank">https://github.com/saicaca/fuwari</a></strong></p><a href="https://github.com/CuteLeaf/Firefly" target="_blank"><div><div><div><div></div><div>CuteLeaf</div></div><div>/</div><div>Firefly</div></div><div></div></div><div>🍀Firefly, fresh and aesthetic Astro blog theme template. </div><div><div>—</div><div>—</div><div>MIT</div><span>Astro</span></div></a><a href="https://github.com/saicaca/fuwari" target="_blank"><div><div><div><div></div><div>saicaca</div></div><div>/</div><div>fuwari</div></div><div></div></div><div>✨A static blog template built with Astro. </div><div><div>—</div><div>—</div><div>MIT</div><span>Astro</span></div></a><p></p><figure><img alt="Firefly" loading="lazy" width="2192" height="1233" src="/_astro/1.BQ4-k1kz_Z17x8Xz.webp" /><figcaption>Firefly</figcaption></figure><p></p></section>
<section><h2>🚀 技术架构<a href="#-技术架构"><span>#</span></a></h2><ul>
<li><strong>静态站点生成</strong>: 基于 Astro ，提供极快的加载速度和优秀的 SEO 优化</li>
<li><strong>TypeScript 支持</strong>: 完整的类型安全，提升开发体验和代码质量</li>
<li><strong>响应式设计</strong>: 使用 Tailwind CSS 构建，完美适配桌面端和移动端</li>
<li><strong>组件化开发</strong>: 支持 Astro、Svelte 组件，灵活可扩展</li>
</ul></section>
<section><h2>📖 配置说明<a href="#-配置说明"><span>#</span></a></h2><blockquote><p>📚 <strong>详细配置文档</strong>: 查看 <a href="https://docs-firefly.cuteleaf.cn/" target="_blank">Firefly 使用文档</a> 获取完整的配置指南</p></blockquote></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/guide/firefly-layout-system/</id>
      <title type="text">Firefly 布局系统详解</title>
      <published>1970-01-01T00:00:00.000Z</published>
      <updated>1970-01-01T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/guide/firefly-layout-system/"/>
      <summary type="text">深入了解 Firefly 的布局系统，包括侧边栏布局（左侧/双侧）和文章列表布局（列表/网格），以及自适应网格列数。</summary>
      <content type="html"><![CDATA[<section><h2>📖 概述<a href="#-概述"><span>#</span></a></h2><p>Firefly 提供了灵活的布局系统，允许您根据内容需求和个人喜好自定义博客的视觉呈现方式。布局系统主要包括<strong>侧边栏布局</strong>和<strong>文章列表布局</strong>两个维度，它们相互配合，共同决定了页面的整体结构。</p><p>本文将详细介绍 Firefly 的各种布局模式、它们的特点、使用场景，以及不同布局组合的效果。</p><hr /><div><figure><img alt="左侧边栏+列表布局" loading="lazy" width="2192" height="1233" src="/_astro/left-list.CdJfuugk_23fiFf.webp" /><figcaption>左侧边栏+列表布局</figcaption></figure><figure><img alt="右侧边栏+网格布局" loading="lazy" width="2192" height="1233" src="/_astro/right-grid2.BDLeNFG9_Z1Ypd95.webp" /><figcaption>右侧边栏+网格布局</figcaption></figure><figure><img alt="左侧边栏+三列网格布局" loading="lazy" width="2192" height="1233" src="/_astro/left-grid3.DCIbm9j3_Z5Vd5j.webp" /><figcaption>左侧边栏+三列网格布局</figcaption></figure></div><div><figure><img alt="双侧边栏+列表布局" loading="lazy" width="2192" height="1233" src="/_astro/both-list.CybtDZTU_xxVkb.webp" /><figcaption>双侧边栏+列表布局</figcaption></figure><figure><img alt="双侧边栏+网格布局" loading="lazy" width="2192" height="1233" src="/_astro/both-grid.B-BFe9Al_1g1tLj.webp" /><figcaption>双侧边栏+网格布局</figcaption></figure><figure><img alt="双侧边栏+网格瀑布流布局" loading="lazy" width="2192" height="1233" src="/_astro/masonry.BgzRsBcp_2mfpqn.webp" /><figcaption>双侧边栏+网格瀑布流布局</figcaption></figure></div></section>
<section><h2>一、侧边栏布局系统<a href="#一侧边栏布局系统"><span>#</span></a></h2><p>侧边栏是博客页面的重要组成部分，用于展示导航、分类、标签、统计信息等辅助内容。Firefly 支持两种侧边栏布局模式。</p><section><h3>1.1 单侧边栏模式<a href="#11-单侧边栏模式"><span>#</span></a></h3><section><h4>左侧边栏 (position: “left”)<a href="#左侧边栏-position-left"><span>#</span></a></h4><p></p><figure><img alt="左侧边栏布局" loading="lazy" width="2192" height="1233" src="/_astro/left-list.CdJfuugk_23fiFf.webp" /><figcaption>左侧边栏布局</figcaption></figure><p></p></section><section><h4>右侧边栏 (position: “right”)<a href="#右侧边栏-position-right"><span>#</span></a></h4><p></p><figure><img alt="右侧边栏布局" loading="lazy" width="2192" height="1233" src="/_astro/right-grid2.BDLeNFG9_Z1Ypd95.webp" /><figcaption>右侧边栏布局</figcaption></figure><p></p></section><section><h4>特点<a href="#特点"><span>#</span></a></h4><ul>
<li>侧边栏固定在页面其中一侧</li>
<li>文章阅读区域体验更佳，更宽敞</li>
<li>更加简约，没有那么紧凑</li>
</ul></section><section><h4>适用场景<a href="#适用场景"><span>#</span></a></h4><ul>
<li>传统博客风格</li>
<li>强调导航和分类的博客</li>
<li>需要突出用户资料的个人博客</li>
<li>内容为主，辅助信息次之的场景</li>
</ul><div><div><div></div><div>Tip</div></div><div><p>文章详情页显示哪几侧，由**各组件的 <code>showOnPostPage</code>（以及 <code>hideOnNonPostPage</code>）**决定：某一侧在当前页型下没有任何可见组件时，该列会自动收起，把空间让给内容栏。</p><p>如果想在文章页同时显示双侧边栏，把 <code>position</code> 设为 <code>"both"</code>，并给两侧组件配好 <code>showOnPostPage</code> 即可。</p></div></div></section><section><h4>配置示例<a href="#配置示例"><span>#</span></a></h4><div><figure><figcaption><span>src/config/sidebarConfig.ts</span></figcaption><pre><code><div><div><div>1</div></div><div><span>export</span><span> </span><span>const</span><span> </span><span>sidebarLayoutConfig</span><span>:</span><span> </span><span>SidebarLayoutConfig</span><span> </span><span>=</span><span> {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>enable</span><span>:</span><span> </span><span>true</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>position</span><span>:</span><span> </span><span>"left"</span><span>, </span><span>// 左侧边栏</span></div></div><div><div><div>4</div></div><div><span>};</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section><section><h3>1.2 双侧边栏模式 (position: “both”)<a href="#12-双侧边栏模式-position-both"><span>#</span></a></h3><section><h4>特点<a href="#特点-1"><span>#</span></a></h4><ul>
<li>左右两侧同时存在侧边栏</li>
<li>主内容区域位于中间</li>
<li>最大化利用屏幕空间</li>
<li>可以展示更多辅助信息</li>
<li>适合宽屏显示器</li>
</ul></section><section><h4>布局结构<a href="#布局结构"><span>#</span></a></h4><p></p><figure><img alt="双侧边栏+列表布局" loading="lazy" width="2192" height="1233" src="/_astro/both-list.CybtDZTU_xxVkb.webp" /><figcaption>双侧边栏+列表布局</figcaption></figure><p></p><p></p><figure><img alt="双侧边栏+网格布局" loading="lazy" width="2192" height="1233" src="/_astro/both-grid.B-BFe9Al_1g1tLj.webp" /><figcaption>双侧边栏+网格布局</figcaption></figure><p></p></section><section><h4>适用场景<a href="#适用场景-1"><span>#</span></a></h4><ul>
<li>宽屏桌面端浏览</li>
<li>信息密集型博客</li>
<li>需要展示大量辅助内容</li>
<li>专业性强的技术博客</li>
</ul></section><section><h4>配置示例<a href="#配置示例-1"><span>#</span></a></h4><div><figure><figcaption><span>src/config/sidebarConfig.ts</span></figcaption><pre><code><div><div><div>1</div></div><div><span>export</span><span> </span><span>const</span><span> </span><span>sidebarLayoutConfig</span><span>:</span><span> </span><span>SidebarLayoutConfig</span><span> </span><span>=</span><span> {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>enable</span><span>:</span><span> </span><span>true</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>position</span><span>:</span><span> </span><span>"both"</span><span>, </span><span>// 双侧边栏</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section></section>
<section><h2>二、文章列表布局系统<a href="#二文章列表布局系统"><span>#</span></a></h2><p>文章列表是博客首页和归档页的核心内容，Firefly 提供两种展示方式，并支持多种网格配置。</p><section><h3>2.1 列表模式 (defaultMode: “list”)<a href="#21-列表模式-defaultmode-list"><span>#</span></a></h3><section><h4>特点<a href="#特点-2"><span>#</span></a></h4><ul>
<li>单列纵向排列</li>
<li>显示文章封面图，可配置在左侧或右侧</li>
<li>展示更多文章摘要</li>
<li>适合深度阅读</li>
</ul></section><section><h4>列表布局结构<a href="#列表布局结构"><span>#</span></a></h4><p></p><figure><img alt="列表模式布局" loading="lazy" width="2192" height="1233" src="/_astro/left-list.CdJfuugk_23fiFf.webp" /><figcaption>列表模式布局</figcaption></figure><p></p></section><section><h4>封面位置<a href="#封面位置"><span>#</span></a></h4><p>列表模式的封面图默认在卡片右侧，可以通过 <code>coverPosition</code> 改到左侧。改到左侧后，标题前的主题色竖线会自动隐藏（它是贴着卡片左边缘的设计），腾出的间距留给正文。</p><p>网格模式的封面固定在卡片顶部，不受这项配置影响。</p></section><section><h4>优点<a href="#优点"><span>#</span></a></h4><ul>
<li>✅ 视觉冲击力强，封面图吸引眼球</li>
<li>✅ 可以展示更多文章信息（摘要、标签等）</li>
<li>✅ 适合图片内容丰富的博客</li>
<li>✅ 移动端友好，单列更易阅读</li>
<li>✅ 兼容所有侧边栏配置（单侧、双侧）</li>
</ul></section><section><h4>配置示例<a href="#配置示例-2"><span>#</span></a></h4><div><figure><figcaption><span>src/config/siteConfig.ts</span></figcaption><pre><code><div><div><div>1</div></div><div><span>export</span><span> </span><span>const</span><span> </span><span>siteConfig</span><span>:</span><span> </span><span>SiteConfig</span><span> </span><span>=</span><span> {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>postListLayout</span><span>:</span><span> {</span></div></div><div><div><div>3</div></div><div><span>    </span><span>defaultMode</span><span>:</span><span> </span><span>"list"</span><span>,    </span><span>// 列表模式</span></div></div><div><div><div>4</div></div><div><span>    </span><span>coverPosition</span><span>:</span><span> </span><span>"right"</span><span>, </span><span>// 封面图位置："right" 右侧，"left" 左侧</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>6</div></div><div><span>};</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section><section><h3>2.2 网格模式 (defaultMode: “grid”)<a href="#22-网格模式-defaultmode-grid"><span>#</span></a></h3><section><h4>特点<a href="#特点-3"><span>#</span></a></h4><ul>
<li>自适应列数，根据浏览器宽度自动调整</li>
<li>紧凑布局，信息密度高</li>
<li>适合快速浏览</li>
</ul></section><section><h4>自适应网格<a href="#自适应网格"><span>#</span></a></h4><p>网格模式通过 <code>columnWidth</code> 配置卡片的最小宽度（单位 px），浏览器会根据容器可用宽度自动计算能容纳多少列。</p><p></p><figure><img alt="网格布局" loading="lazy" width="2192" height="1233" src="/_astro/left-grid3.DCIbm9j3_Z5Vd5j.webp" /><figcaption>网格布局</figcaption></figure><p></p></section><section><h4>配置示例<a href="#配置示例-3"><span>#</span></a></h4><div><figure><figcaption><span>src/config/siteConfig.ts</span></figcaption><pre><code><div><div><div>1</div></div><div><span>export</span><span> </span><span>const</span><span> </span><span>siteConfig</span><span>:</span><span> </span><span>SiteConfig</span><span> </span><span>=</span><span> {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>postListLayout</span><span>:</span><span> {</span></div></div><div><div><div>3</div></div><div><span>    </span><span>defaultMode</span><span>:</span><span> </span><span>"grid"</span><span>,</span></div></div><div><div><div>4</div></div><div><span>    </span><span>grid</span><span>:</span><span> {</span></div></div><div><div><div>5</div></div><div><span>      </span><span>masonry</span><span>:</span><span> </span><span>true</span><span>,      </span><span>// 开启瀑布流</span></div></div><div><div><div>6</div></div><div><span>      </span><span>columnWidth</span><span>:</span><span> </span><span>320</span><span>,   </span><span>// 卡片最小宽度(px)，浏览器自动计算列数</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>8</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>9</div></div><div><span>};</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section><section><h3>2.3 瀑布流布局 (Masonry)<a href="#23-瀑布流布局-masonry"><span>#</span></a></h3><p>Firefly 的网格模式内置了智能瀑布流布局支持，解决了网格布局中因图文混合文章导致的卡片高度不一致导致的空白问题。</p><p></p><figure><img alt="瀑布流布局" loading="lazy" width="2192" height="1233" src="/_astro/masonry.BgzRsBcp_2mfpqn.webp" /><figcaption>瀑布流布局</figcaption></figure><p></p><ul>
<li><strong>智能排版</strong>：自动将卡片放置到最短的列，最大化利用垂直空间。</li>
<li><strong>消除空白</strong>：通过绝对定位精确计算每个卡片的位置，让卡片紧贴上方卡片，消除垂直方向的空白间隙。</li>
<li><strong>自适应列数</strong>：瀑布流同样根据 <code>columnWidth</code> 和容器宽度动态计算列数，无需固定配置。</li>
<li><strong>配置灵活</strong>：您可以在 <code>siteConfig.ts</code> 中通过 <code>postListLayout.grid.masonry</code> 选项自由开启或关闭此功能。</li>
</ul><hr /></section></section>
<section><h2>三、布局组合指南<a href="#三布局组合指南"><span>#</span></a></h2><p>Firefly 允许您自由组合侧边栏和文章列表布局。以下是各种组合的效果说明。</p>

<table><thead><tr><th>侧边栏模式</th><th>文章列表模式</th><th>推荐度</th><th>适用场景</th></tr></thead><tbody><tr><td>单侧边栏</td><td>列表模式</td><td>⭐⭐⭐⭐⭐</td><td>摄影、设计、生活类博客，强调图片和沉浸感</td></tr><tr><td>单侧边栏</td><td>网格模式</td><td>⭐⭐⭐⭐⭐</td><td>技术、笔记类博客，平衡阅读与检索效率</td></tr><tr><td>双侧边栏</td><td>列表模式</td><td>⭐⭐⭐⭐⭐</td><td>需要展示大量侧边栏信息的站点</td></tr><tr><td>双侧边栏</td><td>网格模式</td><td>⭐⭐⭐⭐⭐</td><td>极客风格，追求最高信息密度</td></tr></tbody></table><hr /></section>
<section><h2>四、响应式布局行为<a href="#四响应式布局行为"><span>#</span></a></h2><p>Firefly 的布局系统具有智能的响应式设计，会根据屏幕尺寸自动调整。</p><p>为了保证最佳阅读体验，系统会在屏幕变窄时自动调整布局：</p><ol>
<li><strong>网格列数自动减少</strong>：网格模式的列数由 <code>columnWidth</code> 和容器宽度自动决定，屏幕越窄列数越少。</li>
<li><strong>列表模式 -&gt; 网格模式</strong>：当屏幕宽度小于 380px（超小屏设备）时，列表模式会自动切换为网格模式，以保证卡片内容的可读性。</li>
<li><strong>双侧边栏 -&gt; 单侧边栏</strong>：当屏幕宽度小于 1280px 时，会根据<code>tabletSidebar</code>配置显示单侧边栏，隐藏其中一个侧边栏，文章目录导航会切换成浮动目录导航。</li>
</ol><hr /></section>
<section><h2>五、常见问题<a href="#五常见问题"><span>#</span></a></h2><section><h3>Q1: 如何调整网格列数？<a href="#q1-如何调整网格列数"><span>#</span></a></h3><p><strong>A</strong>: 通过 <code>columnWidth</code> 配置卡片最小宽度即可。值越小，同等宽度下列数越多；值越大，列数越少。浏览器会自动根据可用宽度计算最佳列数。</p><hr /></section></section>
<section><h2>六、总结<a href="#六总结"><span>#</span></a></h2><p>Firefly 的布局系统给予了您更大的自由度，您都可以通过简单的配置实现。</p><p>我们建议您根据自己的内容类型和目标读者的设备偏好，尝试不同的组合，找到最适合您的博客形态。</p><hr /></section>
<section><h2>相关链接<a href="#相关链接"><span>#</span></a></h2><ul>
<li>📚 <a href="https://docs-firefly.cuteleaf.cn/config/sidebarConfig-usage/" target="_blank">侧边栏配置文档</a></li>
<li>📚 <a href="https://docs-firefly.cuteleaf.cn/config/siteConfig-usage/" target="_blank">站点配置文档</a></li>
<li>🏠 <a href="https://docs-firefly.cuteleaf.cn/" target="_blank">Firefly 官方文档</a></li>
<li>⭐ <a href="https://github.com/CuteLeaf/Firefly" target="_blank">Firefly GitHub</a></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/katex-math-example/</id>
      <title type="text">KaTeX 数学公式示例</title>
      <published>1970-01-01T00:00:00.000Z</published>
      <updated>1970-01-01T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/katex-math-example/"/>
      <summary type="text">展示 Firefly 主题对 KaTeX 数学公式的支持，包括行内公式、块级公式和复杂数学符号。</summary>
      <content type="html"><![CDATA[<p>本文展示了 <a href="https://github.com/CuteLeaf/Firefly" target="_blank">Firefly</a> 主题对 KaTeX 数学公式的渲染支持。</p>
<section><h2>行内公式 (Inline)<a href="#行内公式-inline"><span>#</span></a></h2><p>行内公式使用单个 <code>$</code> 符号包裹。</p><p>例如：欧拉公式 <span><span>eiπ+1=0e^{i\pi} + 1 = 0</span><span><span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>iπ</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>1</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span> 是数学中最优美的公式之一。</p><p>质能方程 <span><span>E=mc2E = mc^2</span><span><span><span></span><span>E</span><span></span><span>=</span><span></span></span><span><span></span><span>m</span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span> 也是家喻户晓。</p></section>
<section><h2>块级公式 (Block)<a href="#块级公式-block"><span>#</span></a></h2><p>块级公式使用两个 <code>$$</code> 符号包裹，会居中显示。</p><span><span><span>∫−∞∞e−x2dx=π\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}</span><span><span><span></span><span><span>∫</span><span><span><span><span><span><span></span><span><span><span>−</span><span>∞</span></span></span></span><span><span></span><span><span><span>∞</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>−</span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span>d</span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span>π</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span><span><span>x=−b±b2−4ac2ax = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}</span><span><span><span></span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>2</span><span>a</span></span></span><span><span></span><span></span></span><span><span></span><span><span>−</span><span>b</span><span></span><span>±</span><span></span><span><span><span><span><span><span></span><span><span><span>b</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span><span></span><span>−</span><span></span><span>4</span><span>a</span><span>c</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span></span></section>
<section><h2>复杂示例<a href="#复杂示例"><span>#</span></a></h2><section><h3>矩阵 (Matrices)<a href="#矩阵-matrices"><span>#</span></a></h3><span><span><span>(abcd)(αβγδ)=(aα+bγaβ+bδcα+dγcβ+dδ)\begin{pmatrix}
a &amp; b \\
c &amp; d
\end{pmatrix}
\begin{pmatrix}
\alpha &amp; \beta \\
\gamma &amp; \delta
\end{pmatrix} =
\begin{pmatrix}
a\alpha + b\gamma &amp; a\beta + b\delta \\
c\alpha + d\gamma &amp; c\beta + d\delta
\end{pmatrix}</span><span><span><span></span><span><span><span>(</span></span><span><span><span><span><span><span><span><span></span><span><span>a</span></span></span><span><span></span><span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span></span><span><span><span><span><span><span></span><span><span>b</span></span></span><span><span></span><span><span>d</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span><span><span>)</span></span></span><span></span><span><span><span>(</span></span><span><span><span><span><span><span><span><span></span><span><span>α</span></span></span><span><span></span><span><span>γ</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span></span><span><span><span><span><span><span></span><span><span>β</span></span></span><span><span></span><span><span>δ</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span><span><span>)</span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span>(</span></span><span><span><span><span><span><span><span><span></span><span><span>a</span><span>α</span><span></span><span>+</span><span></span><span>bγ</span></span></span><span><span></span><span><span>c</span><span>α</span><span></span><span>+</span><span></span><span>d</span><span>γ</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span></span><span><span><span><span><span><span></span><span><span>a</span><span>β</span><span></span><span>+</span><span></span><span>b</span><span>δ</span></span></span><span><span></span><span><span>c</span><span>β</span><span></span><span>+</span><span></span><span>d</span><span>δ</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span><span><span>)</span></span></span></span></span></span></span></section><section><h3>极限与求和 (Limits and Sums)<a href="#极限与求和-limits-and-sums"><span>#</span></a></h3><span><span><span>∑n=1∞1n2=π26\sum_{n=1}^{\infty} \frac{1}{n^2} = \frac{\pi^2}{6}</span><span><span><span></span><span><span><span><span><span><span></span><span><span><span>n</span><span>=</span><span>1</span></span></span></span><span><span></span><span><span>∑</span></span></span><span><span></span><span><span><span>∞</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>n</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>6</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>π</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span></span><span><span><span>lim⁡x→0sin⁡xx=1\lim_{x \to 0} \frac{\sin x}{x} = 1</span><span><span><span></span><span><span><span><span><span><span></span><span><span><span>x</span><span>→</span><span>0</span></span></span></span><span><span></span><span><span>lim</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>sin</span><span></span><span>x</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>1</span></span></span></span></span></section><section><h3>麦克斯韦方程组 (Maxwell’s Equations)<a href="#麦克斯韦方程组-maxwells-equations"><span>#</span></a></h3><span><span><span>∇⋅E=ρε0∇⋅B=0∇×E=−∂B∂t∇×B=μ0J+μ0ε0∂E∂t\begin{aligned}
\nabla \cdot \mathbf{E} &amp;= \frac{\rho}{\varepsilon_0} \\
\nabla \cdot \mathbf{B} &amp;= 0 \\
\nabla \times \mathbf{E} &amp;= -\frac{\partial \mathbf{B}}{\partial t} \\
\nabla \times \mathbf{B} &amp;= \mu_0\mathbf{J} + \mu_0\varepsilon_0\frac{\partial \mathbf{E}}{\partial t}
\end{aligned}</span><span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>∇</span><span></span><span>⋅</span><span></span><span>E</span></span></span><span><span></span><span><span>∇</span><span></span><span>⋅</span><span></span><span>B</span></span></span><span><span></span><span><span>∇</span><span></span><span>×</span><span></span><span>E</span></span></span><span><span></span><span><span>∇</span><span></span><span>×</span><span></span><span>B</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span><span><span><span><span><span></span><span><span></span><span></span><span>=</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>ε</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>ρ</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span><span></span><span></span><span>=</span><span></span><span>0</span></span></span><span><span></span><span><span></span><span></span><span>=</span><span></span><span>−</span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span>t</span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span><span>B</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span><span><span></span><span><span></span><span></span><span>=</span><span></span><span><span>μ</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>J</span><span></span><span>+</span><span></span><span><span>μ</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>ε</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span>t</span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span><span>E</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></span></span></section><section><h3>化学方程式 (Chemical Equations)<a href="#化学方程式-chemical-equations"><span>#</span></a></h3><span><span><span>\ceCH4+2O2−&gt;CO2+2H2O\ce{CH4 + 2O2 -&gt; CO2 + 2H2O}</span><span><span><span></span><span><span>\ce</span></span><span><span>C</span><span>H</span><span>4</span><span></span><span>+</span><span></span><span>2</span><span>O</span><span>2</span><span>−</span><span></span><span>&gt;</span><span></span><span>C</span><span>O</span><span>2</span><span></span><span>+</span><span></span><span>2</span><span>H</span><span>2</span><span>O</span></span></span></span></span></span></section></section>
<section><h2>更多符号<a href="#更多符号"><span>#</span></a></h2>

<table><thead><tr><th>符号</th><th>代码</th><th>渲染结果</th></tr></thead><tbody><tr><td>Alpha</td><td><code>\alpha</code></td><td><span><span>α\alpha</span><span><span><span></span><span>α</span></span></span></span></td></tr><tr><td>Beta</td><td><code>\beta</code></td><td><span><span>β\beta</span><span><span><span></span><span>β</span></span></span></span></td></tr><tr><td>Gamma</td><td><code>\Gamma</code></td><td><span><span>Γ\Gamma</span><span><span><span></span><span>Γ</span></span></span></span></td></tr><tr><td>Pi</td><td><code>\pi</code></td><td><span><span>π\pi</span><span><span><span></span><span>π</span></span></span></span></td></tr><tr><td>Infinity</td><td><code>\infty</code></td><td><span><span>∞\infty</span><span><span><span></span><span>∞</span></span></span></span></td></tr><tr><td>Right Arrow</td><td><code>\rightarrow</code></td><td><span><span>→\rightarrow</span><span><span><span></span><span>→</span></span></span></span></td></tr><tr><td>Partial</td><td><code>\partial</code></td><td><span><span>∂\partial</span><span><span><span></span><span>∂</span></span></span></span></td></tr></tbody></table><p>更多 KaTeX 语法请参考 <a href="https://katex.org/docs/supported.html" target="_blank">KaTeX Supported Functions</a>。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/markdown-extended/</id>
      <title type="text">Markdown 扩展功能</title>
      <published>1970-01-01T00:00:00.000Z</published>
      <updated>1970-01-01T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/markdown-extended/"/>
      <summary type="text">了解 Firefly 中的 Markdown 功能</summary>
      <content type="html"><![CDATA[<section><h2>GitHub 仓库卡片<a href="#github-仓库卡片"><span>#</span></a></h2><p>您可以添加链接到 GitHub 仓库的动态卡片，在页面加载时，仓库信息会从 GitHub API 获取。</p><a href="https://github.com/CuteLeaf/Firefly" target="_blank"><div><div><div><div></div><div>CuteLeaf</div></div><div>/</div><div>Firefly</div></div><div></div></div><div>🍀Firefly, fresh and aesthetic Astro blog theme template. </div><div><div>—</div><div>—</div><div>MIT</div><span>Astro</span></div></a><p>使用代码 <code>::github{repo="CuteLeaf/Firefly"}</code> 创建 GitHub 仓库卡片。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>::github{repo="CuteLeaf/Firefly"}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>提醒框(Admonitions)配置<a href="#提醒框admonitions配置"><span>#</span></a></h2><p>Firefly 采用了 <a href="https://github.com/lin-stephanie/rehype-callouts" target="_blank">rehype-callouts</a> 插件，支持了四种风格的提醒框主题：<code>GitHub</code>、<code>Obsidian</code>、<code>VitePress</code> 和 <code>Docusaurus</code>。您可以在 <code>src/config/siteConfig.ts</code> 中进行配置：</p><div><figure><figcaption><span>src/config/siteConfig.ts</span></figcaption><pre><code><div><div><div>1</div></div><div><span>export</span><span> </span><span>const</span><span> </span><span>siteConfig</span><span>:</span><span> </span><span>SiteConfig</span><span> </span><span>=</span><span> {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>// ...</span></div></div><div><div><div>3</div></div><div><span>  </span><span>rehypeCallouts</span><span>:</span><span> {</span></div></div><div><div><div>4</div></div><div><span>    </span><span>// 选项: "github" | "obsidian" | "vitepress" | "docusaurus"</span></div></div><div><div><div>5</div></div><div><span>    </span><span>theme</span><span>:</span><span> </span><span>"github"</span><span>,</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>7</div></div><div><span>  </span><span>// ...</span></div></div><div><div><div>8</div></div><div><span>};</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>注意：<strong>更改配置后需要重启开发服务器才能生效。</strong></p><p>以下是各个主题支持的类型列表，每个主题风格和语法不同，可根据喜好选择。</p><section><h3>1. GitHub 主题风格<a href="#1-github-主题风格"><span>#</span></a></h3><p>这是 GitHub 官方支持的 5 种基本类型。</p><p></p><figure><img alt="GitHub" loading="lazy" width="2144" height="1086" src="/_astro/github.urcbElKG_Z1bC9wS.webp" /><figcaption>GitHub</figcaption></figure><p></p><p><strong>基本语法</strong></p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&gt; </span><span>[</span><span>!NOTE</span><span>]</span><span> NOTE</span></div></div><div><div><div>2</div></div><div><span>&gt; 突出显示用户应该考虑的信息。</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>&gt; </span><span>[</span><span>!TIP</span><span>]</span><span> TIP</span></div></div><div><div><div>5</div></div><div><span>&gt; 可选信息，帮助用户更成功。</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>&gt; </span><span>[</span><span>!IMPORTANT</span><span>]</span><span> IMPORTANT</span></div></div><div><div><div>8</div></div><div><span>&gt; 用户成功所必需的关键信息。</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>&gt; </span><span>[</span><span>!WARNING</span><span>]</span><span> WARNING</span></div></div><div><div><div>11</div></div><div><span>&gt; 关键内容，需要立即注意。</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>&gt; </span><span>[</span><span>!CAUTION</span><span>]</span><span> CAUTION</span></div></div><div><div><div>14</div></div><div><span>&gt; 行动的负面潜在后果。</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span>&gt; </span><span>[</span><span>!NOTE</span><span>]</span><span> 自定义标题</span></div></div><div><div><div>17</div></div><div><span>&gt; 这是一个带有自定义标题的示例。</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><hr /></section><section><h3>2. Obsidian 主题风格<a href="#2-obsidian-主题风格"><span>#</span></a></h3><p><a href="https://obsidian.md/" target="_blank">Obsidian</a> 风格支持非常丰富的类型和别名。</p>
点击展开 Obsidian 语法列表<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&gt; </span><span>[</span><span>!NOTE</span><span>]</span><span> NOTE</span></div></div><div><div><div>2</div></div><div><span>&gt; 通用的笔记块。</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>&gt; </span><span>[</span><span>!ABSTRACT</span><span>]</span><span> ABSTRACT</span></div></div><div><div><div>5</div></div><div><span>&gt; 文章的摘要。</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>&gt; </span><span>[</span><span>!SUMMARY</span><span>]</span><span> SUMMARY</span></div></div><div><div><div>8</div></div><div><span>&gt; 文章的总结（同 Abstract）。</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>&gt; </span><span>[</span><span>!TLDR</span><span>]</span><span> TLDR</span></div></div><div><div><div>11</div></div><div><span>&gt; 太长不看（同 Abstract）。</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>&gt; </span><span>[</span><span>!INFO</span><span>]</span><span> INFO</span></div></div><div><div><div>14</div></div><div><span>&gt; 提供额外信息。</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span>&gt; </span><span>[</span><span>!TODO</span><span>]</span><span> TODO</span></div></div><div><div><div>17</div></div><div><span>&gt; 需要完成的事项。</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>&gt; </span><span>[</span><span>!TIP</span><span>]</span><span> TIP</span></div></div><div><div><div>20</div></div><div><span>&gt; 实用技巧或提示。</span></div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span>&gt; </span><span>[</span><span>!HINT</span><span>]</span><span> HINT</span></div></div><div><div><div>23</div></div><div><span>&gt; 暗示（同 Tip）。</span></div></div><div><div><div>24</div></div><div>
</div></div><div><div><div>25</div></div><div><span>&gt; </span><span>[</span><span>!IMPORTANT</span><span>]</span><span> IMPORTANT</span></div></div><div><div><div>26</div></div><div><span>&gt; 重要信息（Obsidian 风格通常使用类似的图标）。</span></div></div><div><div><div>27</div></div><div>
</div></div><div><div><div>28</div></div><div><span>&gt; </span><span>[</span><span>!SUCCESS</span><span>]</span><span> SUCCESS</span></div></div><div><div><div>29</div></div><div><span>&gt; 操作成功。</span></div></div><div><div><div>30</div></div><div>
</div></div><div><div><div>31</div></div><div><span>&gt; </span><span>[</span><span>!CHECK</span><span>]</span><span> CHECK</span></div></div><div><div><div>32</div></div><div><span>&gt; 检查通过（同 Success）。</span></div></div><div><div><div>33</div></div><div>
</div></div><div><div><div>34</div></div><div><span>&gt; </span><span>[</span><span>!DONE</span><span>]</span><span> DONE</span></div></div><div><div><div>35</div></div><div><span>&gt; 已完成（同 Success）。</span></div></div><div><div><div>36</div></div><div>
</div></div><div><div><div>37</div></div><div><span>&gt; </span><span>[</span><span>!QUESTION</span><span>]</span><span> QUESTION</span></div></div><div><div><div>38</div></div><div><span>&gt; 提出问题。</span></div></div><div><div><div>39</div></div><div>
</div></div><div><div><div>40</div></div><div><span>&gt; </span><span>[</span><span>!HELP</span><span>]</span><span> HELP</span></div></div><div><div><div>41</div></div><div><span>&gt; 寻求帮助（同 Question）。</span></div></div><div><div><div>42</div></div><div>
</div></div><div><div><div>43</div></div><div><span>&gt; </span><span>[</span><span>!FAQ</span><span>]</span><span> FAQ</span></div></div><div><div><div>44</div></div><div><span>&gt; 常见问题（同 Question）。</span></div></div><div><div><div>45</div></div><div>
</div></div><div><div><div>46</div></div><div><span>&gt; </span><span>[</span><span>!WARNING</span><span>]</span><span> WARNING</span></div></div><div><div><div>47</div></div><div><span>&gt; 警告信息。</span></div></div><div><div><div>48</div></div><div>
</div></div><div><div><div>49</div></div><div><span>&gt; </span><span>[</span><span>!CAUTION</span><span>]</span><span> CAUTION</span></div></div><div><div><div>50</div></div><div><span>&gt; 注意事项（同 Warning）。</span></div></div><div><div><div>51</div></div><div>
</div></div><div><div><div>52</div></div><div><span>&gt; </span><span>[</span><span>!ATTENTION</span><span>]</span><span> ATTENTION</span></div></div><div><div><div>53</div></div><div><span>&gt; 引起注意（同 Warning）。</span></div></div><div><div><div>54</div></div><div>
</div></div><div><div><div>55</div></div><div><span>&gt; </span><span>[</span><span>!FAILURE</span><span>]</span><span> FAILURE</span></div></div><div><div><div>56</div></div><div><span>&gt; 操作失败。</span></div></div><div><div><div>57</div></div><div>
</div></div><div><div><div>58</div></div><div><span>&gt; </span><span>[</span><span>!FAIL</span><span>]</span><span> FAIL</span></div></div><div><div><div>59</div></div><div><span>&gt; 失败（同 Failure）。</span></div></div><div><div><div>60</div></div><div>
</div></div><div><div><div>61</div></div><div><span>&gt; </span><span>[</span><span>!MISSING</span><span>]</span><span> MISSING</span></div></div><div><div><div>62</div></div><div><span>&gt; 缺失内容（同 Failure）。</span></div></div><div><div><div>63</div></div><div>
</div></div><div><div><div>64</div></div><div><span>&gt; </span><span>[</span><span>!DANGER</span><span>]</span><span> DANGER</span></div></div><div><div><div>65</div></div><div><span>&gt; 危险操作警告。</span></div></div><div><div><div>66</div></div><div>
</div></div><div><div><div>67</div></div><div><span>&gt; </span><span>[</span><span>!ERROR</span><span>]</span><span> ERROR</span></div></div><div><div><div>68</div></div><div><span>&gt; 错误信息（同 Danger）。</span></div></div><div><div><div>69</div></div><div>
</div></div><div><div><div>70</div></div><div><span>&gt; </span><span>[</span><span>!BUG</span><span>]</span><span> BUG</span></div></div><div><div><div>71</div></div><div><span>&gt; 报告软件缺陷。</span></div></div><div><div><div>72</div></div><div>
</div></div><div><div><div>73</div></div><div><span>&gt; </span><span>[</span><span>!EXAMPLE</span><span>]</span><span> EXAMPLE</span></div></div><div><div><div>74</div></div><div><span>&gt; 展示一个例子。</span></div></div><div><div><div>75</div></div><div>
</div></div><div><div><div>76</div></div><div><span>&gt; </span><span>[</span><span>!QUOTE</span><span>]</span><span> QUOTE</span></div></div><div><div><div>77</div></div><div><span>&gt; 引用一段话。</span></div></div><div><div><div>78</div></div><div>
</div></div><div><div><div>79</div></div><div><span>&gt; </span><span>[</span><span>!CITE</span><span>]</span><span> CITE</span></div></div><div><div><div>80</div></div><div><span>&gt; 引证（同 Quote）。</span></div></div><div><div><div>81</div></div><div>
</div></div><div><div><div>82</div></div><div><span>&gt; </span><span>[</span><span>!NOTE</span><span>]</span><span> 自定义标题</span></div></div><div><div><div>83</div></div><div><span>&gt; 这是一个带有自定义标题的示例。</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p></p><figure><img alt="Obsidian" loading="lazy" width="2144" height="1320" src="/_astro/obsidian.Cwb2iYzd_1I7Wom.webp" /><figcaption>Obsidian</figcaption></figure><p></p><hr /></section><section><h3>3. VitePress 主题风格<a href="#3-vitepress-主题风格"><span>#</span></a></h3><p><a href="https://vitepress.dev/" target="_blank">VitePress</a> 风格提供了一套现代化的、扁平的默认样式。目前仅包含与 GitHub 一致的 <strong>5 种</strong> 基础类型。</p>
点击展开 VitePress 语法列表<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&gt; </span><span>[</span><span>!NOTE</span><span>]</span><span> NOTE</span></div></div><div><div><div>2</div></div><div><span>&gt; 对应 GitHub 的 Note。</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>&gt; </span><span>[</span><span>!TIP</span><span>]</span><span> TIP</span></div></div><div><div><div>5</div></div><div><span>&gt; 对应 GitHub 的 Tip。</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>&gt; </span><span>[</span><span>!IMPORTANT</span><span>]</span><span> IMPORTANT</span></div></div><div><div><div>8</div></div><div><span>&gt; 对应 GitHub 的 Important。</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>&gt; </span><span>[</span><span>!WARNING</span><span>]</span><span> WARNING</span></div></div><div><div><div>11</div></div><div><span>&gt; 对应 GitHub 的 Warning。</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>&gt; </span><span>[</span><span>!CAUTION</span><span>]</span><span> CAUTION</span></div></div><div><div><div>14</div></div><div><span>&gt; 对应 GitHub 的 Caution。</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span>&gt; </span><span>[</span><span>!TIP</span><span>]</span><span> 自定义标题</span></div></div><div><div><div>17</div></div><div><span>&gt; VitePress 风格同样支持自定义标题。</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p></p><figure><img alt="VitePress" loading="lazy" width="2144" height="1318" src="/_astro/vitepress.D2YnjBWE_Z1rUl1H.webp" /><figcaption>VitePress</figcaption></figure><p></p><hr /></section><section><h3>4. Docusaurus 主题风格<a href="#4-docusaurus-主题风格"><span>#</span></a></h3><p><a href="https://docusaurus.io/docs/markdown-features/admonitions" target="_blank">Docusaurus</a> 风格提供了一套现代化的提醒框样式，支持 5 种类型。</p>
点击展开 Docusaurus 语法列表 <p>支持以下类型的提醒框：<code>note</code> <code>tip</code> <code>info</code> <code>warning</code> <code>danger</code></p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>:::note</span></div></div><div><div><div>2</div></div><div><span>突出显示用户应该考虑的信息，即使在快速浏览时也是如此。</span></div></div><div><div><div>3</div></div><div><span>:::</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>:::tip</span></div></div><div><div><div>6</div></div><div><span>可选信息，帮助用户更成功。</span></div></div><div><div><div>7</div></div><div><span>:::</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>:::info</span></div></div><div><div><div>10</div></div><div><span>一般信息。</span></div></div><div><div><div>11</div></div><div><span>:::</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>:::warning</span></div></div><div><div><div>14</div></div><div><span>由于潜在风险需要用户立即注意的关键内容。</span></div></div><div><div><div>15</div></div><div><span>:::</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>:::danger</span></div></div><div><div><div>18</div></div><div><span>行动的负面潜在后果。</span></div></div><div><div><div>19</div></div><div><span>:::</span></div></div><div><div><div>20</div></div><div>
</div></div><div><div><div>21</div></div><div><span>:::tip</span><span>[</span><span>自定义标题</span><span>]</span></div></div><div><div><div>22</div></div><div><span>可选信息，帮助用户更成功。</span></div></div><div><div><div>23</div></div><div><span>:::</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p></p><figure><img alt="Docusaurus" loading="lazy" width="2158" height="1394" src="/_astro/docusaurus.Cu-On_k2_Zy4rHX.webp" /><figcaption>Docusaurus</figcaption></figure><p></p><hr /></section></section>
<section><h2>剧透<a href="#剧透"><span>#</span></a></h2><p>您可以为文本添加剧透。文本也支持 <strong>Markdown</strong> 语法。</p><p>内容 被隐藏了 <strong>哈哈</strong>！</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>内容 :spoiler[被隐藏了 </span><span>**哈哈**</span><span>]！</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>图片画廊网格 (Image Grid)<a href="#图片画廊网格-image-grid"><span>#</span></a></h2><p>您可以使用 <code>[grid]</code> 和 <code>[/grid]</code> 标签将多张图片纵向并排展示。这对于展示照片画廊或对比图非常有用。系统会自动根据包裹在其中的图片数量（最多支持并排展示4张）以响应式网格进行布局。</p><p><strong>自动补齐图片高度：</strong> 同一排中如果有高度、大小或者比例不一的图片，会像「九宫格画廊相册」一样自动撑满。较短或不协调的图片会自动使用 object-cover 进行完美中心裁剪补充视野。图片边框水平彻底对齐无缝隙，但被裁剪后，只有点击图片通过灯箱才能查看完整图片，所以建议尽量避免使用长宽比例不一致的图片在同一排中。</p><p><strong>图注恒定底端对齐：</strong> 不论上面的图片长宽如何变化，在同一行的所有图像解释文字（图注）都会对标到一条完美的水平基线上了。</p><div><figure><img alt="示例图片一" loading="lazy" width="3328" height="1872" src="/_astro/firefly1.CZCuCN4V_1dgNYg.webp" /><figcaption>示例图片一</figcaption></figure><figure><img alt="示例图片二" loading="lazy" width="4096" height="2212" src="/_astro/firefly2.dxmXG905_ZyJm5m.webp" /><figcaption>示例图片二</figcaption></figure><figure><img alt="示例图片二" loading="lazy" width="3840" height="2160" src="/_astro/firefly3.CGzFXcxi_Z1Lz6q8.webp" /><figcaption>示例图片二</figcaption></figure></div><p><strong>基本语法</strong></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[</span><span>grid</span><span>]</span></div></div><div><div><div>2</div></div><div><span>![</span><span>示例图片一</span><span>]</span><span><span>(</span><span>./images/firefly1.avif</span><span>)</span></span></div></div><div><div><div>3</div></div><div><span>![</span><span>示例图片二</span><span>]</span><span><span>(</span><span>./images/firefly2.avif</span><span>)</span></span></div></div><div><div><div>4</div></div><div><span>![</span><span>示例图片二</span><span>]</span><span><span>(</span><span>./images/firefly3.avif</span><span>)</span></span></div></div><div><div><div>5</div></div><div><span>[</span><span>/grid</span><span>]</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/markdown-mermaid/</id>
      <title type="text">Markdown Mermaid 图表</title>
      <published>1970-01-01T00:00:00.000Z</published>
      <updated>1970-01-01T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/markdown-mermaid/"/>
      <summary type="text">一个包含 Mermaid 的 Markdown 博客文章简单示例。</summary>
      <content type="html"><![CDATA[<section><h2>Markdown 中 Mermaid 图表完整指南<a href="#markdown-中-mermaid-图表完整指南"><span>#</span></a></h2><p>本文演示如何在 Markdown 文档中使用 Mermaid 创建各种复杂图表，包括流程图、时序图、ER 图、类图、状态图、XY 图、甘特图、思维导图等。</p><blockquote><p>Mermaid 图表由 <a href="https://github.com/Latias94/merman" target="_blank">Merman</a> 实现。Firefly 在 Astro 构建阶段生成亮色和深色两套静态 SVG，无需在浏览器中加载 Mermaid 渲染运行时。可以前往 <a href="http://frankorz.com/merman/" target="_blank">Merman Playground</a> 实时编辑语法并预览渲染结果。</p></blockquote></section>
<section><h2>流程图示例<a href="#流程图示例"><span>#</span></a></h2><p>流程图非常适合表示流程或算法步骤。</p><div><div><div><div><span></span></div><div><span><p>是</p></span></div><div><span><p>否</p></span></div><div><span><p>选项 1</p></span></div><div><span><p>选项 2</p></span></div><div><span><p>选项 3</p></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>子过程详情</p></span></div><div><span></span></div><div><span></span></div><div><span><p>子步骤 1</p></span></div><div><span><p>子步骤 2</p></span></div><div><span><p>子步骤 3</p></span></div><div><span><p>开始</p></span></div><div><span><p>条件检查</p></span></div><div><span><p>处理步骤 1</p></span></div><div><span><p>处理步骤 2</p></span></div><div><span><p>另一个决策</p></span></div><div><span><p>结果 1</p></span></div><div><span><p>结果 2</p></span></div><div><span><p>结果 3</p></span></div><div><span><p>结束</p></span></div>
</div><div><div><span></span></div><div><span><p>是</p></span></div><div><span><p>否</p></span></div><div><span><p>选项 1</p></span></div><div><span><p>选项 2</p></span></div><div><span><p>选项 3</p></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>子过程详情</p></span></div><div><span></span></div><div><span></span></div><div><span><p>子步骤 1</p></span></div><div><span><p>子步骤 2</p></span></div><div><span><p>子步骤 3</p></span></div><div><span><p>开始</p></span></div><div><span><p>条件检查</p></span></div><div><span><p>处理步骤 1</p></span></div><div><span><p>处理步骤 2</p></span></div><div><span><p>另一个决策</p></span></div><div><span><p>结果 1</p></span></div><div><span><p>结果 2</p></span></div><div><span><p>结果 3</p></span></div><div><span><p>结束</p></span></div>
</div></div></div></section>
<section><h2>时序图示例<a href="#时序图示例"><span>#</span></a></h2><p>时序图显示对象之间随时间的交互。</p><div><div><div>数据库服务器网页应用用户数据库服务器网页应用用户alt[认证成功][认证失败]提交登录请求发送认证请求查询用户凭据返回用户数据返回认证结果显示欢迎页面请求用户数据获取用户偏好返回偏好设置返回用户数据加载个性化界面显示错误消息提示重新输入
</div><div>数据库服务器网页应用用户数据库服务器网页应用用户alt[认证成功][认证失败]提交登录请求发送认证请求查询用户凭据返回用户数据返回认证结果显示欢迎页面请求用户数据获取用户偏好返回偏好设置返回用户数据加载个性化界面显示错误消息提示重新输入
</div></div></div></section>
<section><h2>ER 图示例<a href="#er-图示例"><span>#</span></a></h2><p>ER 图（实体关系图）非常适合表示数据库结构。</p><div><div><div>

<div><span><p>writes</p></span></div><div><span><p>posts</p></span></div><div><span><p>has</p></span></div><div><span><p>belongs to</p></span></div>
<div><span><p>USER</p></span></div><div><span><p>int</p></span></div><div><span><p>id</p></span></div><div><span><p>PK</p></span></div><div><span></span></div><div><span><p>string</p></span></div><div><span><p>username</p></span></div><div><span></span></div><div><span></span></div><div><span><p>string</p></span></div><div><span><p>email</p></span></div><div><span></span></div><div><span></span></div><div><span><p>datetime</p></span></div><div><span><p>created_at</p></span></div><div><span></span></div><div><span></span></div><div><span><p>ARTICLE</p></span></div><div><span><p>int</p></span></div><div><span><p>id</p></span></div><div><span><p>PK</p></span></div><div><span></span></div><div><span><p>string</p></span></div><div><span><p>title</p></span></div><div><span></span></div><div><span></span></div><div><span><p>text</p></span></div><div><span><p>content</p></span></div><div><span></span></div><div><span></span></div><div><span><p>datetime</p></span></div><div><span><p>published</p></span></div><div><span></span></div><div><span></span></div><div><span><p>int</p></span></div><div><span><p>author_id</p></span></div><div><span><p>FK</p></span></div><div><span></span></div><div><span><p>COMMENT</p></span></div><div><span><p>int</p></span></div><div><span><p>id</p></span></div><div><span><p>PK</p></span></div><div><span></span></div><div><span><p>text</p></span></div><div><span><p>content</p></span></div><div><span></span></div><div><span></span></div><div><span><p>datetime</p></span></div><div><span><p>created_at</p></span></div><div><span></span></div><div><span></span></div><div><span><p>int</p></span></div><div><span><p>user_id</p></span></div><div><span><p>FK</p></span></div><div><span></span></div><div><span><p>int</p></span></div><div><span><p>article_id</p></span></div><div><span><p>FK</p></span></div><div><span></span></div><div><span><p>CATEGORY</p></span></div><div><span><p>int</p></span></div><div><span><p>id</p></span></div><div><span><p>PK</p></span></div><div><span></span></div><div><span><p>string</p></span></div><div><span><p>name</p></span></div><div><span></span></div><div><span></span></div><div><span><p>string</p></span></div><div><span><p>description</p></span></div><div><span></span></div><div><span></span></div>

</div><div>

<div><span><p>writes</p></span></div><div><span><p>posts</p></span></div><div><span><p>has</p></span></div><div><span><p>belongs to</p></span></div>
<div><span><p>USER</p></span></div><div><span><p>int</p></span></div><div><span><p>id</p></span></div><div><span><p>PK</p></span></div><div><span></span></div><div><span><p>string</p></span></div><div><span><p>username</p></span></div><div><span></span></div><div><span></span></div><div><span><p>string</p></span></div><div><span><p>email</p></span></div><div><span></span></div><div><span></span></div><div><span><p>datetime</p></span></div><div><span><p>created_at</p></span></div><div><span></span></div><div><span></span></div><div><span><p>ARTICLE</p></span></div><div><span><p>int</p></span></div><div><span><p>id</p></span></div><div><span><p>PK</p></span></div><div><span></span></div><div><span><p>string</p></span></div><div><span><p>title</p></span></div><div><span></span></div><div><span></span></div><div><span><p>text</p></span></div><div><span><p>content</p></span></div><div><span></span></div><div><span></span></div><div><span><p>datetime</p></span></div><div><span><p>published</p></span></div><div><span></span></div><div><span></span></div><div><span><p>int</p></span></div><div><span><p>author_id</p></span></div><div><span><p>FK</p></span></div><div><span></span></div><div><span><p>COMMENT</p></span></div><div><span><p>int</p></span></div><div><span><p>id</p></span></div><div><span><p>PK</p></span></div><div><span></span></div><div><span><p>text</p></span></div><div><span><p>content</p></span></div><div><span></span></div><div><span></span></div><div><span><p>datetime</p></span></div><div><span><p>created_at</p></span></div><div><span></span></div><div><span></span></div><div><span><p>int</p></span></div><div><span><p>user_id</p></span></div><div><span><p>FK</p></span></div><div><span></span></div><div><span><p>int</p></span></div><div><span><p>article_id</p></span></div><div><span><p>FK</p></span></div><div><span></span></div><div><span><p>CATEGORY</p></span></div><div><span><p>int</p></span></div><div><span><p>id</p></span></div><div><span><p>PK</p></span></div><div><span></span></div><div><span><p>string</p></span></div><div><span><p>name</p></span></div><div><span></span></div><div><span></span></div><div><span><p>string</p></span></div><div><span><p>description</p></span></div><div><span></span></div><div><span></span></div>

</div></div></div></section>
<section><h2>类图示例<a href="#类图示例"><span>#</span></a></h2><p>类图显示系统的静态结构，包括类、属性、方法及其关系。</p><div><div><div><div><span><p>写作</p></span></div><div><span><p>发表</p></span></div><div><span><p>拥有</p></span></div><div><span><p>属于</p></span></div><div><span><p>1</p></span></div><div><span><p>1</p></span></div><div><span><p>1</p></span></div><div><span><p>1</p></span></div><div><span><p>*</p></span></div><div><span><p>*</p></span></div><div><span><p>*</p></span></div><div><span><p>*</p></span></div><div><span><p>User</p></span></div><div><span><p>+String username</p></span></div><div><span><p>+String password</p></span></div><div><span><p>+String email</p></span></div><div><span><p>+Boolean active</p></span></div><div><span><p>+login()</p></span></div><div><span><p>+logout()</p></span></div><div><span><p>+updateProfile()</p></span></div><div><span><p>Article</p></span></div><div><span><p>+String title</p></span></div><div><span><p>+String content</p></span></div><div><span><p>+Date publishDate</p></span></div><div><span><p>+Boolean published</p></span></div><div><span><p>+publish()</p></span></div><div><span><p>+edit()</p></span></div><div><span><p>+delete()</p></span></div><div><span><p>Comment</p></span></div><div><span><p>+String content</p></span></div><div><span><p>+Date commentDate</p></span></div><div><span><p>+addComment()</p></span></div><div><span><p>+deleteComment()</p></span></div><div><span><p>Category</p></span></div><div><span><p>+String name</p></span></div><div><span><p>+String description</p></span></div><div><span><p>+addArticle()</p></span></div><div><span><p>+removeArticle()</p></span></div></div><div><div><span><p>写作</p></span></div><div><span><p>发表</p></span></div><div><span><p>拥有</p></span></div><div><span><p>属于</p></span></div><div><span><p>1</p></span></div><div><span><p>1</p></span></div><div><span><p>1</p></span></div><div><span><p>1</p></span></div><div><span><p>*</p></span></div><div><span><p>*</p></span></div><div><span><p>*</p></span></div><div><span><p>*</p></span></div><div><span><p>User</p></span></div><div><span><p>+String username</p></span></div><div><span><p>+String password</p></span></div><div><span><p>+String email</p></span></div><div><span><p>+Boolean active</p></span></div><div><span><p>+login()</p></span></div><div><span><p>+logout()</p></span></div><div><span><p>+updateProfile()</p></span></div><div><span><p>Article</p></span></div><div><span><p>+String title</p></span></div><div><span><p>+String content</p></span></div><div><span><p>+Date publishDate</p></span></div><div><span><p>+Boolean published</p></span></div><div><span><p>+publish()</p></span></div><div><span><p>+edit()</p></span></div><div><span><p>+delete()</p></span></div><div><span><p>Comment</p></span></div><div><span><p>+String content</p></span></div><div><span><p>+Date commentDate</p></span></div><div><span><p>+addComment()</p></span></div><div><span><p>+deleteComment()</p></span></div><div><span><p>Category</p></span></div><div><span><p>+String name</p></span></div><div><span><p>+String description</p></span></div><div><span><p>+addArticle()</p></span></div><div><span><p>+removeArticle()</p></span></div></div></div></div></section>
<section><h2>状态图示例<a href="#状态图示例"><span>#</span></a></h2><p>状态图显示对象在其生命周期中经历的状态序列。</p><div><div><div><div><span></span></div><div><span><p>提交</p></span></div><div><span><p>拒绝</p></span></div><div><span><p>批准</p></span></div><div><span><p>发布</p></span></div><div><span><p>归档</p></span></div><div><span><p>撤回</p></span></div><div><span></span></div><div><span><p>草稿</p></span></div><div><span><p>审核中</p></span></div><div><span><p>已批准</p></span></div><div><span><p>已归档</p></span></div><div><span>已发布</span></div><div><span></span></div><div><span><p>临时隐藏</p></span></div><div><span><p>恢复</p></span></div><div><span></span></div><div><span></span></div><div><span><p>活跃</p></span></div><div><span><p>隐藏</p></span></div>
</div><div><div><span></span></div><div><span><p>提交</p></span></div><div><span><p>拒绝</p></span></div><div><span><p>批准</p></span></div><div><span><p>发布</p></span></div><div><span><p>归档</p></span></div><div><span><p>撤回</p></span></div><div><span></span></div><div><span><p>草稿</p></span></div><div><span><p>审核中</p></span></div><div><span><p>已批准</p></span></div><div><span><p>已归档</p></span></div><div><span>已发布</span></div><div><span></span></div><div><span><p>临时隐藏</p></span></div><div><span><p>恢复</p></span></div><div><span></span></div><div><span></span></div><div><span><p>活跃</p></span></div><div><span><p>隐藏</p></span></div>
</div></div></div></section>
<section><h2>XY 图示例<a href="#xy-图示例"><span>#</span></a></h2><p>XY 图表非常适合展示趋势和对比数据。</p><div><div><div>月度访问量趋势1月2月3月4月5月6月5000450040003500300025002000150010005000访问量
</div><div>月度访问量趋势1月2月3月4月5月6月5000450040003500300025002000150010005000访问量
</div></div></div></section>
<section><h2>饼图示例<a href="#饼图示例"><span>#</span></a></h2><p>饼图适合直观展示各部分在整体中的占比。</p><div><div><div>45%30%15%10%内容类型占比技术文章 [45]项目记录 [30]生活随笔 [15]其他 [10]
</div><div>45%30%15%10%内容类型占比技术文章 [45]项目记录 [30]生活随笔 [15]其他 [10]
</div></div></div></section>
<section><h2>甘特图示例<a href="#甘特图示例"><span>#</span></a></h2><p>甘特图可以按时间轴展示项目阶段、任务依赖和当前进度。</p><div><div><div>07/0107/0307/0507/0707/0907/1107/1307/1507/17需求整理 视觉设计 功能实现 内容迁移 构建检查 正式上线 准备开发发布博客版本发布计划
</div><div>07/0107/0307/0507/0707/0907/1107/1307/1507/17需求整理 视觉设计 功能实现 内容迁移 构建检查 正式上线 准备开发发布博客版本发布计划
</div></div></div></section>
<section><h2>思维导图示例<a href="#思维导图示例"><span>#</span></a></h2><p>思维导图适合梳理主题层级和知识结构。</p><div><div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>Firefly</p></span></div><div><span><p>内容</p></span></div><div><span><p>技术文章</p></span></div><div><span><p>生活记录</p></span></div><div><span><p>体验</p></span></div><div><span><p>搜索</p></span></div><div><span><p>深色模式</p></span></div><div><span><p>图表</p></span></div><div><span><p>工程</p></span></div><div><span><p>Astro</p></span></div><div><span><p>Svelte</p></span></div><div><span><p>Merman</p></span></div>
</div><div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span></span></div><div><span><p>Firefly</p></span></div><div><span><p>内容</p></span></div><div><span><p>技术文章</p></span></div><div><span><p>生活记录</p></span></div><div><span><p>体验</p></span></div><div><span><p>搜索</p></span></div><div><span><p>深色模式</p></span></div><div><span><p>图表</p></span></div><div><span><p>工程</p></span></div><div><span><p>Astro</p></span></div><div><span><p>Svelte</p></span></div><div><span><p>Merman</p></span></div>
</div></div></div></section>
<section><h2>时间线示例<a href="#时间线示例"><span>#</span></a></h2><p>时间线用于按年份或阶段呈现项目的重要事件。</p><div><div><div>2024建立博客完成基础主题2025加入搜索与图库完善内容系统2026升级   Astro   7使用   Merman   渲染图表Firefly 演进时间线
</div><div>2024建立博客完成基础主题2025加入搜索与图库完善内容系统2026升级   Astro   7使用   Merman   渲染图表Firefly 演进时间线
</div></div></div></section>
<section><h2>用户旅程图示例<a href="#用户旅程图示例"><span>#</span></a></h2><p>用户旅程图能够描述用户在不同阶段的行为和体验评分。</p><div><div><div>读者<div><div>发现内容</div></div>发现内容读者<div><div>      打开首页</div></div>      打开首页读者<div><div>      搜索主题</div></div>      搜索主题<div><div>阅读文章</div></div>阅读文章读者<div><div>      浏览正文</div></div>      浏览正文读者<div><div>      查看图表</div></div>      查看图表<div><div>继续探索</div></div>继续探索读者<div><div>      查看相关文章</div></div>      查看相关文章读者<div><div>      分享文章</div></div>      分享文章读者浏览文章的旅程
</div><div>读者<div><div>发现内容</div></div>发现内容读者<div><div>      打开首页</div></div>      打开首页读者<div><div>      搜索主题</div></div>      搜索主题<div><div>阅读文章</div></div>阅读文章读者<div><div>      浏览正文</div></div>      浏览正文读者<div><div>      查看图表</div></div>      查看图表<div><div>继续探索</div></div>继续探索读者<div><div>      查看相关文章</div></div>      查看相关文章读者<div><div>      分享文章</div></div>      分享文章读者浏览文章的旅程
</div></div></div></section>
<section><h2>Git 图示例<a href="#git-图示例"><span>#</span></a></h2><p>Git 图可以清晰展示分支、提交和合并历史。</p><div><div><div>mainfeatureinitadd-diagramspolish-themesmerge-featurerelease
</div><div>mainfeatureinitadd-diagramspolish-themesmerge-featurerelease
</div></div></div></section>
<section><h2>看板示例<a href="#看板示例"><span>#</span></a></h2><p>看板适合展示任务在不同工作阶段之间的分布。</p><div><div><div><div><span><p>待办</p></span></div><div><span><p>进行中</p></span></div><div><span><p>已完成</p></span></div><div><span><p>整理需求</p></span></div><div><span></span></div><div><span></span></div><div><span><p>准备示例</p></span></div><div><span></span></div><div><span></span></div><div><span><p>接入 Merman</p></span></div><div><span></span></div><div><span></span></div><div><span><p>服务端渲染</p></span></div><div><span></span></div><div><span></span></div><div><span><p>亮暗主题</p></span></div><div><span></span></div><div><span></span></div>
</div><div><div><span><p>待办</p></span></div><div><span><p>进行中</p></span></div><div><span><p>已完成</p></span></div><div><span><p>整理需求</p></span></div><div><span></span></div><div><span></span></div><div><span><p>准备示例</p></span></div><div><span></span></div><div><span></span></div><div><span><p>接入 Merman</p></span></div><div><span></span></div><div><span></span></div><div><span><p>服务端渲染</p></span></div><div><span></span></div><div><span></span></div><div><span><p>亮暗主题</p></span></div><div><span></span></div><div><span></span></div>
</div></div></div></section>
<section><h2>Sankey 图示例<a href="#sankey-图示例"><span>#</span></a></h2><p>Sankey 图通过连线宽度展示流量在不同节点之间的流向。</p><div><div><div>Home
1650Post list
1200Search
450Post detail
1220Related posts
260External shares
180</div><div>Home
1650Post list
1200Search
450Post detail
1220Related posts
260External shares
180</div></div></div></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>Mermaid 是在 Markdown 文档中创建各种类型图表的强大工具。本文演示了流程图、时序图、ER 图、类图、状态图、XY 图、饼图、甘特图、思维导图、时间线、用户旅程图、Git 图、看板和 Sankey 图。这些图表可以帮助您更清晰地表达复杂的概念、流程和数据结构。</p><p>要使用 Mermaid，只需在代码块中指定 mermaid 语言，并使用简洁的文本语法描述图表。图表会在构建时自动渲染为 SVG，无需客户端 JavaScript 加载。</p><p>可以前往 <a href="http://frankorz.com/merman/" target="_blank">Merman Playground</a> 尝试更多语法，再将图表代码粘贴到文章中。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/markdown-plantuml/</id>
      <title type="text">Markdown PlantUML 图表</title>
      <published>1970-01-01T00:00:00.000Z</published>
      <updated>1970-01-01T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/markdown-plantuml/"/>
      <summary type="text">用于验证 Firefly 中 PlantUML 插件渲染、主题切换与交互能力的示例文章。</summary>
      <content type="html"><![CDATA[<section><h2>Markdown 中 PlantUML 图表指南<a href="#markdown-中-plantuml-图表指南"><span>#</span></a></h2><p>PlantUML 是一种使用纯文本描述图表的工具。你只需要写一段结构化语法，就可以生成时序图、类图、用例图、活动图等常见工程图。</p><p>它特别适合写在技术博客和项目文档里：</p><ul>
<li>图表和正文一起版本管理，便于协作与审阅</li>
<li>修改图只需要改文本，适合频繁迭代</li>
<li>能和 Markdown 无缝结合，保持文档统一</li>
</ul><p>在 Firefly 中，<code>plantuml</code> 代码块会在构建阶段编码并生成服务器 SVG 地址，页面端再根据亮暗主题自动切换图源，并支持缩放、拖拽和全屏交互。</p><p>如果你想快速上手，可以记住这个最小模板：</p><div><div><img alt="@startuml
Alice -&gt; Bob: Hello
Bob --&gt; Alice: Hi
@enduml" src="https://www.plantuml.com/plantuml/svg/SoWkIImgAStDuNBCoKnELT2rKt3AJx9Iy4ZDoSddSifFKj3LjLC0orafU6HoEQJcfPJcvW00" loading="lazy" /></div></div></section>
<section><h2>活动图示例<a href="#活动图示例"><span>#</span></a></h2><div><div><img alt="@startuml
start
:用户提交订单;
if (库存充足?) then (是)
	:冻结库存;
	:创建支付单;
	if (支付成功?) then (是)
		:生成发货单;
		:通知仓库拣货;
	else (否)
		:取消订单;
		:释放库存;
	endif
else (否)
	:提示缺货;
endif
stop
@enduml" src="https://www.plantuml.com/plantuml/svg/NOuz2i9048NhtLEaZ5VO57eLmHM56CN4taODYYHYbA15mFz6BHI5ZNYQp6oyXMI38dRpcFTzl9BjbDjEfs5ITL0cWmEwT_JyH6pIqmh6CuFMgveEOWh747gzz7Of5ZIdnYrDn_1Se8H1FvRnD6yOMNQN40iCpaaSAW7937b6ruTXz6SWJ0PHzl4cwNMV8uIzkWiPRHDbnj4wlUuDIhXfSqq7VwSmyEPuSpyxCsOmnE3vdSAjIhrAVnc6dYytGZw4ykK5sscsQ8bRbKx3V0C0" loading="lazy" /></div></div></section>
<section><h2>状态图示例<a href="#状态图示例"><span>#</span></a></h2><div><div><img alt="@startuml
[*] --&gt; 草稿

草稿 --&gt; 待审核 : 提交
待审核 --&gt; 草稿 : 驳回
待审核 --&gt; 已发布 : 审核通过
已发布 --&gt; 已归档 : 到期归档
已发布 --&gt; 草稿 : 撤回修改

state 已发布 {
	[*] --&gt; 可见
	可见 --&gt; 隐藏 : 手动隐藏
	隐藏 --&gt; 可见 : 恢复展示
}

已归档 --&gt; [*]
@enduml" src="https://www.plantuml.com/plantuml/svg/SoWkIImgAStDuOhMYbNGrRLJUD7R-Np5VYuk20qMUhglzUcwXSyMx52mKdZMF-79hYLS22647WKhXPShDp-TFGzDzkdsJK_x9pxTqQnWfG0HVjamwyN-TYw414pPtadF5Yu6AUlOy6pEV0WNJHdShcUJbZoTFU_9_dNFfkpauYekIIn9HRAgceiJvgEd_UjVB6_aueJGOA6NioQycDuFCgIp-sdN2WYNYnCgZD04Kj6uwEcItgSRfpvViekhbeiBuKoGicYjM2w7rBoKqjmS0000" loading="lazy" /></div></div></section>
<section><h2>用例图示例<a href="#用例图示例"><span>#</span></a></h2><div><div><img alt="@startuml
left to right direction
actor 游客
actor 用户
actor 管理员

rectangle 博客系统 {
	usecase &quot;浏览文章&quot; as UC1
	usecase &quot;搜索内容&quot; as UC2
	usecase &quot;发表评论&quot; as UC3
	usecase &quot;点赞收藏&quot; as UC4
	usecase &quot;审核评论&quot; as UC5
	usec" src="https://www.plantuml.com/plantuml/svg/PP3BJi9058RNdASuOSz2Raj3uZFm09CoOfFI9krqPTm88XjJI8WQGv1s8ud9i02qoFFCvJ6CCf8EBh_pvJyvvsz5Z8GixddWqKk6BC3GxLunxBWXTPWR-40S5eGeyrpmp82QBkNeymzugiP3CNa6-8aGl-jH50ylWcTglLVxLxo6KXnHXqGKotARwBUHVBnNxuioaWZR5sT5FPwfJIQ6TuBlZAuMj4WcEbtgrK3pBwDh1QrkTtexbzCF_PGONI-cUIeNkPLksCj5thTEQy8DmE5rh5JEVu-ri0g7BexMmXDRix4En-hCfF5lqeGMzJjnp_i6" loading="lazy" /></div></div></section>
<section><h2>组件图示例<a href="#组件图示例"><span>#</span></a></h2><div><div><img alt="@startuml
package &quot;Firefly Site&quot; {
	[Astro App] as App
	[Markdown Parser] as Parser
	[PlantUML Encoder] as Encoder
	[Theme Switcher] as Theme
	[Search Indexer] as Search
}

cloud &quot;PlantUML Server&quot; as " src="https://www.plantuml.com/plantuml/svg/JL51QiCm43nxNp7u7dht8IIK5WeD15oVJ0-oj8sDPKcLvAIbzEz5YX9wqZ2pxCoiTY4A7zT5anDo5YT6_Jnv_j3VQAV8DNwewlSXUekzS-yG8RrKzGVXPsKl1aVX0_kiN25L_L4B4xl3AvwCjAge1LFLlusyCDhB5ELOn4nHrRSil1pnOXH_5UbAqI-Hr7PLgE_RM_PdzdMsxaY9A0OH6FMZDP5DH1kjvomNXcZl73QRROcA1Yu1BAKD5JwDbBnem1d19TzrqHYqbNEWsq3Urw61vy-LGqGud-v6rwuDGcuB9VpyeAVJ616yl4-LsWs6TT8ABdt4b6xmFz2jLZ8I2iw666Z7HgsB_WC0" loading="lazy" /></div></div></section>
<section><h2>部署图示例<a href="#部署图示例"><span>#</span></a></h2><div><div><img alt="@startuml
node &quot;User Device&quot; {
	artifact &quot;Browser&quot;
}

node &quot;CDN / Edge&quot; {
	artifact &quot;Static Assets&quot;
}

node &quot;Cloudflare Worker&quot; {
	artifact &quot;SSR Handler&quot;
}

node &quot;PlantUML Service&quot; {
	artifact &quot;SVG Re" src="https://www.plantuml.com/plantuml/svg/ROz1Jy9044RFxg_uqZlfdOD1WS11r53Hyz2TraAxYpDJE1Z_kqb3J6azxtkpxvkfaLZRr2v4pqXsoe85dwkS4toxEnAh2ieDoQF4Yx8axiTTsVdY6IcMlXoYcP5LEHvKsRGlrB7rHKt2-8XoP1bwsHPh2hw--UQrfc2xpHCobd-wilSLjXmyozNoPBGdPIGl-mFdXioYq2XoGtBqyH8mZy4uMEV-hSHaSZySWYbMopSSDCrLqwefHtYl7rC8VxMiXXELx6uVEtnKq3daSOfgezlzcPYYOCi_uIigXHhekNGp3hvjwby0" loading="lazy" /></div></div></section>
<section><h2>ER 图示例<a href="#er-图示例"><span>#</span></a></h2><div><div><img alt="@startuml
entity User {
	*id : uuid &lt;&lt;PK&gt;&gt;
	--
	username : varchar
	email : varchar
	created_at : datetime
}

entity Post {
	*id : uuid &lt;&lt;PK&gt;&gt;
	--
	author_id : uuid &lt;&lt;FK&gt;&gt;
	title : varchar
	content : " src="https://www.plantuml.com/plantuml/svg/VP2x2W9134NhoLUa5lO71X51iB6niPRiJc07vY6JZ0_KVvTTKHGVRKwIavkvA1MjCG0dzNh2ZN31CvY9TsYnLkzmEbslPZCmJGEc2fT4aT7YdahNKm73aNnuBNI5ITbjIT6Y8sNraU4A3ySwY_vnKDK-b-qhN8vGlOOtSvUJSXeioaS5iwjjyDB_KIzoZCF4R_ikYtvn3y6_bDliJa_zpzpZKo-NfiddUtYBX-ALvOqyRhDuNoGmzdxGdWJcd5oDuGO0" loading="lazy" /></div></div></section>
<section><h2>时序图示例（登录与刷新令牌）<a href="#时序图示例登录与刷新令牌"><span>#</span></a></h2><div><div><img alt="@startuml
autonumber
actor User as 用户
participant Web as 前端页面
participant API as 网关接口
participant Auth as 认证服务
database Redis as 会话缓存

用户 -&gt; 前端页面 : 输入账号密码并提交
前端页面 -&gt; 网关接口 : POST /login
网关接口 -&gt; 认证服务 : " src="https://www.plantuml.com/plantuml/svg/bP3BJi9068NtynJ_thGIbrqqk7GbyHANPYYZ4A4bxVG1M70D5GrAn42u2CPee2HUY0BwCioql8L1t0ma1jVVEJFVVu8MnIQr4t64RMheTY9CJ8GrQfXmQ14Ji0NUrGFF3L4IcpIcnP9Oft14mdF2yextvCvQhxDwM-3RePsVvkIIfP_vUPULxaHkq-WyuFSxlflYDOSLMYY2AGvZYy0UYSIiEPwERtstxetBh7U3qC8395Nu5nJmFyiitVLVxbbfoDoCrqonzpTUkfX-T90GbLH12HG8xUuVm6RSE8tfI42IAiY10hpPcZqMMRR7dJuIcAGAfg00orHPkWicEJ695JscnXdHbpghBbZJY6Kjmh2nL1RbLZVO2WJ0guxOv9hdBbYXWP0io-AJ_bUMrneWop9QRvPVW_M6-VFObO7yIPyxxNyEn2i3uQArHk6LmNJKyV9552Hwn4x4lm40" loading="lazy" /></div></div></section>
<section><h2>C4 风格容器图示例<a href="#c4-风格容器图示例"><span>#</span></a></h2><div><div><img alt="@startuml
!includeurl https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

Person(user, &quot;博客访客&quot;, &quot;阅读文章与搜索内容&quot;)

System_Boundary(system, &quot;Firefly Blog&quot;) {
	Container(we" src="https://www.plantuml.com/plantuml/svg/PL7BJjj055tNNp7robP3l67L5I7b9GKHnQ6egyYE9udBn8x6Oq9KLQeeeLMbGDHIYWfL6fTAIAXs7w2cGOAVoTZENrHZfsaYTZFtddlkkUVCMKJ1nAuYxhvk596jGHiZK26aPZsK9ApKasMTL6pLjY0kcWQ11aaMpQfKGuh1ncOieY5TbTApCrbMMb_DI5N58X1BwTb2sZI8eXiG9sji1PU5s38DWP4b04zR7wdhXEujTHq-0VZXSJFqhlsZLy75vq5lts-V1fSEtMjIzmylSfpSi0Yi5kPDsz0Kt12iw9y0_AAEOGarm3mooxm8dd7tndk5EbGJWD-0AaZLQcn9oYBO10-0l0KHWQpYztxwdNV3xjNmapFexG_wPuF-MrwSOZ7nPYHPbdDW8_gmoJGoRQs450n7HOjLwTbkqDxpJrlqJJUuy6BwqFlj_zYPOdsa2YD76LNy0Z8nSQHgLS6RcbatW0JMrAUm6BUKSjIatuxfpldOgV1gr--tQVEb__wxttAdjLjGmSKAqnuzm8gXmMr6abNAiAGRMkJ1GNjmSqARZDF_yYAuT7YHUpxsV66R2FyIPvEZf84CyLPiHN3OyL-tWVnu2T2Jcx1xpXBBGJJAEeuXT6-77rm6Nyxdip8lHeYeDtOuDWeme-D8xi17oF_UXTurFJYAtPZa75_kTxw6daERluQ7RkYr9Z4JLyMRO_Ni47P19lLaRJrVo2mivWkvbQNbl21oSz3Gx2hw2m00" loading="lazy" /></div></div></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/markdown-tutorial/</id>
      <title type="text">Markdown 教程</title>
      <published>1970-01-01T00:00:00.000Z</published>
      <updated>1970-01-01T00:00:00.000Z</updated>
      <author><name>emn178</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/markdown-tutorial/"/>
      <summary type="text">一个简明的 Markdown 博客示例。</summary>
      <content type="html"><![CDATA[<p>这是一个展示如何编写 Markdown 文件的示例。本文档汇总了核心语法与常见扩展（GFM）。</p>
<ul>
<li><a href="#block-elements">块级元素</a>
<ul>
<li><a href="#paragraphs-and-line-breaks">段落与换行</a></li>
<li><a href="#headers">标题</a></li>
<li><a href="#blockquotes">引用</a></li>
<li><a href="#lists">列表</a></li>
<li><a href="#code-blocks">代码块</a></li>
<li><a href="#horizontal-rules">分割线</a></li>
<li><a href="#table">表格</a></li>
</ul>
</li>
<li><a href="#span-elements">内联元素</a>
<ul>
<li><a href="#links">链接</a></li>
<li><a href="#emphasis">强调</a></li>
<li><a href="#code">行内代码</a></li>
<li><a href="#images">图片</a></li>
<li><a href="#strikethrough">删除线</a></li>
</ul>
</li>
<li><a href="#miscellaneous">杂项</a>
<ul>
<li><a href="#automatic-links">自动链接</a></li>
<li><a href="#backslash-escapes">反斜杠转义</a></li>
</ul>
</li>
<li><a href="#inline-html">内联 HTML</a></li>
</ul>
<p><a></a></p>
<section><h2>块级元素<a href="#块级元素"><span>#</span></a></h2><p><a></a></p><section><h3>段落与换行<a href="#段落与换行"><span>#</span></a></h3><section><h4>段落<a href="#段落"><span>#</span></a></h4><p>HTML 标签：<code>&lt;p&gt;</code></p><p>使用一个或多个空行分隔段落。（仅包含<strong>空格</strong>或<strong>制表符</strong>的行也视为空行。）</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>This will be</span></div></div><div><div><div>2</div></div><div><span>inline.</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>This is second paragraph.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p>This will be
inline.</p><p>This is second paragraph.</p><hr /></section><section><h4>换行<a href="#换行"><span>#</span></a></h4><p>HTML 标签：<code>&lt;br /&gt;</code></p><p>在行末添加<strong>两个或更多空格</strong>来产生换行。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>This will be not</span></div></div><div><div><div>2</div></div><div><span>inline.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p>This will be not<br />
inline.</p><hr /><p><a></a></p></section></section><section><h3>标题<a href="#标题"><span>#</span></a></h3><p>Markdown 支持两种标题样式：Setext 与 atx。</p><section><h4>Setext<a href="#setext"><span>#</span></a></h4><p>HTML 标签：<code>&lt;h1&gt;</code>，<code>&lt;h2&gt;</code></p><p>使用<strong>等号 (=)</strong> 表示 <code>&lt;h1&gt;</code>、使用<strong>短横线 (-)</strong> 表示 <code>&lt;h2&gt;</code>，数量不限，作为“下划线”。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>This is an H1</span></div></div><div><div><div>2</div></div><div><span>=============</span></div></div><div><div><div>3</div></div><div><span>This is an H2</span></div></div><div><div><div>4</div></div><div><span>-------------</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /></section></section></section>
<section><h1>This is an H1<a href="#this-is-an-h1"><span>#</span></a></h1><section><h2>This is an H2<a href="#this-is-an-h2"><span>#</span></a></h2><hr /><section><h4>atx<a href="#atx"><span>#</span></a></h4><p>HTML 标签：<code>&lt;h1&gt;</code>，<code>&lt;h2&gt;</code>，<code>&lt;h3&gt;</code>，<code>&lt;h4&gt;</code>，<code>&lt;h5&gt;</code>，<code>&lt;h6&gt;</code></p><p>在行首使用 1-6 个<strong>井号 (#)</strong>，对应 <code>&lt;h1&gt;</code> 至 <code>&lt;h6&gt;</code>。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># This is an H1</span></div></div><div><div><div>2</div></div><div><span>## This is an H2</span></div></div><div><div><div>3</div></div><div><span>###### This is an H6</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /></section></section></section>
<section><h1>This is an H1<a href="#this-is-an-h1-1"><span>#</span></a></h1><section><h2>This is an H2<a href="#this-is-an-h2-1"><span>#</span></a></h2><section><h6>This is an H6<a href="#this-is-an-h6"><span>#</span></a></h6><hr /><p>可选：你可以在行尾“闭合” atx 标题。末尾的井号数量<strong>不必与</strong>开头一致。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># This is an H1 #</span></div></div><div><div><div>2</div></div><div><span>## This is an H2 ##</span></div></div><div><div><div>3</div></div><div><span>### This is an H3 ######</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /></section></section></section>
<section><h1>This is an H1<a href="#this-is-an-h1-2"><span>#</span></a></h1><section><h2>This is an H2<a href="#this-is-an-h2-2"><span>#</span></a></h2><section><h3>This is an H3<a href="#this-is-an-h3"><span>#</span></a></h3><hr /><p><a></a></p></section><section><h3>引用<a href="#引用"><span>#</span></a></h3><p>HTML 标签：<code>&lt;blockquote&gt;</code></p><p>Markdown 使用邮件风格的 <strong>&gt;</strong> 作为引用符号。若手动换行并在每行前加 &gt;，显示效果最佳。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&gt; This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,</span></div></div><div><div><div>2</div></div><div><span>&gt; consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.</span></div></div><div><div><div>3</div></div><div><span>&gt; Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</span></div></div><div><div><div>4</div></div><div><span>&gt;</span></div></div><div><div><div>5</div></div><div><span>&gt; Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse</span></div></div><div><div><div>6</div></div><div><span>&gt; id sem consectetuer libero luctus adipiscing.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><blockquote><p>This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p><p>Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
id sem consectetuer libero luctus adipiscing.</p></blockquote><hr /><p>Markdown 允许“偷懒”：在一个硬换行段落中，只在第一行前加 &gt; 即可。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&gt; This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,</span></div></div><div><div><div>2</div></div><div><span>consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.</span></div></div><div><div><div>3</div></div><div><span>Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>&gt; Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse</span></div></div><div><div><div>6</div></div><div><span>id sem consectetuer libero luctus adipiscing.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><blockquote><p>This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p></blockquote><blockquote><p>Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
id sem consectetuer libero luctus adipiscing.</p></blockquote><hr /><p>引用可以嵌套（引用中的引用），通过增加 &gt; 层级实现。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&gt; This is the first level of quoting.</span></div></div><div><div><div>2</div></div><div><span>&gt;</span></div></div><div><div><div>3</div></div><div><span>&gt; &gt; This is nested blockquote.</span></div></div><div><div><div>4</div></div><div><span>&gt;</span></div></div><div><div><div>5</div></div><div><span>&gt; Back to the first level.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><blockquote><p>This is the first level of quoting.</p><blockquote><p>This is nested blockquote.</p></blockquote><p>Back to the first level.</p></blockquote><hr /><p>引用内可包含其他 Markdown 元素，包括标题、列表与代码块。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&gt; ## This is a header.</span></div></div><div><div><div>2</div></div><div><span>&gt;</span></div></div><div><div><div>3</div></div><div><span>&gt; 1.   This is the first list item.</span></div></div><div><div><div>4</div></div><div><span>&gt; 2.   This is the second list item.</span></div></div><div><div><div>5</div></div><div><span>&gt;</span></div></div><div><div><div>6</div></div><div><span>&gt; Here's some example code:</span></div></div><div><div><div>7</div></div><div><span>&gt;</span></div></div><div><div><div>8</div></div><div><span>&gt;     return shell_exec("echo $input | $markdown_script");</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><blockquote><h2>This is a header.<a href="#this-is-a-header"><span>#</span></a></h2><ol>
<li>This is the first list item.</li>
<li>This is the second list item.</li>
</ol><p>Here’s some example code:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>return shell_exec("echo $input | $markdown_script");</span></div></div></code></pre><div><div></div><div></div></div></figure></div></blockquote><hr /><p><a></a></p></section><section><h3>列表<a href="#列表"><span>#</span></a></h3><p>Markdown 支持有序（数字）与无序（圆点）列表。</p><section><h4>无序列表<a href="#无序列表"><span>#</span></a></h4><p>HTML 标签：<code>&lt;ul&gt;</code></p><p>无序列表可使用 <strong>星号 (*)</strong>、<strong>加号 (+)</strong> 或 <strong>短横线 (-)</strong>。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>*   Red</span></div></div><div><div><div>2</div></div><div><span>*   Green</span></div></div><div><div><div>3</div></div><div><span>*   Blue</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><ul>
<li>Red</li>
<li>Green</li>
<li>Blue</li>
</ul><hr /><p>等价于：</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>+   Red</span></div></div><div><div><div>2</div></div><div><span>+   Green</span></div></div><div><div><div>3</div></div><div><span>+   Blue</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>或者：</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>-   Red</span></div></div><div><div><div>2</div></div><div><span>-   Green</span></div></div><div><div><div>3</div></div><div><span>-   Blue</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>有序列表<a href="#有序列表"><span>#</span></a></h4><p>HTML 标签：<code>&lt;ol&gt;</code></p><p>有序列表使用数字加英文句点：</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>1.  Bird</span></div></div><div><div><div>2</div></div><div><span>2.  McHale</span></div></div><div><div><div>3</div></div><div><span>3.  Parish</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><ol>
<li>Bird</li>
<li>McHale</li>
<li>Parish</li>
</ol><hr /><p>注意：像下面这样可能会“意外触发”有序列表：</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>1986. What a great season.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><ol>
<li>What a great season.</li>
</ol><hr /><p>你可以用<strong>反斜杠转义 (\)</strong> 句点：</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>1986\. What a great season.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p>1986. What a great season.</p><hr /></section><section><h4>列表中的缩进内容<a href="#列表中的缩进内容"><span>#</span></a></h4><section><h5>列表项里的引用<a href="#列表项里的引用"><span>#</span></a></h5><p>在列表项内放置引用，需要将 &gt; 符号整体缩进：</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>*   A list item with a blockquote:</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>&gt; This is a blockquote</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>&gt; inside a list item.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><ul>
<li>
<p>A list item with a blockquote:</p>
<blockquote><p>This is a blockquote
inside a list item.</p></blockquote>
</li>
</ul><hr /></section><section><h5>列表项里的代码块<a href="#列表项里的代码块"><span>#</span></a></h5><p>在列表项内放置代码块，需要缩进两层——<strong>8 个空格</strong>或<strong>两个 Tab</strong>：</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>*   A list item with a code block:</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>        </span></span><span>&lt;code goes here&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><ul>
<li>
<p>A list item with a code block:</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;code goes here&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul><hr /></section><section><h5>嵌套列表<a href="#嵌套列表"><span>#</span></a></h5><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>* A</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>* A1</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>* A2</span></div></div><div><div><div>4</div></div><div><span>* B</span></div></div><div><div><div>5</div></div><div><span>* C</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><ul>
<li>A
<ul>
<li>A1</li>
<li>A2</li>
</ul>
</li>
<li>B</li>
<li>C</li>
</ul><hr /><p><a></a></p></section></section></section><section><h3>代码块<a href="#代码块"><span>#</span></a></h3><p>HTML 标签：<code>&lt;pre&gt;</code></p><p>将代码块中的每行缩进至少<strong>4 个空格</strong>或<strong>1 个制表符</strong>。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>This is a normal paragraph:</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>This is a code block.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p>This is a normal paragraph:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>This is a code block.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /><p>代码块会一直持续，直到遇到未缩进的行（或文末）。</p><p>在代码块内，<strong>与号 (&amp;)</strong> 和尖括号 <strong>(&lt; &gt;)</strong> 会自动转为 HTML 实体。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>    </span></span><span>&lt;div class="footer"&gt;</span></div></div><div><div><div>2</div></div><div><span><span>        </span></span><span>&amp;copy; 2004 Foo Corporation</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>&lt;/div&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;div class="footer"&gt;</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>&amp;copy; 2004 Foo Corporation</span></div></div><div><div><div>3</div></div><div><span>&lt;/div&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /><p>下文的“围栏代码块”和“语法高亮”属于扩展语法，你也可以用它们来书写代码块。</p><section><h4>围栏代码块<a href="#围栏代码块"><span>#</span></a></h4><p>使用成对的反引号围起来（如下所示），就不需要四空格缩进了。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Here's an example:</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>```</span></div></div><div><div><div>4</div></div><div><span>function test() {</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>console.log("notice the blank line before this function?");</span></div></div><div><div><div>6</div></div><div><span>}</span></div></div><div><div><div>7</div></div><div><span>```</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p>Here’s an example:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>function test() {</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>console.log("notice the blank line before this function?");</span></div></div><div><div><div>3</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section><section><h4>语法高亮<a href="#语法高亮"><span>#</span></a></h4><p>在围栏代码块后添加可选的语言标识，即可启用语法高亮（参见支持语言列表）。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>```ruby</span></div></div><div><div><div>2</div></div><div><span>require 'redcarpet'</span></div></div><div><div><div>3</div></div><div><span>markdown = Redcarpet.new("Hello World!")</span></div></div><div><div><div>4</div></div><div><span>puts markdown.to_html</span></div></div><div><div><div>5</div></div><div><span>```</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>require </span><span>'redcarpet'</span></div></div><div><div><div>2</div></div><div><span>markdown</span><span><span> </span><span>=</span><span> </span></span><span>Redcarpet</span><span>.</span><span>new</span><span>(</span><span>"Hello World!"</span><span>)</span></div></div><div><div><div>3</div></div><div><span>puts</span><span> markdown.</span><span>to_html</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /><p><a></a></p></section></section><section><h3>分割线（水平线）<a href="#分割线水平线"><span>#</span></a></h3><p>HTML 标签：<code>&lt;hr /&gt;</code>
一行中放置<strong>三个或以上的短横线 (-)、星号 (*) 或下划线 (_)</strong>。符号之间允许有空格。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>* * *</span></div></div><div><div><div>2</div></div><div><span>***</span></div></div><div><div><div>3</div></div><div><span>*****</span></div></div><div><div><div>4</div></div><div><span>- - -</span></div></div><div><div><div>5</div></div><div><span>---------------------------------------</span></div></div><div><div><div>6</div></div><div><span>___</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><hr /><hr /><hr /><hr /><hr /><hr /><hr /><p><a></a></p></section><section><h3>表格<a href="#表格"><span>#</span></a></h3><p>HTML 标签：<code>&lt;table&gt;</code></p><p>这是扩展语法。</p><p>用<strong>竖线 (|)</strong> 分隔列，用<strong>短横线 (-)</strong> 分隔表头，使用<strong>冒号 (:)</strong> 指定对齐方式。</p><p>两侧的<strong>竖线 (|)</strong> 与对齐可选。用于表头分隔时，每列至少需要 <strong>3 个短横线</strong>。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>| Left | Center | Right |</span></div></div><div><div><div>2</div></div><div><span>|:-----|:------:|------:|</span></div></div><div><div><div>3</div></div><div><span>|aaa   |bbb     |ccc    |</span></div></div><div><div><div>4</div></div><div><span>|ddd   |eee     |fff    |</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span><span> </span></span><span>A | B</span></div></div><div><div><div>7</div></div><div><span>---|---</span></div></div><div><div><div>8</div></div><div><span>123|456</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>A |B</span></div></div><div><div><div>12</div></div><div><span>--|--</span></div></div><div><div><div>13</div></div><div><span>12|45</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr />

<table><thead><tr><th>Left</th><th>Center</th><th>Right</th></tr></thead><tbody><tr><td>aaa</td><td>bbb</td><td>ccc</td></tr><tr><td>ddd</td><td>eee</td><td>fff</td></tr></tbody></table>

<table><thead><tr><th>A</th><th>B</th></tr></thead><tbody><tr><td>123</td><td>456</td></tr></tbody></table>

<table><thead><tr><th>A</th><th>B</th></tr></thead><tbody><tr><td>12</td><td>45</td></tr></tbody></table><hr /><p><a></a></p></section></section><section><h2>内联元素<a href="#内联元素"><span>#</span></a></h2><p><a></a></p><section><h3>链接<a href="#链接"><span>#</span></a></h3><p>HTML 标签：<code>&lt;a&gt;</code></p><p>Markdown 支持两种链接样式：行内链接与引用式链接。</p><section><h4>行内链接<a href="#行内链接"><span>#</span></a></h4><p>行内链接格式：<code>[文本](URL "标题")</code></p><p>标题可选。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>This is [an example](http://example.com/ "Title") inline link.</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>[This link](http://example.net/) has no title attribute.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p>This is <a href="http://example.com/" target="_blank">an example</a> inline link.</p><p><a href="http://example.net/" target="_blank">This link</a> has no title attribute.</p><hr /><p>如果引用同一站点的本地资源，可以使用相对路径：</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>See my [About](/about/) page for details.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p>See my <a href="/about/">About</a> page for details.</p><hr /></section><section><h4>引用式链接<a href="#引用式链接"><span>#</span></a></h4><p>可以预定义链接引用。定义格式：<code>[id]: URL "标题"</code></p><p>标题同样可选。引用时使用：<code>[文本][id]</code></p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[id]: http://example.com/  "Optional Title Here"</span></div></div><div><div><div>2</div></div><div><span>This is [an example][id] reference-style link.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p>This is <a href="http://example.com/" target="_blank">an example</a> reference-style link.</p><hr /><p>说明：</p><ul>
<li>方括号中包含链接标识（<strong>不区分大小写</strong>，可在左侧缩进最多三格空格）；</li>
<li>随后是冒号；</li>
<li>再跟一个或多个空格（或 tab）；</li>
<li>然后是链接 URL；</li>
<li>URL 可选地用尖括号包裹；</li>
<li>可选地跟随标题属性，用引号或圆括号包裹。</li>
</ul><p>以下三种定义等价：</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[foo]: http://example.com/  "Optional Title Here"</span></div></div><div><div><div>2</div></div><div><span>[foo]: http://example.com/  'Optional Title Here'</span></div></div><div><div><div>3</div></div><div><span>[foo]: http://example.com/  (Optional Title Here)</span></div></div><div><div><div>4</div></div><div><span>[foo]: &lt;http://example.com/&gt;  "Optional Title Here"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果使用空的方括号，则链接文本本身会作为名称。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[Google]: http://google.com/</span></div></div><div><div><div>2</div></div><div><span>[Google][]</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p><a href="http://google.com/" target="_blank">Google</a></p><hr /><p><a></a></p></section></section><section><h3>强调<a href="#强调"><span>#</span></a></h3><p>HTML 标签：<code>&lt;em&gt;</code>，<code>&lt;strong&gt;</code></p><p>Markdown 使用 <strong>星号 (*)</strong> 或 <strong>下划线 (_)</strong> 表示强调。<strong>一个分隔符</strong>对应 <code>&lt;em&gt;</code>；<strong>两个分隔符</strong>对应 <code>&lt;strong&gt;</code>。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>*single asterisks*</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>_single underscores_</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>**double asterisks**</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>__double underscores__</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p><em>single asterisks</em></p><p><em>single underscores</em></p><p><strong>double asterisks</strong></p><p><strong>double underscores</strong></p><hr /><p>但如果两侧有空格，则会被视作普通字符而非强调语法。</p><p>你可以使用反斜杠进行转义：</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>\*this text is surrounded by literal asterisks\*</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p>*this text is surrounded by literal asterisks*</p><hr /><p><a></a></p></section><section><h3>行内代码<a href="#行内代码"><span>#</span></a></h3><p>HTML 标签：<code>&lt;code&gt;</code></p><p>用<strong>反引号 (`)</strong> 包裹。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Use the `printf()` function.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p>Use the <code>printf()</code> function.</p><hr /><p>若行内代码中需要包含反引号字符，可使用<strong>多重反引号</strong>作为定界符：</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>``There is a literal backtick (`) here.``</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p><code>There is a literal backtick (`) here.</code></p><hr /><p>行内代码两侧的定界符允许包含空格（开头一个、结尾一个），方便在代码起始或结尾放置反引号字符：</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>A single backtick in a code span: `` ` ``</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>A backtick-delimited string in a code span: `` `foo` ``</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p>A single backtick in a code span: <code>`</code></p><p>A backtick-delimited string in a code span: <code>`foo`</code></p><hr /><p><a></a></p></section><section><h3>图片<a href="#图片"><span>#</span></a></h3><p>HTML 标签：<code>&lt;img /&gt;</code></p><p>Markdown 的图片语法与链接类似，支持行内与引用两种方式。</p><section><h4>行内图片<a href="#行内图片"><span>#</span></a></h4><p>行内图片语法：<code>![替代文本](URL "标题")</code></p><p>标题可选。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>![Alt text](/path/to/img.jpg)</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>![Alt text](/path/to/img.jpg "Optional title")</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p></p><figure><img src="https://s2.loli.net/2024/08/20/5fszgXeOxmL3Wdv.webp" alt="Alt text" /><figcaption>Alt text</figcaption></figure><p></p><p></p><figure><img src="https://s2.loli.net/2024/08/20/5fszgXeOxmL3Wdv.webp" alt="Alt text" title="Optional title" /><figcaption>Alt text</figcaption></figure><p></p><hr /><p>说明：</p><ul>
<li>一个感叹号 !；</li>
<li>后接方括号，放置图片的替代文本；</li>
<li>再接圆括号，内含图片 URL/路径，及可选的标题（引号包裹）。</li>
</ul></section><section><h4>引用式图片<a href="#引用式图片"><span>#</span></a></h4><p>引用式图片语法：<code>![替代文本][id]</code></p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[img id]: https://s2.loli.net/2024/08/20/5fszgXeOxmL3Wdv.webp  "Optional title attribute"</span></div></div><div><div><div>2</div></div><div><span>![Alt text][img id]</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p></p><figure><img src="https://s2.loli.net/2024/08/20/5fszgXeOxmL3Wdv.webp" alt="Alt text" title="Optional title attribute" /><figcaption>Alt text</figcaption></figure><p></p><hr /><p><a></a></p></section></section><section><h3>删除线<a href="#删除线"><span>#</span></a></h3><p>HTML 标签：<code>&lt;del&gt;</code></p><p>这是扩展语法。</p><p>GFM 增加了删除线语法。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>~~Mistaken text.~~</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p>Mistaken text.</p><hr /><p><a></a></p></section></section><section><h2>杂项<a href="#杂项"><span>#</span></a></h2><p><a></a></p><section><h3>自动链接<a href="#自动链接"><span>#</span></a></h3><p>Markdown 支持一种便捷写法来创建“自动链接”（URL 与邮箱地址）：只需用尖括号将其包住即可。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;http://example.com/&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>&lt;address@example.com&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p><a href="http://example.com/" target="_blank">http://example.com/</a></p><p><a href="#">address@example.com</a></p><hr /><p>GFM 会自动识别标准 URL 并转换为链接。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://github.com/emn178/markdown</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p><a href="https://github.com/emn178/markdown" target="_blank">https://github.com/emn178/markdown</a></p><hr /><p><a></a></p></section><section><h3>反斜杠转义<a href="#反斜杠转义"><span>#</span></a></h3><p>Markdown 允许使用反斜杠来转义那些本用于 Markdown 语法的特殊字符，使其按字面显示。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>\*literal asterisks\*</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p>*literal asterisks*</p><hr /><p>以下字符可通过反斜杠转义以按字面量输出：</p><p>Code:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>\   backslash</span></div></div><div><div><div>2</div></div><div><span>`   backtick</span></div></div><div><div><div>3</div></div><div><span>*   asterisk</span></div></div><div><div><div>4</div></div><div><span>_   underscore</span></div></div><div><div><div>5</div></div><div><span>{}  curly braces</span></div></div><div><div><div>6</div></div><div><span>[]  square brackets</span></div></div><div><div><div>7</div></div><div><span>()  parentheses</span></div></div><div><div><div>8</div></div><div><span>#   hash mark</span></div></div><div><div><div>9</div></div><div><span>+   plus sign</span></div></div><div><div><div>10</div></div><div><span>-   minus sign (hyphen)</span></div></div><div><div><div>11</div></div><div><span>.   dot</span></div></div><div><div><div>12</div></div><div><span>!   exclamation mark</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><a></a></p></section></section><section><h2>内联 HTML<a href="#内联-html"><span>#</span></a></h2><p>对于 Markdown 语法未覆盖的标记，直接使用原生 HTML 即可。无需特别声明从 Markdown 切换到 HTML，直接写标签就行。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>This is a regular paragraph.</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>&lt;table&gt;</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>&lt;tr&gt;</span></div></div><div><div><div>5</div></div><div><span><span>        </span></span><span>&lt;td&gt;Foo&lt;/td&gt;</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>&lt;/tr&gt;</span></div></div><div><div><div>7</div></div><div><span>&lt;/table&gt;</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>This is another regular paragraph.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p>This is a regular paragraph.</p><table>
    <tbody><tr>
        <td>Foo</td>
    </tr>
</tbody></table><p>This is another regular paragraph.</p><hr /><p>请注意：在<strong>块级 HTML 标签</strong>内不会处理 Markdown 语法。</p><p>与块级标签不同，在<strong>行内级标签</strong>内会处理 Markdown 语法。</p><p>代码：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;span&gt;**Work**&lt;/span&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>&lt;div&gt;</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>**No Work**</span></div></div><div><div><div>5</div></div><div><span>&lt;/div&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预览：</p><hr /><p><span><strong>Work</strong></span></p><div>
  **No Work**
</div>
***</section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/mdx-example/</id>
      <title type="text">MDX 格式文章示例</title>
      <published>1970-01-01T00:00:00.000Z</published>
      <updated>1970-01-01T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/mdx-example/"/>
      <summary type="text">这是一个 MDX 格式的示例文章，展示了如何在 Markdown 中使用 JSX。</summary>
      <content type="html"><![CDATA[<div><div><div></div><div>Tip</div></div><div><p><a href="https://github.com/CuteLeaf/Firefly" target="_blank">Firefly</a> 支持 <code>MDX</code> 和 <code>Markdown</code> 两种类型的文章，你可以在文章中混合使用两种格式，如果没有特别复杂内容和需求，推荐使用 Markdown 格式就够了。</p></div></div>
<section><h2>Markdown 和 MDX 的区别<a href="#markdown-和-mdx-的区别"><span>#</span></a></h2><ul>
<li>Markdown (MD) 是一种轻量级标记语言，允许用户使用纯文本格式编写文档，然后将其转换为格式化的HTML。它因其简洁易用的语法而广受欢迎，特别适合编写文档和博客文章。</li>
<li>MDX 是一种扩展了 Markdown 语法的格式，允许在 Markdown 文档中无缝地插入 JSX 代码。通过 MDX，用户可以在文档中嵌入 React 组件，从而实现更丰富的交互性和动态性。</li>
</ul>

<table><thead><tr><th>特性</th><th>Markdown</th><th>MDX</th></tr></thead><tbody><tr><td>基础语法</td><td>支持 (CommonMark)</td><td>支持 (CommonMark)</td></tr><tr><td>HTML 标签</td><td>支持</td><td>支持 (作为 JSX)</td></tr><tr><td>组件导入</td><td>不支持</td><td>支持 (import)</td></tr><tr><td>动态数据</td><td>不支持</td><td>支持 (JS 表达式)</td></tr><tr><td>样式定制</td><td>有限 (class/style)</td><td>灵活 (className/CSS-in-JS)</td></tr></tbody></table><hr /></section>
<section><h2>Firefly 内置的专属 MDX UI 组件<a href="#firefly-内置的专属-mdx-ui-组件"><span>#</span></a></h2><p>这里列出 Firefly 内置的 MDX UI 组件，方便在 MDX 文章中直接使用。</p><section><h3>Tab分组：<code>TabGroup</code><a href="#tab分组tabgroup"><span>#</span></a></h3><p>用于创建可切换的标签页，方便在文章中展示不同语言或不同版本的代码等等。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>TabGroup</span><span> </span><span>labels</span><span>=</span><span>{</span><span>[</span><span>"test.js"</span><span>, </span><span>"test.py"</span><span>]</span><span>}</span><span> </span><span>client</span><span>:</span><span>load</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span>  </span><span>```</span><span>js</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>1</span><span>)</span></div></div><div><div><div>4</div></div><div><span>  </span><span>```</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>  </span><span>```</span><span>py</span></div></div><div><div><div>7</div></div><div><span>  </span><span>print</span><span>(</span><span>"hello world"</span><span>)</span></div></div><div><div><div>8</div></div><div><span>  </span><span>```</span></div></div><div><div><div>9</div></div><div><span>&lt;/</span><span>TabGroup</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><div>test.jstest.py</div> <div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>console</span><span>.</span></span><span>log</span><span>(</span><span>1</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>print</span><span>(</span><span>"hello world"</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div></div></div><hr /></section><section><h3>时间线：<code>Timeline</code> / <code>TimelineItem</code><a href="#时间线timeline--timelineitem"><span>#</span></a></h3>

<table><thead><tr><th>属性</th><th>必填</th><th>说明</th></tr></thead><tbody><tr><td><code>date</code></td><td>否</td><td>时间标签，如 “2024-03-10”</td></tr><tr><td><code>title</code></td><td>否</td><td>条目标题</td></tr><tr><td><code>type</code></td><td>否</td><td>节点颜色，default 为主题色，其余对应提示框色板（tip / note / important / warning / caution）</td></tr><tr><td><code>icon</code></td><td>否</td><td>内置图标名，显示在圆点内：star / rocket / git / flag / book / heart / zap / bug / tag / calendar / code / edit</td></tr><tr><td>正文</td><td>否</td><td><code>&lt;TimelineItem&gt;</code> 标签内的内容，支持 Markdown</td></tr></tbody></table><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>Timeline</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>&lt;</span><span>TimelineItem</span><span> </span><span>date</span><span>=</span><span>"2026-08-16"</span><span> </span><span>title</span><span>=</span><span>"新版本发布"</span><span> </span><span>icon</span><span>=</span><span>"rocket"</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>发布了全新版本，带来以下更新：</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>- 新增时间线组件</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>- 改进暗色主题</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>正文里支持 </span><span>**</span><span>Markdown</span><span>**</span><span> 内容。</span></div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>&lt;/</span><span>TimelineItem</span><span>&gt;</span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>&lt;</span><span>TimelineItem</span><span> </span><span>date</span><span>=</span><span>"2025-11-02"</span><span> </span><span>title</span><span>=</span><span>"站点上线"</span><span> </span><span>type</span><span>=</span><span>"tip"</span><span> </span><span>icon</span><span>=</span><span>"flag"</span><span>&gt;</span></div></div><div><div><div>11</div></div><div><span><span>    </span></span><span>欢迎来到我的博客。</span></div></div><div><div><div>12</div></div><div><span><span>  </span></span><span>&lt;/</span><span>TimelineItem</span><span>&gt;</span></div></div><div><div><div>13</div></div><div><span><span>  </span></span><span>&lt;</span><span>TimelineItem</span><span> </span><span>date</span><span>=</span><span>"2025-06-15"</span><span> </span><span>title</span><span>=</span><span>"项目立项"</span><span> </span><span>type</span><span>=</span><span>"note"</span><span>&gt;</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>开始规划 Firefly 主题。</span></div></div><div><div><div>15</div></div><div><span><span>  </span></span><span>&lt;/</span><span>TimelineItem</span><span>&gt;</span></div></div><div><div><div>16</div></div><div><span>&lt;/</span><span>Timeline</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><ol><li><div><span></span></div><div><div>2026-08-16</div><div>新版本发布</div><div><p>发布了全新版本，带来以下更新：</p><ul>
<li>新增时间线组件</li>
<li>改进暗色主题</li>
</ul><p>正文里支持 <strong>Markdown</strong> 内容。</p></div></div></li><li><div><span></span></div><div><div>2025-11-02</div><div>站点上线</div><div><p>欢迎来到我的博客。</p></div></div></li><li><div></div><div><div>2025-06-15</div><div>项目立项</div><div><p>开始规划 Firefly 主题。</p></div></div></li></ol><hr /></section><section><h3>步骤条：<code>Steps</code> / <code>StepItem</code><a href="#步骤条steps--stepitem"><span>#</span></a></h3><p>编号步骤条，适合教程、部署流程。编号自动生成，无需手动传序号。</p>

<table><thead><tr><th>属性</th><th>必填</th><th>说明</th></tr></thead><tbody><tr><td><code>title</code></td><td>否</td><td>步骤标题</td></tr><tr><td><code>type</code></td><td>否</td><td>编号圆颜色，default 为主题色，其余对应提示框色板（tip / note / important / warning / caution）</td></tr><tr><td><code>icon</code></td><td>否</td><td>内置图标名，有图标时显示图标而非数字（star / rocket / git / flag / book / heart / zap / bug / tag / calendar / code / edit）</td></tr><tr><td>正文</td><td>否</td><td><code>&lt;StepItem&gt;</code> 标签内的内容，支持 Markdown</td></tr></tbody></table><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>Steps</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>&lt;</span><span>StepItem</span><span> </span><span>title</span><span>=</span><span>"安装依赖"</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>运行 </span><span>`</span><span>pnpm install</span><span>`</span><span>。</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>&lt;/</span><span>StepItem</span><span>&gt;</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>&lt;</span><span>StepItem</span><span> </span><span>title</span><span>=</span><span>"启动开发服务器"</span><span> </span><span>type</span><span>=</span><span>"tip"</span><span> </span><span>icon</span><span>=</span><span>"rocket"</span><span>&gt;</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>运行 </span><span>`</span><span>pnpm dev</span><span>`</span><span>，打开 </span><span>`</span><span>localhost:4321</span><span>`</span><span>。</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>&lt;/</span><span>StepItem</span><span>&gt;</span></div></div><div><div><div>8</div></div><div><span><span>  </span></span><span>&lt;</span><span>StepItem</span><span> </span><span>title</span><span>=</span><span>"编写文章"</span><span>&gt;</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>在 </span><span>`</span><span>src/content/posts/</span><span>`</span><span> 新建 </span><span>`</span><span>.mdx</span><span>`</span><span> 文章。</span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>&lt;/</span><span>StepItem</span><span>&gt;</span></div></div><div><div><div>11</div></div><div><span>&lt;/</span><span>Steps</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol><li><span></span><div><div>安装依赖</div><div><p>运行 <code>pnpm install</code>。</p></div></div></li><li><span><span></span></span><div><div>启动开发服务器</div><div><p>运行 <code>pnpm dev</code>，打开 <code>localhost:4321</code>。</p></div></div></li><li><span></span><div><div>编写文章</div><div><p>在 <code>src/content/posts/</code> 新建 <code>.mdx</code> 文章。</p></div></div></li></ol><hr /></section><section><h3>徽章：<code>Badge</code><a href="#徽章badge"><span>#</span></a></h3><p>内联彩色小徽章，可嵌在段落或标题里。</p>

<table><thead><tr><th>属性</th><th>必填</th><th>说明</th></tr></thead><tbody><tr><td><code>type</code></td><td>否</td><td>default 为主题色，其余对应提示框色板（tip / note / important / warning / caution）</td></tr></tbody></table><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>Badge</span><span> </span><span>type</span><span>=</span><span>"tip"</span><span>&gt;提示&lt;/</span><span>Badge</span><span>&gt; &lt;</span><span>Badge</span><span> </span><span>type</span><span>=</span><span>"warning"</span><span>&gt;注意&lt;/</span><span>Badge</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><span>新功能</span><span>提示</span><span>笔记</span><span>重要</span><span>注意</span><span>危险</span><hr /><p>更多信息，请查看 <a href="https://mdxjs.com/" target="_blank">MDX 文档</a></p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/update-firefly/</id>
      <title type="text">Firefly 更新方式</title>
      <published>1970-01-01T00:00:00.000Z</published>
      <updated>1970-01-01T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/update-firefly/"/>
      <summary type="text">Firefly 是一款基于 Astro 框架和 Fuwari 模板开发的清新美观且现代化个人博客主题模板，专为技术爱好者和内容创作者设计。该主题融合了现代 Web 技术栈，提供了丰富的功能模块和高度可定制的界面，让您能够轻松打造出专业且美观的个人博客网站。</summary>
      <content type="html"><![CDATA[<section><h3>方法一：Git 合并（推荐）<a href="#方法一git-合并推荐"><span>#</span></a></h3><p>如果你是通过 <code>git clone</code> 获取的项目，可以通过 Git 拉取上游更新。</p><section><h4>1. 添加上游仓库<a href="#1-添加上游仓库"><span>#</span></a></h4><p>如果还没有添加过上游仓库：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>remote</span><span> </span><span>add</span><span> </span><span>upstream</span><span> </span><span>https://github.com/CuteLeaf/Firefly.git</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>2. 拉取最新代码<a href="#2-拉取最新代码"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>fetch</span><span> </span><span>upstream</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>3. 合并更新<a href="#3-合并更新"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>merge</span><span> </span><span>upstream/master</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>4. 解决冲突<a href="#4-解决冲突"><span>#</span></a></h4><p>如果出现合并冲突，通常发生在你修改过的配置文件上。手动解决冲突后：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>add</span><span> </span><span>.</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>commit</span><span> </span><span>-m</span><span> </span><span>"merge: update Firefly theme"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><div><div></div><div>Tip</div></div><div><p>建议只修改 <code>src/config/</code> 目录下的配置文件和 <code>src/content/</code> 目录下的内容文件，尽量不要修改主题核心文件，这样更新时冲突会比较少。</p></div></div></section></section>
<section><h3>方法二：手动覆盖<a href="#方法二手动覆盖"><span>#</span></a></h3><p>如果 Git 合并冲突太多或者你做了大量自定义修改：</p><ol>
<li>备份你的配置文件和内容：</li>
</ol><ul>
<li><code>src/config/</code> — 所有配置文件</li>
<li><code>src/content/</code> — 文章和页面内容</li>
<li><code>public/</code> — 静态资源（图片、字体等）</li>
</ul><ol>
<li>
<p>下载最新版本的 Firefly</p>
</li>
<li>
<p>将备份的文件还原到对应目录</p>
</li>
<li>
<p>重新安装依赖：</p>
</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>pnpm</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>启动开发服务器，检查是否有报错：</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>pnpm</span><span> </span><span>dev</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>更新后检查<a href="#更新后检查"><span>#</span></a></h2><p>更新完成后，建议检查以下内容：</p><ol>
<li><strong>配置文件兼容性</strong>：新版本可能新增了配置项，查看仓库的 commit 记录了解变更</li>
<li><strong>类型检查</strong>：如果 TypeScript 报错，说明配置文件的类型定义可能有变化，参照类型定义补充新增的必填字段</li>
<li><strong>依赖更新</strong>：运行 <code>pnpm install</code> 确保依赖是最新的</li>
<li><strong>本地预览</strong>：运行 <code>pnpm dev</code> 在本地预览，确认页面渲染正常</li>
<li><strong>构建测试</strong>：运行 <code>pnpm build</code> 确认构建没有错误</li>
</ol></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.huhaha.vip/posts/video/</id>
      <title type="text">在文章中嵌入视频</title>
      <published>1970-01-01T00:00:00.000Z</published>
      <updated>1970-01-01T00:00:00.000Z</updated>
      <author><name>小王的博客</name></author>
      <link rel="alternate" href="https://blog.huhaha.vip/posts/video/"/>
      <summary type="text">这篇文章演示如何在博客文章中嵌入视频。</summary>
      <content type="html"><![CDATA[<p>只需从 YouTube 或其他平台复制嵌入代码，然后将其粘贴到 markdown 文件中。</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>---</span></div></div><div><div><div>2</div></div><div><span>title</span><span>: </span><span>在文章中嵌入视频</span></div></div><div><div><div>3</div></div><div><span>published</span><span>: </span><span>2023-10-19</span></div></div><div><div><div>4</div></div><div><span>// ...</span></div></div><div><div><div>5</div></div><div><span>---</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>&lt;iframe width="100%" height="468" src="https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_" title="YouTube video player" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<section><h2>YouTube<a href="#youtube"><span>#</span></a></h2></section>
<section><h2>Bilibili<a href="#bilibili"><span>#</span></a></h2> </section>]]></content>
    </entry>
</feed>
