<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>小敏の晚风</title>
  
  <subtitle>非人之学能，非己之识用</subtitle>
  <link href="https://xmblog.chrislin.eu.org/atom.xml" rel="self"/>
  
  <link href="https://xmblog.chrislin.eu.org/"/>
  <updated>2026-11-10T13:02:16.260Z</updated>
  <id>https://xmblog.chrislin.eu.org/</id>
  
  <author>
    <name>小敏</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Windows 11 移除 WMIC 后，如何让依赖 wmic 的老程序继续工作</title>
    <link href="https://xmblog.chrislin.eu.org/posts/20260917030256.html"/>
    <id>https://xmblog.chrislin.eu.org/posts/20260917030256.html</id>
    <published>2026-09-17T03:02:56.000Z</published>
    <updated>2026-11-10T13:02:16.260Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Windows-11-移除-WMIC-后，如何让依赖-wmic-的老程序继续工作"><a href="#Windows-11-移除-WMIC-后，如何让依赖-wmic-的老程序继续工作" class="headerlink" title="Windows 11 移除 WMIC 后，如何让依赖 wmic 的老程序继续工作"></a>Windows 11 移除 WMIC 后，如何让依赖 wmic 的老程序继续工作</h1><blockquote><p>一套通用的 <strong>wmic 兼容垫片</strong>方案：不装回废弃二进制，让老程序零改动继续跑。</p><p>适用系统：Windows 11 24H2 &#x2F; 25H2 &#x2F; 26H1（2026 年 8 月更新及以后）<br>整理日期：2026-09-17</p></blockquote><hr><h2 id="目录"><a href="#目录" class="headerlink" title="目录"></a>目录</h2><ul><li><a href="#%E4%B8%80%E9%97%AE%E9%A2%98wmic-%E6%B2%A1%E4%BA%86%E5%80%92%E4%B8%8B%E7%9A%84%E4%B8%8D%E6%AD%A2%E4%B8%80%E4%B8%AA%E7%A8%8B%E5%BA%8F">一、问题：wmic 没了，倒下的不止一个程序</a><ul><li><a href="#11-%E7%8E%B0%E8%B1%A1">1.1 现象</a></li><li><a href="#12-%E8%B0%81%E4%BC%9A%E4%B8%AD%E6%8B%9B">1.2 谁会中招</a></li><li><a href="#13-%E6%8A%A5%E9%94%99%E9%95%BF%E4%BB%80%E4%B9%88%E6%A0%B7">1.3 报错长什么样</a></li><li><a href="#14-%E5%85%B3%E9%94%AE%E8%AE%A4%E7%9F%A5wmi-%E8%BF%98%E5%9C%A8%E5%8F%AA%E6%98%AF%E5%A4%96%E5%A3%B3%E6%B2%A1%E4%BA%86">1.4 关键认知：WMI 还在，只是外壳没了</a></li></ul></li><li><a href="#%E4%BA%8C%E5%85%88%E5%88%A4%E6%96%AD%E6%98%AF%E4%B8%8D%E6%98%AF%E4%B8%AD%E4%BA%86%E8%BF%99%E4%B8%80%E6%9E%AA">二、先判断：是不是中了这一枪</a><ul><li><a href="#21-%E4%B8%89%E6%AD%A5%E5%AE%9A%E4%BD%8D%E6%B3%95">2.1 三步定位法</a></li><li><a href="#22-%E6%89%BE%E5%87%BA%E7%A8%8B%E5%BA%8F%E6%89%A7%E8%A1%8C%E4%BA%86%E5%93%AA%E6%9D%A1%E5%91%BD%E4%BB%A4">2.2 找出程序执行了哪条命令</a></li><li><a href="#23-%E7%A1%AE%E8%AE%A4-wmic-%E7%9A%84%E7%9C%9F%E5%AE%9E%E7%8A%B6%E6%80%81">2.3 确认 wmic 的真实状态</a></li><li><a href="#24-%E5%BE%AE%E8%BD%AF%E5%AE%98%E6%96%B9%E6%97%B6%E9%97%B4%E7%BA%BF">2.4 微软官方时间线</a></li><li><a href="#25-%E5%85%88%E5%88%AB%E6%80%A5%E7%9D%80-dism">2.5 先别急着 DISM</a></li></ul></li><li><a href="#%E4%B8%89%E6%96%B9%E6%A1%88%E5%AF%B9%E6%AF%94">三、方案对比</a></li><li><a href="#%E5%9B%9B%E9%83%A8%E7%BD%B2-wmic-%E5%85%BC%E5%AE%B9%E5%9E%AB%E7%89%87">四、部署 wmic 兼容垫片</a><ul><li><a href="#41-%E5%8E%9F%E7%90%86">4.1 原理</a></li><li><a href="#42-%E6%94%AF%E6%8C%81%E7%9A%84%E5%91%BD%E4%BB%A4%E8%8C%83%E5%9B%B4">4.2 支持的命令范围</a></li><li><a href="#43-%E6%96%87%E4%BB%B6%E6%B8%85%E5%8D%95">4.3 文件清单</a></li><li><a href="#44-%E6%96%B9%E5%BC%8F%E4%B8%80%E9%9C%80%E8%A6%81%E7%AE%A1%E7%90%86%E5%91%98%E6%8E%A8%E8%8D%90">4.4 方式一：需要管理员（推荐）</a></li><li><a href="#45-%E6%96%B9%E5%BC%8F%E4%BA%8C%E5%85%8D%E7%AE%A1%E7%90%86%E5%91%98">4.5 方式二：免管理员</a></li><li><a href="#46-%E9%AA%8C%E8%AF%81">4.6 验证</a></li><li><a href="#47-%E5%8D%B8%E8%BD%BD">4.7 卸载</a></li></ul></li><li><a href="#%E4%BA%94%E6%89%A9%E5%B1%95%E5%9E%AB%E7%89%87">五、扩展垫片</a><ul><li><a href="#51-%E5%88%AB%E5%90%8D%E6%98%A0%E5%B0%84%E8%A1%A8">5.1 别名映射表</a></li><li><a href="#52-%E5%8A%A0%E4%B8%80%E4%B8%AA%E5%88%AB%E5%90%8D">5.2 加一个别名</a></li><li><a href="#53-where-%E6%9D%A1%E4%BB%B6%E7%9A%84%E5%86%99%E6%B3%95">5.3 where 条件的写法</a></li><li><a href="#54-%E8%BE%93%E5%87%BA%E6%A0%BC%E5%BC%8F">5.4 输出格式</a></li><li><a href="#55-%E8%B0%83%E8%AF%95%E6%96%B9%E6%B3%95">5.5 调试方法</a></li></ul></li><li><a href="#%E5%85%AD%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98">六、常见问题</a></li><li><a href="#%E9%99%84%E5%BD%95-a%E8%84%9A%E6%9C%AC%E6%BA%90%E7%A0%81">附录 A：脚本源码</a></li><li><a href="#%E9%99%84%E5%BD%95-b%E6%8E%92%E6%9F%A5%E5%91%BD%E4%BB%A4%E9%80%9F%E6%9F%A5">附录 B：排查命令速查</a></li><li><a href="#%E9%99%84%E5%BD%95-c%E6%A1%88%E4%BE%8B%E5%A4%8D%E7%9B%98--%E8%93%9D%E5%87%8C-kmss-idea-%E6%8F%92%E4%BB%B6">附录 C：案例复盘 —— 蓝凌 KMSS IDEA 插件</a></li><li><a href="#%E9%99%84%E4%B8%80%E9%A1%B5%E9%80%9F%E6%9F%A5">附：一页速查</a></li></ul><hr><h2 id="一、问题：wmic-没了，倒下的不止一个程序"><a href="#一、问题：wmic-没了，倒下的不止一个程序" class="headerlink" title="一、问题：wmic 没了，倒下的不止一个程序"></a>一、问题：wmic 没了，倒下的不止一个程序</h2><h3 id="1-1-现象"><a href="#1-1-现象" class="headerlink" title="1.1 现象"></a>1.1 现象</h3><p>2026 年 8 月起，Windows 11 的 24H2 &#x2F; 25H2 &#x2F; 26H1 更新<strong>彻底删除了 <code>wmic.exe</code></strong>，<br>而且<strong>不再作为「可选功能」提供</strong> —— 你在「设置 → 系统 → 可选功能」里已经搜不到它了。</p><p>麻烦在于：<code>wmic</code> 曾经是过去十几年里最顺手的系统查询命令行，<br>大量老程序把它当成理所当然的存在。它一消失，这些程序会以各种奇怪的方式失败：</p><table><thead><tr><th>表现</th><th>说明</th></tr></thead><tbody><tr><td>直接报「不是内部或外部命令」</td><td>最直白的一种，程序会把命令的错误输出打出来</td></tr><tr><td><strong>静默拿到空结果</strong></td><td>最坑的一种。程序不报错，只是某个功能「检测不到」</td></tr><tr><td>把退出码 1 当成失败并中断</td><td>有些程序只看退出码，直接走进错误分支</td></tr><tr><td>功能入口消失 &#x2F; 按钮变灰</td><td>检测失败的连带结果</td></tr></tbody></table><p>关键在于：<strong>第二种最难查</strong>。程序看起来一切正常，就是不工作。</p><blockquote><p>本文用蓝凌 KMSS 的 IDEA 插件「代码合并工具」作为贯穿案例 —— 它就属于第二种，<br>表现为「idea 程序位置检测不出来」。完整复盘见<a href="#%E9%99%84%E5%BD%95-c%E6%A1%88%E4%BE%8B%E5%A4%8D%E7%9B%98--%E8%93%9D%E5%87%8C-kmss-idea-%E6%8F%92%E4%BB%B6">附录 C</a>，<br>正文部分尽量与具体程序解耦。</p></blockquote><h3 id="1-2-谁会中招"><a href="#1-2-谁会中招" class="headerlink" title="1.2 谁会中招"></a>1.2 谁会中招</h3><p>只要程序内部 shell out 到 <code>wmic</code>，就会中招。实际遇到过的类别：</p><table><thead><tr><th>类别</th><th>典型场景</th></tr></thead><tbody><tr><td>IDE &#x2F; 编辑器插件</td><td>检测 IDE 安装路径、枚举进程、取硬件信息</td></tr><tr><td>构建与发布脚本</td><td><code>.bat</code> &#x2F; <code>.cmd</code> &#x2F; <code>.ps1</code> 里查进程、查磁盘、查服务</td></tr><tr><td>运维 &#x2F; 巡检脚本</td><td>采集 CPU、内存、磁盘、服务状态</td></tr><tr><td>安装包 &#x2F; 静默部署脚本</td><td>前置检查、卸载旧版本、检测进程占用</td></tr><tr><td>监控采集器 &#x2F; 资产盘点工具</td><td>上报硬件序列号、系统版本、补丁列表</td></tr><tr><td>老版本业务系统客户端</td><td>启动时做环境自检</td></tr></tbody></table><p>判断方法很简单：<strong>在你自己的脚本或程序目录里搜一下 <code>wmic</code></strong>（见 <a href="#22-%E6%89%BE%E5%87%BA%E7%A8%8B%E5%BA%8F%E6%89%A7%E8%A1%8C%E4%BA%86%E5%93%AA%E6%9D%A1%E5%91%BD%E4%BB%A4">2.2</a>）。</p><h3 id="1-3-报错长什么样"><a href="#1-3-报错长什么样" class="headerlink" title="1.3 报错长什么样"></a>1.3 报错长什么样</h3><p>英文系统：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&#x27;wmic&#x27; is not recognized as an internal or external command,</span><br><span class="line">operable program or batch file.</span><br></pre></td></tr></table></figure><p>中文系统：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&#x27;wmic&#x27; 不是内部或外部命令，也不是可运行的程序</span><br><span class="line">或批处理文件。</span><br></pre></td></tr></table></figure><p>静默型（没有报错，只有程序自己的日志）：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ideaPath64 为空</span><br><span class="line">检测失败：未获取到目标信息</span><br></pre></td></tr></table></figure><h3 id="1-4-关键认知：WMI-还在，只是外壳没了"><a href="#1-4-关键认知：WMI-还在，只是外壳没了" class="headerlink" title="1.4 关键认知：WMI 还在，只是外壳没了"></a>1.4 关键认知：WMI 还在，只是外壳没了</h3><p>这是整件事里最重要的一点，也是后面所有方案成立的基础：</p><blockquote><p><strong>被移除的只是 <code>wmic.exe</code> 这个命令行外壳。WMI 服务本身完全正常。</strong></p></blockquote><p><code>wmic</code> 只是一层「把命令行翻译成 WMI 查询」的皮。剥掉它，<br>底层能力（<code>Win32_Process</code>、<code>Win32_OperatingSystem</code>、<code>Win32_Service</code> …）<br>一个都没少，用 PowerShell 的 <code>Get-CimInstance</code> 查得到的东西和以前完全一样。</p><p>所以问题不是「能力没了」，而是「<strong>调用约定变了</strong>」。<br>既然我们无法改老程序，那就<strong>把老的调用约定补回来</strong> —— 这就是本方案的全部思路。</p><hr><h2 id="二、先判断：是不是中了这一枪"><a href="#二、先判断：是不是中了这一枪" class="headerlink" title="二、先判断：是不是中了这一枪"></a>二、先判断：是不是中了这一枪</h2><h3 id="2-1-三步定位法"><a href="#2-1-三步定位法" class="headerlink" title="2.1 三步定位法"></a>2.1 三步定位法</h3><p>别急着动手，先花十分钟确认三件事：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">第 1 步  它到底在调什么？</span><br><span class="line">         └─ 拿到程序执行的那条完整命令行（关键证据）</span><br><span class="line"></span><br><span class="line">第 2 步  wmic 是真的没了，还是 PATH / 权限问题？</span><br><span class="line">         └─ 排除「其实只是环境变量被改坏了」</span><br><span class="line"></span><br><span class="line">第 3 步  它需要什么输出？有没有绕过的口子？</span><br><span class="line">         └─ 决定是「改配置」还是「补命令」</span><br></pre></td></tr></table></figure><p>第 3 步决定方案选择：</p><table><thead><tr><th>第 3 步的结论</th><th>走哪条路</th></tr></thead><tbody><tr><td>程序提供了手工指定路径的入口（可编辑输入框）</td><td>直接填，收工</td></tr><tr><td>程序有配置文件，且<strong>代码真的会读回</strong></td><td>改配置文件，收工</td></tr><tr><td>只能自动检测，没有绕过口子</td><td>走<a href="#%E5%9B%9B%E9%83%A8%E7%BD%B2-wmic-%E5%85%BC%E5%AE%B9%E5%9E%AB%E7%89%87">第四章</a>的垫片方案</td></tr></tbody></table><blockquote><p>⚠️ 「有配置文件」不等于「改了有用」。案例里那个插件就把路径写进<br><code>.idea/kmss_dev_config.xml</code>，但<strong>全 jar 没有任何代码读回它</strong> ——<br>是只写不读的缓存，改了白改，还会被程序退出时覆盖。<br>所以第 3 步必须看代码或做实测，不能只看「有没有这个字段」。</p></blockquote><h3 id="2-2-找出程序执行了哪条命令"><a href="#2-2-找出程序执行了哪条命令" class="headerlink" title="2.2 找出程序执行了哪条命令"></a>2.2 找出程序执行了哪条命令</h3><p>按可行性从高到低：</p><table><thead><tr><th>手段</th><th>适用</th><th>怎么做</th></tr></thead><tbody><tr><td><strong>程序自己的日志</strong></td><td>首选，最省事</td><td>搜关键字 <code>wmic</code>、<code>exec</code>、<code>command</code>、<code>bat</code>、厂商名</td></tr><tr><td><strong>进程监控</strong></td><td>程序无日志、需要看进程调用</td><td>Process Monitor，过滤 <code>Operation = Process Start</code>，看 Command Line 列</td></tr><tr><td><strong>ETW &#x2F; Sysmon</strong></td><td>不方便装工具</td><td>Sysmon 事件 ID 1（进程创建）带完整命令行</td></tr><tr><td><strong>字符串搜索</strong></td><td>程序是脚本、jar、exe</td><td>在文件里直接搜 <code>wmic</code> 明文</td></tr><tr><td><strong>反编译</strong></td><td>jar &#x2F; .NET 程序</td><td><code>javap</code>（Java）、dnSpy（.NET）</td></tr><tr><td><strong>手动复现</strong></td><td>已知命令</td><td>在 <code>cmd</code> 里原样敲一遍，看真实报错</td></tr></tbody></table><p>案例中的证据就是这样拿到的 —— 插件日志里直接写着它执行的命令，<br>连报错都一起打出来了（见<a href="#%E9%99%84%E5%BD%95-c%E6%A1%88%E4%BE%8B%E5%A4%8D%E7%9B%98--%E8%93%9D%E5%87%8C-kmss-idea-%E6%8F%92%E4%BB%B6">附录 C</a>）。</p><blockquote><p>💡 拿到命令行后，先把它<strong>原样在 <code>cmd</code> 里跑一遍</strong>。<br>这一步能同时完成第 1、2 步：既确认命令内容，也确认 wmic 到底在不在。</p></blockquote><h3 id="2-3-确认-wmic-的真实状态"><a href="#2-3-确认-wmic-的真实状态" class="headerlink" title="2.3 确认 wmic 的真实状态"></a>2.3 确认 wmic 的真实状态</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. wmic 是否还存在（两个可能的位置都看）</span></span><br><span class="line"><span class="built_in">Test-Path</span> <span class="string">&quot;<span class="variable">$env:SystemRoot</span>\System32\wmic.exe&quot;</span></span><br><span class="line"><span class="built_in">Test-Path</span> <span class="string">&quot;<span class="variable">$env:SystemRoot</span>\System32\wbem\wmic.exe&quot;</span></span><br><span class="line"><span class="comment">#    都返回 False → wmic 已被移除</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 它在 PATH 里还解析得到吗</span></span><br><span class="line">cmd /c <span class="string">&quot;where wmic&quot;</span></span><br><span class="line"><span class="comment">#    返回「信息: 用提供的模式无法找到文件。」→ 确实没有</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. WMI 服务本身是否正常（正常 ≠ wmic 还在）</span></span><br><span class="line"><span class="built_in">Get-Service</span> Winmgmt | <span class="built_in">Format-List</span> Name, Status, StartType</span><br><span class="line"><span class="comment">#    期望：Running / Automatic</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 4. 确认 WMI 能力没丢（这条能跑通，垫片方案就一定可行）</span></span><br><span class="line"><span class="built_in">Get-CimInstance</span> Win32_OperatingSystem | <span class="built_in">Select-Object</span> Caption, Version</span><br></pre></td></tr></table></figure><p>如果第 3、4 步异常，那是另一类问题（WMI 仓库损坏），不在本文范围。</p><h3 id="2-4-微软官方时间线"><a href="#2-4-微软官方时间线" class="headerlink" title="2.4 微软官方时间线"></a>2.4 微软官方时间线</h3><p>摘自微软 KB5067470《Windows Management Instrumentation Command-line (WMIC) removal from Windows》：</p><table><thead><tr><th>时间</th><th>状态</th></tr></thead><tbody><tr><td>2021</td><td>Windows 10 21H2 起标记为<strong>弃用</strong></td></tr><tr><td>2022</td><td>Win11 22H2 作为「可选功能」预装并默认启用</td></tr><tr><td>2024</td><td>Win11 23H2 &#x2F; 24H2 <strong>默认禁用</strong>，仍可作可选功能安装</td></tr><tr><td>2025</td><td>升级到 25H2 时被移除，<strong>仍可作可选功能装回</strong></td></tr><tr><td><strong>2026-08</strong></td><td><strong>从 24H2 &#x2F; 25H2 &#x2F; 26H1 彻底移除，不再作为可选功能提供</strong></td></tr></tbody></table><p>所以「可选功能里搜不到 wmic」是<strong>正常现象，不是机器有问题</strong>。<br>网上那些「设置 → 可选功能 → 搜索 wmic 下载安装」的教程，<br>对 2026 年 8 月之后的系统已经<strong>全部失效</strong>。</p><h3 id="2-5-先别急着-DISM"><a href="#2-5-先别急着-DISM" class="headerlink" title="2.5 先别急着 DISM"></a>2.5 先别急着 DISM</h3><p>网上流传一条命令，号称能把 WMIC 装回来：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">DISM /Online /<span class="built_in">Add-Capability</span> /CapabilityName:WMIC~~~~</span><br></pre></td></tr></table></figure><p><strong>实测：会显示「操作成功完成」，但实际什么都没装，<code>wmic</code> 依然找不到。</strong></p><p>原因（已逐项验证）：</p><ul><li>组件存储里还留着 <code>Microsoft-Windows-WMIC-FoD-Package*</code> 的元数据（<code>.mum</code> &#x2F; <code>.cat</code>），<br>所以 DISM 校验能过、不报错；</li><li>但 <code>wmic.exe</code> 的<strong>实际载荷已被删除</strong> —— 全盘 <code>WinSxS</code> 里只剩 <code>wmi-wmiclnt</code><br>（WMI 客户端 DLL，跟 wmic.exe 没关系），没有任何 <code>wmic.exe</code>；</li><li>也没有待重启标记（<code>RebootPending = False</code>），所以不是「重启一下就好」。</li></ul><p>这与 KB 的说法一致：WMIC <strong>已不再作为 Feature on Demand 提供</strong>。<br>那条 DISM 命令只对 23H2 &#x2F; 24H2 早期有效。</p><blockquote><p>⚠️ 这个坑值得单独记一笔：<strong>DISM 报「操作成功完成」不代表装上了</strong>。<br>元数据残留会让它误判为「已安装」。</p></blockquote><hr><h2 id="三、方案对比"><a href="#三、方案对比" class="headerlink" title="三、方案对比"></a>三、方案对比</h2><table><thead><tr><th>#</th><th>方案</th><th>需要管理员</th><th>优点</th><th>缺点</th><th>适用</th></tr></thead><tbody><tr><td>1</td><td>程序界面里手工指定路径</td><td>—</td><td>成本最低</td><td>多数程序没这个入口（案例中是只读标签）</td><td>先试</td></tr><tr><td>2</td><td>改程序的配置文件</td><td>—</td><td>不用装东西</td><td>必须确认代码<strong>真的读回</strong>该值</td><td>视程序而定</td></tr><tr><td>3</td><td>微软官方临时包 <code>wmic_dlc.zip</code></td><td>✅</td><td>官方出品，装回真 <code>wmic.exe</code>，<strong>所有程序零改动</strong></td><td>塞回已弃用二进制；微软声明只是临时方案</td><td>想让流程与现有文档保持一致</td></tr><tr><td>4</td><td><strong>wmic 兼容垫片（本方案）</strong></td><td>✅ &#x2F; 可选免管理员</td><td>不引入废弃二进制；可控、可扩展、可卸载</td><td>自制件需自己维护；只覆盖常见语法</td><td><strong>推荐</strong></td></tr><tr><td>5</td><td>推动上游改用 <code>Get-CimInstance</code></td><td>—</td><td>治本</td><td>依赖厂商排期</td><td>建议同步推进</td></tr><tr><td>6</td><td>降级 &#x2F; 更换系统</td><td>—</td><td>立刻可用</td><td>代价大，且不解决长期问题</td><td>不推荐</td></tr></tbody></table><blockquote><p>方案 3 的官方包在 KB5067470 里，链接指向 <code>download.microsoft.com</code>。<br>解压后管理员 PowerShell 执行 <code>Set-ExecutionPolicy Bypass -Scope Process</code> 再 <code>.\install.ps1</code>。</p><p><strong>方案 3 与方案 4 怎么选</strong>：<br>如果组内有一堆说不清的脚本都在用 wmic、且语法五花八门 → 选 3，最省心；<br>如果只是个别程序、用的语法很固定 → 选 4，不引入废弃二进制、更干净。</p></blockquote><hr><h2 id="四、部署-wmic-兼容垫片"><a href="#四、部署-wmic-兼容垫片" class="headerlink" title="四、部署 wmic 兼容垫片"></a>四、部署 wmic 兼容垫片</h2><h3 id="4-1-原理"><a href="#4-1-原理" class="headerlink" title="4.1 原理"></a>4.1 原理</h3><p>一句话：<strong>做一个假的 <code>wmic</code>，把命令翻译成 PowerShell 执行。</strong></p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">老程序 / 插件</span><br><span class="line">  │  cmd /c wmic process where name=&#x27;xxx.exe&#x27; get processid,executablepath</span><br><span class="line">  ▼</span><br><span class="line">cmd.exe 沿 PATH 解析 wmic</span><br><span class="line">  │  System32\wmic.exe ✗ 已不存在 → 继续往后找</span><br><span class="line">  ▼</span><br><span class="line">命中 C:\Windows\System32\Wbem\wmic.cmd   ← 转接头（该目录本来就在 PATH 上）</span><br><span class="line">  │  把参数原样转发</span><br><span class="line">  ▼</span><br><span class="line">wmic-shim.ps1</span><br><span class="line">  │  解析别名 / where / get → Get-CimInstance 查 WMI</span><br><span class="line">  ▼</span><br><span class="line">按 wmic 原格式输出 → 老程序解析到它要的东西</span><br></pre></td></tr></table></figure><p><strong>为什么 cmd 会选中我们的 <code>wmic.cmd</code>？</strong></p><p><code>cmd.exe</code> 解析 <code>wmic</code> 时的顺序是：逐个 PATH 目录，在每个目录里按 <code>PATHEXT</code><br>顺序找 <code>wmic.com</code> → <code>wmic.exe</code> → <code>wmic.bat</code> → <code>wmic.cmd</code>。</p><p><code>System32\</code> 和 <code>C:\Windows\</code> 里都没有 <code>wmic.*</code>，于是继续往后找，<br>最终命中 <code>System32\Wbem\wmic.cmd</code>（<code>PATHEXT</code> 默认含 <code>.CMD</code>）。</p><blockquote><p><strong>前提是 <code>wmic.exe</code> 已经被删干净</strong> —— 正是这个方案的成立条件。<br>反过来说，如果哪天微软把 <code>wmic.exe</code> 还回来，<code>.EXE</code> 在 <code>PATHEXT</code> 里排在<br><code>.CMD</code> 前面，垫片会自动「让位」，不会打架。这个设计是刻意留的。</p></blockquote><p><strong>性能</strong>：每次调用多一次 PowerShell 启动，实测 90–500 ms。<br>对交互式功能无感；如果是高频循环调用（比如脚本里查上千次进程），会明显变慢。</p><h3 id="4-2-支持的命令范围"><a href="#4-2-支持的命令范围" class="headerlink" title="4.2 支持的命令范围"></a>4.2 支持的命令范围</h3><table><thead><tr><th>命令形态</th><th>支持</th><th>说明</th></tr></thead><tbody><tr><td><code>&lt;别名&gt; where &lt;条件&gt; get &lt;属性,...&gt;</code></td><td>✅</td><td>主力形态</td></tr><tr><td><code>&lt;别名&gt; get &lt;属性&gt;</code></td><td>✅</td><td>无过滤条件</td></tr><tr><td><code>&lt;别名&gt; where &lt;条件&gt;</code></td><td>✅</td><td>输出全部属性，list 格式</td></tr><tr><td><code>&lt;别名&gt;</code></td><td>✅</td><td>输出全部属性，list 格式</td></tr><tr><td><code>/value</code>、<code>/format:list</code></td><td>✅</td><td><code>Prop=Value</code> 形式</td></tr><tr><td><code>/format:csv</code></td><td>✅</td><td><code>Node,Prop1,...</code> + 每行前缀主机名</td></tr><tr><td>带 <code>wmic</code> &#x2F; <code>wmic.exe</code> &#x2F; 完整路径前缀</td><td>✅</td><td>有些调用方会把整条命令一起传进来</td></tr><tr><td><code>&lt;别名&gt; call &lt;方法&gt;</code>（如 <code>process call create</code>）</td><td>❌</td><td>不处理，静默返回空</td></tr><tr><td><code>/node:</code> <code>/user:</code> <code>/password:</code> 远程查询</td><td>❌</td><td><strong>静默返回空</strong>，不会用本机数据冒充远程结果</td></tr><tr><td>其他子命令（<code>wmic /?</code> 等）</td><td>❌</td><td>静默返回空</td></tr></tbody></table><p><strong>设计原则：不支持的语法一律「静默返回空 + 退出码 0」，绝不报错。</strong><br>因为调用方通常只看输出，报错反而会打断它的主流程。</p><blockquote><p>已知别名见 <a href="#51-%E5%88%AB%E5%90%8D%E6%98%A0%E5%B0%84%E8%A1%A8">5.1</a>。不在表里的别名会按 <code>Win32_&lt;首字母大写&gt;</code> 猜一次，<br>猜不到就返回空。需要支持更多时按 <a href="#52-%E5%8A%A0%E4%B8%80%E4%B8%AA%E5%88%AB%E5%90%8D">5.2</a> 加一行即可。</p></blockquote><h3 id="4-3-文件清单"><a href="#4-3-文件清单" class="headerlink" title="4.3 文件清单"></a>4.3 文件清单</h3><table><thead><tr><th>文件</th><th>作用</th></tr></thead><tbody><tr><td><code>wmic.cmd</code></td><td><strong>核心</strong>。转接头，把参数转发给下面的脚本</td></tr><tr><td><code>wmic-shim.ps1</code></td><td><strong>核心</strong>。翻译逻辑：解析 → 查 CIM → 按 wmic 格式输出</td></tr><tr><td><code>安装-wmic垫片.cmd</code></td><td>安装到 <code>System32\Wbem</code>（需管理员），自带自检</td></tr><tr><td><code>安装-wmic垫片-免管理员.cmd</code></td><td>装到 <code>%USERPROFILE%\wmic-shim</code> + 用户 PATH（免管理员）</td></tr><tr><td><code>卸载-wmic垫片.cmd</code></td><td>删除已安装的文件，恢复原状</td></tr><tr><td><code>检查安装状态.cmd</code></td><td>一键自检：文件是否到位 &#x2F; <code>where wmic</code> &#x2F; 实测查询</td></tr></tbody></table><blockquote><p>全部 6 个脚本源码见<a href="#%E9%99%84%E5%BD%95-a%E8%84%9A%E6%9C%AC%E6%BA%90%E7%A0%81">附录 A</a>，也可以直接取用本目录下的同名文件。</p></blockquote><h3 id="4-4-方式一：需要管理员（推荐）"><a href="#4-4-方式一：需要管理员（推荐）" class="headerlink" title="4.4 方式一：需要管理员（推荐）"></a>4.4 方式一：需要管理员（推荐）</h3><p><strong>做法 A：双击脚本</strong></p><p>右键 <code>安装-wmic垫片.cmd</code> → <strong>以管理员身份运行</strong>。脚本会自动复制文件并做自检。</p><p><strong>做法 B：管理员 PowerShell 里粘贴</strong></p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$dst</span> = <span class="string">&quot;<span class="variable">$env:SystemRoot</span>\System32\Wbem&quot;</span></span><br><span class="line"><span class="built_in">Copy-Item</span> <span class="string">&quot;&lt;本目录&gt;\wmic.cmd&quot;</span>      <span class="variable">$dst</span> <span class="literal">-Force</span></span><br><span class="line"><span class="built_in">Copy-Item</span> <span class="string">&quot;&lt;本目录&gt;\wmic-shim.ps1&quot;</span> <span class="variable">$dst</span> <span class="literal">-Force</span></span><br><span class="line">cmd /c <span class="string">&quot;wmic process where name=&#x27;explorer.exe&#x27; get processid,executablepath&quot;</span></span><br></pre></td></tr></table></figure><p><strong>优点</strong>：不需要改 PATH，<strong>不需要重启程序</strong>，装完直接重开那个功能即可。</p><h3 id="4-5-方式二：免管理员"><a href="#4-5-方式二：免管理员" class="headerlink" title="4.5 方式二：免管理员"></a>4.5 方式二：免管理员</h3><p>右键 <code>安装-wmic垫片-免管理员.cmd</code> 运行（无需提权）。它会：</p><ol><li>把两个核心文件复制到 <code>%USERPROFILE%\wmic-shim\</code></li><li>通过 <code>setx PATH</code> 把该目录追加到<strong>用户级 PATH</strong>（不动系统 PATH）</li></ol><blockquote><p>⚠️ <strong>必须完全退出目标程序再重新启动</strong> —— 只有新进程才会带上更新后的 PATH。<br>如果程序是 IDE，记得连 JetBrains Toolbox 一起退。<br>这也是为什么推荐方式一：<code>System32\Wbem</code> 本来就在 PATH 上，省掉重启这一步。</p></blockquote><h3 id="4-6-验证"><a href="#4-6-验证" class="headerlink" title="4.6 验证"></a>4.6 验证</h3><p>双击 <code>检查安装状态.cmd</code>，或手动执行：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. 文件是否到位</span></span><br><span class="line"><span class="built_in">Test-Path</span> <span class="string">&quot;<span class="variable">$env:SystemRoot</span>\System32\Wbem\wmic.cmd&quot;</span>       <span class="comment"># 期望 True</span></span><br><span class="line"><span class="built_in">Test-Path</span> <span class="string">&quot;<span class="variable">$env:SystemRoot</span>\System32\Wbem\wmic-shim.ps1&quot;</span>  <span class="comment"># 期望 True</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. cmd 能否解析到 wmic</span></span><br><span class="line">cmd /c <span class="string">&quot;where wmic&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 查一个「一定在运行」的进程 —— 用 explorer.exe，它永远在</span></span><br><span class="line">cmd /c <span class="string">&quot;wmic process where name=&#x27;explorer.exe&#x27; get processid,executablepath&quot;</span></span><br><span class="line"><span class="comment"># → ExecutablePath           ProcessId</span></span><br><span class="line"><span class="comment"># → C:\Windows\Explorer.EXE  21572</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 4. 查目标程序自己的进程（程序没开时为空是正常的）</span></span><br><span class="line">cmd /c <span class="string">&quot;wmic process where name=&#x27;idea64.exe&#x27; get processid,executablepath&quot;</span></span><br><span class="line"><span class="comment"># → D:\SoftWare\JetBrains\Apps\IntelliJ IDEA Ultimate\bin\idea64.exe  26660</span></span><br></pre></td></tr></table></figure><p>判定标准：</p><ul><li>第 3 步有路径 &#x3D; <strong>垫片工作正常</strong></li><li>第 4 步有路径 &#x3D; 目标程序在运行，它也能检测到</li></ul><blockquote><p>💡 <strong>两个坑</strong></p><ol><li>在 PowerShell 7 会话里直接敲 <code>wmic</code> 可能仍报「找不到」——<blockquote><p>   PowerShell 会缓存命令查找结果。自检请用 <code>cmd /c &quot;wmic ...&quot;</code>，或新开一个终端。<br>2. 第 4 步为空时先确认程序是否真的开着（<code>Get-Process &lt;名字&gt;</code>），别误判成失败。</p></blockquote></li></ol></blockquote><h3 id="4-7-卸载"><a href="#4-7-卸载" class="headerlink" title="4.7 卸载"></a>4.7 卸载</h3><p>右键 <code>卸载-wmic垫片.cmd</code> → 以管理员身份运行，删除 <code>System32\Wbem</code> 下的两个文件即可。<br>免管理员版同理，再手动把用户 PATH 里的 <code>%USERPROFILE%\wmic-shim</code> 去掉。</p><hr><h2 id="五、扩展垫片"><a href="#五、扩展垫片" class="headerlink" title="五、扩展垫片"></a>五、扩展垫片</h2><p>垫片是<strong>为常见语法做的通用翻译器</strong>，不是完整的 wmic 复刻。<br>遇到它不支持的语法时，按下面几节自己加。</p><h3 id="5-1-别名映射表"><a href="#5-1-别名映射表" class="headerlink" title="5.1 别名映射表"></a>5.1 别名映射表</h3><p>脚本里内置了这些别名（wmic 别名 → CIM 类）：</p><table><thead><tr><th>别名</th><th>CIM 类</th><th>别名</th><th>CIM 类</th></tr></thead><tbody><tr><td><code>process</code></td><td><code>Win32_Process</code></td><td><code>printer</code></td><td><code>Win32_Printer</code></td></tr><tr><td><code>os</code></td><td><code>Win32_OperatingSystem</code></td><td><code>printjob</code></td><td><code>Win32_PrintJob</code></td></tr><tr><td><code>computersystem</code></td><td><code>Win32_ComputerSystem</code></td><td><code>share</code></td><td><code>Win32_Share</code></td></tr><tr><td><code>logicaldisk</code> &#x2F; <code>filesystem</code></td><td><code>Win32_LogicalDisk</code></td><td><code>netuse</code></td><td><code>Win32_NetworkConnection</code></td></tr><tr><td><code>volume</code></td><td><code>Win32_Volume</code></td><td><code>nic</code></td><td><code>Win32_NetworkAdapter</code></td></tr><tr><td><code>diskdrive</code></td><td><code>Win32_DiskDrive</code></td><td><code>nicconfig</code></td><td><code>Win32_NetworkAdapterConfiguration</code></td></tr><tr><td><code>partition</code></td><td><code>Win32_DiskPartition</code></td><td><code>netprotocol</code></td><td><code>Win32_NetworkProtocol</code></td></tr><tr><td><code>cdrom</code></td><td><code>Win32_CDROMDrive</code></td><td><code>useraccount</code></td><td><code>Win32_UserAccount</code></td></tr><tr><td><code>service</code></td><td><code>Win32_Service</code></td><td><code>group</code></td><td><code>Win32_Group</code></td></tr><tr><td><code>sysdriver</code></td><td><code>Win32_SystemDriver</code></td><td><code>environment</code></td><td><code>Win32_Environment</code></td></tr><tr><td><code>bios</code></td><td><code>Win32_BIOS</code></td><td><code>startup</code></td><td><code>Win32_StartupCommand</code></td></tr><tr><td><code>cpu</code></td><td><code>Win32_Processor</code></td><td><code>timezone</code></td><td><code>Win32_TimeZone</code></td></tr><tr><td><code>baseboard</code></td><td><code>Win32_BaseBoard</code></td><td><code>qfe</code></td><td><code>Win32_QuickFixEngineering</code></td></tr><tr><td><code>memorychip</code></td><td><code>Win32_PhysicalMemory</code></td><td><code>product</code></td><td><code>Win32_Product</code></td></tr><tr><td><code>sounddevice</code></td><td><code>Win32_SoundDevice</code></td><td><code>desktop</code></td><td><code>Win32_Desktop</code></td></tr><tr><td><code>shadowcopy</code></td><td><code>Win32_ShadowCopy</code></td><td></td><td></td></tr></tbody></table><p>不在表里的别名，会先按 <code>Win32_&lt;首字母大写&gt;</code> 猜一次（如 <code>win32_bios</code> → <code>Win32_BIOS</code>），<br>猜不到就返回空。</p><h3 id="5-2-加一个别名"><a href="#5-2-加一个别名" class="headerlink" title="5.2 加一个别名"></a>5.2 加一个别名</h3><p>找到脚本里的 <code>$AliasMap</code>，加一行即可：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$AliasMap</span> = <span class="selector-tag">@</span>&#123;</span><br><span class="line">    <span class="string">&#x27;process&#x27;</span>        = <span class="string">&#x27;Win32_Process&#x27;</span></span><br><span class="line">    <span class="comment"># ...</span></span><br><span class="line">    <span class="string">&#x27;idecontroller&#x27;</span>  = <span class="string">&#x27;Win32_IDEController&#x27;</span>   <span class="comment"># ← 新增</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>怎么知道别名对应哪个类？</strong> 两种办法：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 办法一：凭经验猜 + 验证</span></span><br><span class="line"><span class="built_in">Get-CimClass</span> <span class="literal">-ClassName</span> Win32_IDEController | <span class="built_in">Select-Object</span> <span class="literal">-ExpandProperty</span> CimClassName</span><br><span class="line"></span><br><span class="line"><span class="comment"># 办法二：全量列出 Win32_* 类，用关键字筛</span></span><br><span class="line"><span class="built_in">Get-CimClass</span> <span class="literal">-ClassName</span> Win32_* |</span><br><span class="line">  <span class="built_in">Where-Object</span> &#123; <span class="variable">$_</span>.CimClassName <span class="operator">-like</span> <span class="string">&#x27;*Network*&#x27;</span> &#125; |</span><br><span class="line">  <span class="built_in">Select-Object</span> <span class="literal">-ExpandProperty</span> CimClassName</span><br></pre></td></tr></table></figure><p>改完直接测：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cmd /c <span class="string">&quot;wmic idecontroller get deviceid,name&quot;</span></span><br></pre></td></tr></table></figure><h3 id="5-3-where-条件的写法"><a href="#5-3-where-条件的写法" class="headerlink" title="5.3 where 条件的写法"></a>5.3 where 条件的写法</h3><p><code>where</code> 后面的内容会<strong>原样透传给 WQL</strong>（<code>Get-CimInstance -Filter</code>），所以：</p><table><thead><tr><th>写法</th><th>支持</th><th>备注</th></tr></thead><tbody><tr><td><code>name=&#39;x.exe&#39;</code></td><td>✅</td><td>属性名<strong>大小写不敏感</strong>，<code>name</code> &#x2F; <code>Name</code> 都行</td></tr><tr><td><code>processid=1234</code></td><td>✅</td><td>数字不用加引号</td></tr><tr><td><code>state=&#39;Running&#39;</code></td><td>✅</td><td>字符串要加引号</td></tr><tr><td><code>name like &#39;%chrome%&#39;</code></td><td>✅</td><td><code>%</code> 是通配符</td></tr><tr><td><code>a=&#39;1&#39; and b=&#39;2&#39;</code></td><td>✅</td><td><code>and</code> &#x2F; <code>or</code></td></tr><tr><td><code>(a=&#39;1&#39; or a=&#39;2&#39;)</code></td><td>✅</td><td>括号</td></tr><tr><td><code>where &quot;name=&#39;x&#39;&quot;</code></td><td>✅</td><td>整体被引号包住会自动剥掉</td></tr></tbody></table><p><strong>补救机制</strong>：如果首次查询因属性名大小写或拼写失败，<br>脚本会读一次类定义、把属性名纠正成规范大小写后<strong>自动重试一次</strong>；<br>仍失败就返回空。</p><blockquote><p>⚠️ <code>where</code> 里引号内的 <code>/</code> 不会被当成开关 ——<br>所以 <code>where caption=&#39;a/b&#39;</code> 是安全的，<code>/b</code> 不会被误删。</p></blockquote><h3 id="5-4-输出格式"><a href="#5-4-输出格式" class="headerlink" title="5.4 输出格式"></a>5.4 输出格式</h3><table><thead><tr><th>格式</th><th>触发方式</th><th>样式</th></tr></thead><tbody><tr><td>table（默认）</td><td>无开关</td><td>表头 + 数据行，列宽对齐，列之间两个空格</td></tr><tr><td>list</td><td><code>/value</code>、<code>/format:list</code></td><td>每行 <code>Prop=Value</code>，实例之间空一行</td></tr><tr><td>csv</td><td><code>/format:csv</code></td><td><code>Node,Prop1,...</code> + 每行前缀计算机名</td></tr></tbody></table><p>两个刻意做的<strong>保真细节</strong>，都是为了「让老程序解析得出来」：</p><ol><li><strong>列按属性名字母序排列</strong> —— 这是 wmic 默认表格输出的行为。<br>所以 <code>get processid,executablepath</code> 得到的是 <code>ExecutablePath  ProcessId</code>（字母序），<br>而不是你写的顺序。垫片保持一致，避免调用方按位置解析时错位。</li><li><strong>属性名输出规范大小写</strong> —— 你写 <code>get processid</code>，输出的是 <code>ProcessId</code>。<br>调用方如果按表头字符串匹配，这一步是必须的。</li></ol><blockquote><p>属性名写错时（如 <code>get bogusproperty</code>），垫片<strong>返回空</strong>而不是吐一堆空行 ——<br>真 wmic 此时会报 <code>Invalid property</code>，返回空是更安全的降级。</p></blockquote><h3 id="5-5-调试方法"><a href="#5-5-调试方法" class="headerlink" title="5.5 调试方法"></a>5.5 调试方法</h3><p><strong>单独测一条命令</strong>（不经过 cmd，直接看脚本行为）：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">powershell <span class="literal">-NoProfile</span> <span class="literal">-ExecutionPolicy</span> Bypass `</span><br><span class="line">  <span class="operator">-File</span> <span class="string">&quot;C:\Windows\System32\Wbem\wmic-shim.ps1&quot;</span> `</span><br><span class="line">  <span class="string">&quot;process where name=&#x27;explorer.exe&#x27; get processid,executablepath&quot;</span></span><br></pre></td></tr></table></figure><p><strong>直接对照 CIM 的原始结果</strong>，确认是垫片的问题还是 WMI 本来就没数据：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Get-CimInstance</span> Win32_Process <span class="literal">-Filter</span> <span class="string">&quot;Name=&#x27;explorer.exe&#x27;&quot;</span> |</span><br><span class="line">  <span class="built_in">Select-Object</span> ProcessId, ExecutablePath</span><br></pre></td></tr></table></figure><p><strong>看退出码</strong>（正常应始终是 0）：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">wmic process get name &gt;<span class="built_in">nul</span></span><br><span class="line"><span class="built_in">echo</span> <span class="variable">%ERRORLEVEL%</span></span><br></pre></td></tr></table></figure><p><strong>脚本语法自检</strong>（改完垫片后强烈建议跑一次）：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$src</span> = <span class="built_in">Get-Content</span> <span class="literal">-Raw</span> <span class="string">&quot;C:\Windows\System32\Wbem\wmic-shim.ps1&quot;</span></span><br><span class="line"><span class="variable">$e</span> = <span class="variable">$null</span></span><br><span class="line">[<span class="built_in">void</span>][<span class="type">System.Management.Automation.Language.Parser</span>]::ParseInput(<span class="variable">$src</span>, [<span class="type">ref</span>]<span class="variable">$null</span>, [<span class="type">ref</span>]<span class="variable">$e</span>)</span><br><span class="line"><span class="keyword">if</span> (<span class="variable">$e</span>) &#123; <span class="variable">$e</span> | <span class="built_in">ForEach-Object</span> &#123; <span class="string">&quot;<span class="variable">$</span>(<span class="variable">$_</span>.Extent.StartLineNumber): <span class="variable">$</span>(<span class="variable">$_</span>.Message)&quot;</span> &#125; &#125; <span class="keyword">else</span> &#123; <span class="string">&quot;语法 OK&quot;</span> &#125;</span><br></pre></td></tr></table></figure><hr><h2 id="六、常见问题"><a href="#六、常见问题" class="headerlink" title="六、常见问题"></a>六、常见问题</h2><p><strong>Q：为什么不直接让程序手工填路径？</strong><br>A：得看程序有没有给你这个入口。案例里那个字段绑定的是 <code>JLabel</code>（只读标签），<br>根本填不了。<strong>先按 <a href="#21-%E4%B8%89%E6%AD%A5%E5%AE%9A%E4%BD%8D%E6%B3%95">2.1</a> 第 3 步确认有没有绕过口子</strong>，再决定。</p><p><strong>Q：改程序的配置文件行不行？</strong><br>A：必须确认代码<strong>真的会读回</strong>这个值。案例里的 <code>ideaPath</code> 是只写不读的缓存，<br>改了不生效，还会被程序退出时用内存里的值覆盖掉。</p><p><strong>Q：为什么垫片放在 <code>System32\Wbem</code> 而不是别的地方？</strong><br>A：那个目录<strong>本来就在系统 PATH 上</strong>，而且正是 <code>wmic.exe</code> 原来的家。<br>放这里不用改 PATH、不用重启程序，命中优先级也自然。</p><p><strong>Q：装了垫片之后，以后系统更新会冲突吗？</strong><br>A：不会。如果将来 <code>wmic.exe</code> 被恢复，<code>.EXE</code> 在 <code>PATHEXT</code> 中优先于 <code>.CMD</code>，垫片自动让位。</p><p><strong>Q：会影响其他用 wmic 的工具吗？</strong><br>A：会 —— 它们现在拿到的是本垫片的输出。好处是覆盖面一下变广了（所有走 PATH 调 wmic 的程序都受益）；<br>代价是<strong>如果某个工具用了垫片不支持的语法，它会拿到空结果</strong>。<br>组内如果有多个工具依赖 wmic，建议先摸清各自用了什么语法，<br>不够用就按<a href="#%E4%BA%94%E6%89%A9%E5%B1%95%E5%9E%AB%E7%89%87">第五章</a>扩展，或改用方案 3（官方包）。</p><p><strong>Q：怎么知道还有哪些程序在偷偷调 wmic？</strong><br>A：装完垫片后开一次 Process Monitor，过滤 <code>Operation = Process Start</code>，<br>看谁的命令行里有 <code>wmic</code>。或者直接搜你的脚本仓库。</p><p><strong>Q：安全软件会报毒吗？</strong><br>A：垫片只是两个纯文本脚本，不含二进制、不联网、不写注册表（免管理员版会写用户 PATH）。<br>如果企业 EDR 对「往 System32 写文件」敏感，可能触发告警，需要加白或改用免管理员版。</p><p><strong>Q：能用 <code>Get-WmiObject</code> 代替 <code>Get-CimInstance</code> 吗？</strong><br>A：不建议。<code>Get-WmiObject</code> 是老的 PowerShell 5.1 写法，PowerShell 7 里已被移除。<br>新写的东西统一用 <code>Get-CimInstance</code>。</p><hr><h2 id="附录-A：脚本源码"><a href="#附录-A：脚本源码" class="headerlink" title="附录 A：脚本源码"></a>附录 A：脚本源码</h2><h3 id="A-1-wmic-cmd（转接头）"><a href="#A-1-wmic-cmd（转接头）" class="headerlink" title="A.1 wmic.cmd（转接头）"></a>A.1 wmic.cmd（转接头）</h3><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">@<span class="built_in">echo</span> off</span><br><span class="line"><span class="comment">rem ============================================================</span></span><br><span class="line"><span class="comment">rem  wmic shim  (drop-in replacement for the removed wmic.exe)</span></span><br><span class="line"><span class="comment">rem  Delegates to wmic-shim.ps1 sitting next to this file.</span></span><br><span class="line"><span class="comment">rem ============================================================</span></span><br><span class="line"><span class="built_in">setlocal</span> EnableExtensions</span><br><span class="line">powershell -NoProfile -ExecutionPolicy Bypass -File &quot;%~dp0wmic-shim.ps1&quot; %*</span><br><span class="line"><span class="keyword">exit</span> /b <span class="variable">%ERRORLEVEL%</span></span><br></pre></td></tr></table></figure><h3 id="A-2-wmic-shim-ps1（翻译逻辑）"><a href="#A-2-wmic-shim-ps1（翻译逻辑）" class="headerlink" title="A.2 wmic-shim.ps1（翻译逻辑）"></a>A.2 wmic-shim.ps1（翻译逻辑）</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ============================================================</span></span><br><span class="line"><span class="comment">#  wmic shim  --  a drop-in stand-in for the removed wmic.exe</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#  背景</span></span><br><span class="line"><span class="comment">#    Windows 11 24H2 / 25H2 / 26H1（2026-08 起）已彻底移除 wmic.exe，</span></span><br><span class="line"><span class="comment">#    且不再作为「可选功能」提供。任何 shell out 到 wmic 的老程序</span></span><br><span class="line"><span class="comment">#    —— IDE 插件、构建脚本、运维脚本、安装包、监控采集器 ——</span></span><br><span class="line"><span class="comment">#    都会以「&#x27;wmic&#x27; 不是内部或外部命令」失败。</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#  做法</span></span><br><span class="line"><span class="comment">#    把 wmic 的命令行翻译成 CIM 查询（Get-CimInstance），</span></span><br><span class="line"><span class="comment">#    再按 wmic 的格式输出，让调用方无感。</span></span><br><span class="line"><span class="comment">#    WMI 服务本身并未被移除，所以这条路完全可行。</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#  支持的语法</span></span><br><span class="line"><span class="comment">#      &lt;别名&gt; [where &lt;条件&gt;] get &lt;属性[,属性...]&gt;  [/value | /format:...]</span></span><br><span class="line"><span class="comment">#      &lt;别名&gt; [where &lt;条件&gt;]                        （无 get → 全部属性）</span></span><br><span class="line"><span class="comment">#      &lt;别名&gt; get &lt;属性&gt;</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#  输出格式</span></span><br><span class="line"><span class="comment">#      默认            table：表头 + 数据行，列按属性名字母序（与 wmic 一致）</span></span><br><span class="line"><span class="comment">#      /value          list ：每行 Prop=Value</span></span><br><span class="line"><span class="comment">#      /format:list    list ：同上</span></span><br><span class="line"><span class="comment">#      /format:csv     csv  ：Node,Prop1,... + 每行前缀计算机名</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#  不支持的语法</span></span><br><span class="line"><span class="comment">#      静默返回空、退出码 0 —— 不报错，避免打断调用方的主流程。</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#  输入</span></span><br><span class="line"><span class="comment">#      原始 wmic 参数行，作为脚本参数传入（兼容环境变量 WBD_WMIC_ARGS）</span></span><br><span class="line"><span class="comment"># ============================================================</span></span><br><span class="line"></span><br><span class="line"><span class="variable">$ErrorActionPreference</span> = <span class="string">&#x27;SilentlyContinue&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 让输出尽量贴近 wmic：使用控制台的 OEM 代码页</span></span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line">    [<span class="type">Console</span>]::OutputEncoding = [<span class="type">System.Text.Encoding</span>]::GetEncoding(</span><br><span class="line">        [<span class="type">System.Globalization.CultureInfo</span>]::CurrentCulture.TextInfo.OEMCodePage)</span><br><span class="line">&#125; <span class="keyword">catch</span> &#123; &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ------------------------------------------------------------</span></span><br><span class="line"><span class="comment">#  把 CIM 的值渲染成 wmic 风格的字符串</span></span><br><span class="line"><span class="comment"># ------------------------------------------------------------</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Format-WmicValue</span><span class="params">(<span class="variable">$v</span>)</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$null</span> <span class="operator">-eq</span> <span class="variable">$v</span>) &#123; <span class="keyword">return</span> <span class="string">&#x27;&#x27;</span> &#125;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$v</span> <span class="operator">-is</span> [<span class="built_in">array</span>]) &#123;</span><br><span class="line">        <span class="variable">$parts</span> = <span class="selector-tag">@</span>()</span><br><span class="line">        <span class="keyword">foreach</span> (<span class="variable">$item</span> <span class="keyword">in</span> <span class="variable">$v</span>) &#123; <span class="variable">$parts</span> += (<span class="built_in">Format-WmicValue</span> <span class="variable">$item</span>) &#125;</span><br><span class="line">        <span class="keyword">return</span> (<span class="variable">$parts</span> <span class="operator">-join</span> <span class="string">&#x27;,&#x27;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$v</span> <span class="operator">-is</span> [<span class="built_in">datetime</span>]) &#123; <span class="keyword">return</span> <span class="variable">$v</span>.ToString(<span class="string">&#x27;yyyyMMddHHmmss&#x27;</span>) + <span class="string">&#x27;.000000+000&#x27;</span> &#125;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$v</span> <span class="operator">-is</span> [<span class="built_in">bool</span>]) &#123; <span class="keyword">if</span> (<span class="variable">$v</span>) &#123; <span class="keyword">return</span> <span class="string">&#x27;TRUE&#x27;</span> &#125; <span class="keyword">else</span> &#123; <span class="keyword">return</span> <span class="string">&#x27;FALSE&#x27;</span> &#125; &#125;</span><br><span class="line">    <span class="keyword">return</span> [<span class="built_in">string</span>]<span class="variable">$v</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ------------------------------------------------------------</span></span><br><span class="line"><span class="comment">#  CSV 单元格：含逗号/引号/换行时加引号（与 wmic /format:csv 一致）</span></span><br><span class="line"><span class="comment"># ------------------------------------------------------------</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Format-CsvCell</span><span class="params">([string]<span class="variable">$v</span>)</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> ([<span class="built_in">string</span>]::IsNullOrEmpty(<span class="variable">$v</span>)) &#123; <span class="keyword">return</span> <span class="string">&#x27;&#x27;</span> &#125;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$v</span> <span class="operator">-match</span> <span class="string">&#x27;[&quot;,\r\n]&#x27;</span>) &#123; <span class="keyword">return</span> <span class="string">&#x27;&quot;&#x27;</span> + (<span class="variable">$v</span> <span class="operator">-replace</span> <span class="string">&#x27;&quot;&#x27;</span>, <span class="string">&#x27;&quot;&quot;&#x27;</span>) + <span class="string">&#x27;&quot;&#x27;</span> &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="variable">$v</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ------------------------------------------------------------</span></span><br><span class="line"><span class="comment">#  在字符串中查找关键字（作为独立单词、且不在引号内）</span></span><br><span class="line"><span class="comment">#  用于区分 `where` / `get`，避免把  name=&#x27;get.exe&#x27;  里的 get 误判成关键字</span></span><br><span class="line"><span class="comment">#  找到返回下标，找不到返回 -1</span></span><br><span class="line"><span class="comment"># ------------------------------------------------------------</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Find-WmicKeyword</span><span class="params">([string]<span class="variable">$s</span>, [string]<span class="variable">$kw</span>)</span></span> &#123;</span><br><span class="line">    <span class="variable">$inQuote</span> = <span class="variable">$false</span></span><br><span class="line">    <span class="variable">$quoteChar</span> = [<span class="built_in">char</span>]<span class="number">0</span></span><br><span class="line">    <span class="variable">$n</span> = <span class="variable">$s</span>.Length</span><br><span class="line">    <span class="variable">$k</span> = <span class="variable">$kw</span>.Length</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="variable">$i</span> = <span class="number">0</span>; <span class="variable">$i</span> <span class="operator">-lt</span> <span class="variable">$n</span>; <span class="variable">$i</span>++) &#123;</span><br><span class="line">        <span class="variable">$c</span> = <span class="variable">$s</span><span class="function">[<span class="variable">$i</span>]</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (<span class="variable">$inQuote</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (<span class="variable">$c</span> <span class="operator">-eq</span> <span class="variable">$quoteChar</span>) &#123; <span class="variable">$inQuote</span> = <span class="variable">$false</span> &#125;</span><br><span class="line">            <span class="keyword">continue</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (<span class="variable">$c</span> <span class="operator">-eq</span> <span class="string">&quot;&#x27;&quot;</span> <span class="operator">-or</span> <span class="variable">$c</span> <span class="operator">-eq</span> <span class="string">&#x27;&quot;&#x27;</span>) &#123; <span class="variable">$quoteChar</span> = <span class="variable">$c</span>; <span class="variable">$inQuote</span> = <span class="variable">$true</span>; <span class="keyword">continue</span> &#125;</span><br><span class="line">        <span class="keyword">if</span> (<span class="variable">$i</span> + <span class="variable">$k</span> <span class="operator">-gt</span> <span class="variable">$n</span>) &#123; <span class="keyword">break</span> &#125;</span><br><span class="line">        <span class="keyword">if</span> ([<span class="built_in">string</span>]::<span class="built_in">Compare</span>(<span class="variable">$s</span>.Substring(<span class="variable">$i</span>, <span class="variable">$k</span>), <span class="variable">$kw</span>, <span class="variable">$true</span>) <span class="operator">-ne</span> <span class="number">0</span>) &#123; <span class="keyword">continue</span> &#125;</span><br><span class="line"></span><br><span class="line">        <span class="variable">$before</span> = <span class="string">&#x27; &#x27;</span></span><br><span class="line">        <span class="keyword">if</span> (<span class="variable">$i</span> <span class="operator">-gt</span> <span class="number">0</span>) &#123; <span class="variable">$before</span> = <span class="variable">$s</span>[<span class="variable">$i</span> - <span class="number">1</span>] &#125;</span><br><span class="line">        <span class="variable">$after</span> = <span class="string">&#x27; &#x27;</span></span><br><span class="line">        <span class="keyword">if</span> (<span class="variable">$i</span> + <span class="variable">$k</span> <span class="operator">-lt</span> <span class="variable">$n</span>) &#123; <span class="variable">$after</span> = <span class="variable">$s</span>[<span class="variable">$i</span> + <span class="variable">$k</span>] &#125;</span><br><span class="line"></span><br><span class="line">        <span class="variable">$okBefore</span> = <span class="operator">-not</span> ([<span class="built_in">char</span>]::IsLetterOrDigit(<span class="variable">$before</span>) <span class="operator">-or</span> <span class="variable">$before</span> <span class="operator">-eq</span> <span class="string">&#x27;_&#x27;</span>)</span><br><span class="line">        <span class="variable">$okAfter</span> = <span class="operator">-not</span> ([<span class="built_in">char</span>]::IsLetterOrDigit(<span class="variable">$after</span>) <span class="operator">-or</span> <span class="variable">$after</span> <span class="operator">-eq</span> <span class="string">&#x27;_&#x27;</span>)</span><br><span class="line">        <span class="keyword">if</span> (<span class="variable">$okBefore</span> <span class="operator">-and</span> <span class="variable">$okAfter</span>) &#123; <span class="keyword">return</span> <span class="variable">$i</span> &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">-1</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ------------------------------------------------------------</span></span><br><span class="line"><span class="comment">#  按列宽渲染一行（列之间两个空格，与 wmic 的表格观感一致）</span></span><br><span class="line"><span class="comment"># ------------------------------------------------------------</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Render-WmicRow</span><span class="params">(<span class="variable">$cells</span>, <span class="variable">$widths</span>)</span></span> &#123;</span><br><span class="line">    <span class="variable">$parts</span> = <span class="selector-tag">@</span>()</span><br><span class="line">    <span class="keyword">for</span> (<span class="variable">$i</span> = <span class="number">0</span>; <span class="variable">$i</span> <span class="operator">-lt</span> <span class="variable">$cells</span>.Count; <span class="variable">$i</span>++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="variable">$i</span> <span class="operator">-eq</span> <span class="variable">$cells</span>.Count - <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="variable">$parts</span> += [<span class="built_in">string</span>]<span class="variable">$cells</span>[<span class="variable">$i</span>]</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="variable">$parts</span> += ([<span class="built_in">string</span>]<span class="variable">$cells</span>[<span class="variable">$i</span>]).PadRight(<span class="variable">$widths</span>[<span class="variable">$i</span>])</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> (<span class="variable">$parts</span> <span class="operator">-join</span> <span class="string">&#x27;  &#x27;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ------------------------------------------------------------</span></span><br><span class="line"><span class="comment">#  去掉 wmic 的开关（/value、/format:list、/node:xxx …）</span></span><br><span class="line"><span class="comment">#  只在「词首」的 / 才当开关，且绝不碰引号内的内容</span></span><br><span class="line"><span class="comment">#  —— 否则  where caption=&#x27;a/b&#x27;  里的 /b 会被误删</span></span><br><span class="line"><span class="comment"># ------------------------------------------------------------</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Remove-WmicSwitches</span><span class="params">([string]<span class="variable">$s</span>)</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> ([<span class="built_in">string</span>]::IsNullOrEmpty(<span class="variable">$s</span>)) &#123; <span class="keyword">return</span> <span class="variable">$s</span> &#125;</span><br><span class="line"></span><br><span class="line">    <span class="variable">$out</span> = <span class="built_in">New-Object</span> System.Text.StringBuilder</span><br><span class="line">    <span class="variable">$inQuote</span> = <span class="variable">$false</span></span><br><span class="line">    <span class="variable">$quoteChar</span> = [<span class="built_in">char</span>]<span class="number">0</span></span><br><span class="line">    <span class="variable">$n</span> = <span class="variable">$s</span>.Length</span><br><span class="line">    <span class="variable">$i</span> = <span class="number">0</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> (<span class="variable">$i</span> <span class="operator">-lt</span> <span class="variable">$n</span>) &#123;</span><br><span class="line">        <span class="variable">$c</span> = <span class="variable">$s</span><span class="function">[<span class="variable">$i</span>]</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (<span class="variable">$inQuote</span>) &#123;</span><br><span class="line">            [<span class="built_in">void</span>]<span class="variable">$out</span>.Append(<span class="variable">$c</span>)</span><br><span class="line">            <span class="keyword">if</span> (<span class="variable">$c</span> <span class="operator">-eq</span> <span class="variable">$quoteChar</span>) &#123; <span class="variable">$inQuote</span> = <span class="variable">$false</span> &#125;</span><br><span class="line">            <span class="variable">$i</span>++</span><br><span class="line">            <span class="keyword">continue</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (<span class="variable">$c</span> <span class="operator">-eq</span> <span class="string">&quot;&#x27;&quot;</span> <span class="operator">-or</span> <span class="variable">$c</span> <span class="operator">-eq</span> <span class="string">&#x27;&quot;&#x27;</span>) &#123;</span><br><span class="line">            <span class="variable">$quoteChar</span> = <span class="variable">$c</span>; <span class="variable">$inQuote</span> = <span class="variable">$true</span></span><br><span class="line">            [<span class="built_in">void</span>]<span class="variable">$out</span>.Append(<span class="variable">$c</span>); <span class="variable">$i</span>++</span><br><span class="line">            <span class="keyword">continue</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (<span class="variable">$c</span> <span class="operator">-eq</span> <span class="string">&#x27;/&#x27;</span> <span class="operator">-and</span> (<span class="variable">$i</span> <span class="operator">-eq</span> <span class="number">0</span> <span class="operator">-or</span> [<span class="built_in">char</span>]::IsWhiteSpace(<span class="variable">$s</span>[<span class="variable">$i</span> - <span class="number">1</span>]))) &#123;</span><br><span class="line">            <span class="keyword">while</span> (<span class="variable">$i</span> <span class="operator">-lt</span> <span class="variable">$n</span> <span class="operator">-and</span> <span class="operator">-not</span> [<span class="built_in">char</span>]::IsWhiteSpace(<span class="variable">$s</span>[<span class="variable">$i</span>])) &#123; <span class="variable">$i</span>++ &#125;</span><br><span class="line">            <span class="keyword">continue</span></span><br><span class="line">        &#125;</span><br><span class="line">        [<span class="built_in">void</span>]<span class="variable">$out</span>.Append(<span class="variable">$c</span>)</span><br><span class="line">        <span class="variable">$i</span>++</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="variable">$out</span>.ToString()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ------------------------------------------------------------</span></span><br><span class="line"><span class="comment">#  修正 where 条件里的属性名大小写（仅在首次查询失败时作为补救）</span></span><br><span class="line"><span class="comment">#    name=&#x27;x&#x27;  →  Name=&#x27;x&#x27;</span></span><br><span class="line"><span class="comment"># ------------------------------------------------------------</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Repair-WmicFilter</span><span class="params">([string]<span class="variable">$ClassName</span>, [string]<span class="variable">$Filter</span>)</span></span> &#123;</span><br><span class="line">    <span class="variable">$cls</span> = <span class="variable">$null</span></span><br><span class="line">    <span class="keyword">try</span> &#123; <span class="variable">$cls</span> = <span class="built_in">Get-CimClass</span> <span class="literal">-ClassName</span> <span class="variable">$ClassName</span> <span class="literal">-ErrorAction</span> Stop &#125; <span class="keyword">catch</span> &#123; <span class="keyword">return</span> <span class="variable">$Filter</span> &#125;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$null</span> <span class="operator">-eq</span> <span class="variable">$cls</span>) &#123; <span class="keyword">return</span> <span class="variable">$Filter</span> &#125;</span><br><span class="line"></span><br><span class="line">    <span class="variable">$out</span> = <span class="variable">$Filter</span></span><br><span class="line">    <span class="keyword">foreach</span> (<span class="variable">$p</span> <span class="keyword">in</span> <span class="variable">$cls</span>.CimClassProperties) &#123;</span><br><span class="line">        <span class="variable">$name</span> = <span class="variable">$p</span>.Name</span><br><span class="line">        <span class="keyword">if</span> ([<span class="built_in">string</span>]::IsNullOrEmpty(<span class="variable">$name</span>)) &#123; <span class="keyword">continue</span> &#125;</span><br><span class="line">        <span class="variable">$pattern</span> = <span class="string">&#x27;(?i)\b&#x27;</span> + [<span class="type">regex</span>]::Escape(<span class="variable">$name</span>) + <span class="string">&#x27;\b(\s*[=&lt;&gt;])&#x27;</span></span><br><span class="line">        <span class="variable">$out</span> = [<span class="type">regex</span>]::Replace(<span class="variable">$out</span>, <span class="variable">$pattern</span>, (<span class="variable">$name</span> + <span class="string">&#x27;$1&#x27;</span>))</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="variable">$out</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ============================================================</span></span><br><span class="line"><span class="comment">#  主逻辑：把一行 wmic 参数翻译成 CIM 查询并按 wmic 格式输出</span></span><br><span class="line"><span class="comment"># ============================================================</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Invoke-WmicShim</span><span class="params">([string]<span class="variable">$RawArgs</span>)</span></span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> ([<span class="built_in">string</span>]::IsNullOrWhiteSpace(<span class="variable">$RawArgs</span>)) &#123; <span class="keyword">return</span> &#125;</span><br><span class="line">    <span class="variable">$raw</span> = <span class="variable">$RawArgs</span>.Trim()</span><br><span class="line"></span><br><span class="line">    <span class="comment"># ---------- 远程查询：不支持 ---------------------------------</span></span><br><span class="line">    <span class="comment"># /node: /user: /password: 这些开关意味着「查别的机器」。</span></span><br><span class="line">    <span class="comment"># 本垫片只做本机查询，此时宁可返回空，也绝不把本机数据</span></span><br><span class="line">    <span class="comment"># 当成远程结果返回 —— 静默给错数据比报错更危险。</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$raw</span> <span class="operator">-match</span> <span class="string">&#x27;(?i)/(node|user|password|implevel|authlevel)\s*:&#x27;</span>) &#123; <span class="keyword">return</span> &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># ---------- wmic 别名 → CIM 类 -------------------------------</span></span><br><span class="line">    <span class="comment"># 常见别名基本够用；不在此表里的会按 Win32_&lt;首字母大写&gt; 猜测，</span></span><br><span class="line">    <span class="comment"># 猜不到就静默返回空。需要更多别名时往这里加一行即可。</span></span><br><span class="line">    <span class="variable">$AliasMap</span> = <span class="selector-tag">@</span>&#123;</span><br><span class="line">        <span class="string">&#x27;process&#x27;</span>        = <span class="string">&#x27;Win32_Process&#x27;</span></span><br><span class="line">        <span class="string">&#x27;os&#x27;</span>             = <span class="string">&#x27;Win32_OperatingSystem&#x27;</span></span><br><span class="line">        <span class="string">&#x27;computersystem&#x27;</span> = <span class="string">&#x27;Win32_ComputerSystem&#x27;</span></span><br><span class="line">        <span class="string">&#x27;logicaldisk&#x27;</span>    = <span class="string">&#x27;Win32_LogicalDisk&#x27;</span></span><br><span class="line">        <span class="string">&#x27;filesystem&#x27;</span>     = <span class="string">&#x27;Win32_LogicalDisk&#x27;</span></span><br><span class="line">        <span class="string">&#x27;volume&#x27;</span>         = <span class="string">&#x27;Win32_Volume&#x27;</span></span><br><span class="line">        <span class="string">&#x27;diskdrive&#x27;</span>      = <span class="string">&#x27;Win32_DiskDrive&#x27;</span></span><br><span class="line">        <span class="string">&#x27;partition&#x27;</span>      = <span class="string">&#x27;Win32_DiskPartition&#x27;</span></span><br><span class="line">        <span class="string">&#x27;cdrom&#x27;</span>          = <span class="string">&#x27;Win32_CDROMDrive&#x27;</span></span><br><span class="line">        <span class="string">&#x27;service&#x27;</span>        = <span class="string">&#x27;Win32_Service&#x27;</span></span><br><span class="line">        <span class="string">&#x27;sysdriver&#x27;</span>      = <span class="string">&#x27;Win32_SystemDriver&#x27;</span></span><br><span class="line">        <span class="string">&#x27;bios&#x27;</span>           = <span class="string">&#x27;Win32_BIOS&#x27;</span></span><br><span class="line">        <span class="string">&#x27;cpu&#x27;</span>            = <span class="string">&#x27;Win32_Processor&#x27;</span></span><br><span class="line">        <span class="string">&#x27;baseboard&#x27;</span>      = <span class="string">&#x27;Win32_BaseBoard&#x27;</span></span><br><span class="line">        <span class="string">&#x27;memorychip&#x27;</span>     = <span class="string">&#x27;Win32_PhysicalMemory&#x27;</span></span><br><span class="line">        <span class="string">&#x27;sounddevice&#x27;</span>    = <span class="string">&#x27;Win32_SoundDevice&#x27;</span></span><br><span class="line">        <span class="string">&#x27;printer&#x27;</span>        = <span class="string">&#x27;Win32_Printer&#x27;</span></span><br><span class="line">        <span class="string">&#x27;printjob&#x27;</span>       = <span class="string">&#x27;Win32_PrintJob&#x27;</span></span><br><span class="line">        <span class="string">&#x27;share&#x27;</span>          = <span class="string">&#x27;Win32_Share&#x27;</span></span><br><span class="line">        <span class="string">&#x27;netuse&#x27;</span>         = <span class="string">&#x27;Win32_NetworkConnection&#x27;</span></span><br><span class="line">        <span class="string">&#x27;nic&#x27;</span>            = <span class="string">&#x27;Win32_NetworkAdapter&#x27;</span></span><br><span class="line">        <span class="string">&#x27;nicconfig&#x27;</span>      = <span class="string">&#x27;Win32_NetworkAdapterConfiguration&#x27;</span></span><br><span class="line">        <span class="string">&#x27;netprotocol&#x27;</span>    = <span class="string">&#x27;Win32_NetworkProtocol&#x27;</span></span><br><span class="line">        <span class="string">&#x27;useraccount&#x27;</span>    = <span class="string">&#x27;Win32_UserAccount&#x27;</span></span><br><span class="line">        <span class="string">&#x27;group&#x27;</span>          = <span class="string">&#x27;Win32_Group&#x27;</span></span><br><span class="line">        <span class="string">&#x27;environment&#x27;</span>    = <span class="string">&#x27;Win32_Environment&#x27;</span></span><br><span class="line">        <span class="string">&#x27;startup&#x27;</span>        = <span class="string">&#x27;Win32_StartupCommand&#x27;</span></span><br><span class="line">        <span class="string">&#x27;timezone&#x27;</span>       = <span class="string">&#x27;Win32_TimeZone&#x27;</span></span><br><span class="line">        <span class="string">&#x27;qfe&#x27;</span>            = <span class="string">&#x27;Win32_QuickFixEngineering&#x27;</span></span><br><span class="line">        <span class="string">&#x27;product&#x27;</span>        = <span class="string">&#x27;Win32_Product&#x27;</span></span><br><span class="line">        <span class="string">&#x27;desktop&#x27;</span>        = <span class="string">&#x27;Win32_Desktop&#x27;</span></span><br><span class="line">        <span class="string">&#x27;shadowcopy&#x27;</span>     = <span class="string">&#x27;Win32_ShadowCopy&#x27;</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># ---------- 切出别名 -----------------------------------------</span></span><br><span class="line">    <span class="comment"># 有些调用方会把整条命令（含开头的 wmic / wmic.exe / 完整路径）一起传进来，</span></span><br><span class="line">    <span class="comment"># 这里先把它剥掉，只留真正的子命令。</span></span><br><span class="line">    <span class="variable">$sp</span> = <span class="variable">$raw</span>.IndexOfAny([<span class="built_in">char</span>[]]<span class="selector-tag">@</span>(<span class="string">&#x27; &#x27;</span>, <span class="string">&quot;`t&quot;</span>))</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$sp</span> <span class="operator">-lt</span> <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="comment"># 只有一个词：可能是裸别名（wmic process），也可能是无意义的输入</span></span><br><span class="line">        <span class="variable">$alias</span> = <span class="variable">$raw</span>.Trim().ToLower()</span><br><span class="line">        <span class="variable">$rest</span> = <span class="string">&#x27;&#x27;</span></span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="variable">$alias</span> = <span class="variable">$raw</span>.Substring(<span class="number">0</span>, <span class="variable">$sp</span>).Trim().ToLower()</span><br><span class="line">        <span class="variable">$rest</span> = <span class="variable">$raw</span>.Substring(<span class="variable">$sp</span>).Trim()</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> ([<span class="built_in">string</span>]::IsNullOrEmpty(<span class="variable">$alias</span>)) &#123; <span class="keyword">return</span> &#125;</span><br><span class="line"></span><br><span class="line">    <span class="variable">$dropLead</span> = <span class="variable">$false</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$alias</span> <span class="operator">-eq</span> <span class="string">&#x27;wmic&#x27;</span> <span class="operator">-or</span> <span class="variable">$alias</span> <span class="operator">-eq</span> <span class="string">&#x27;wmic.exe&#x27;</span> <span class="operator">-or</span> <span class="variable">$alias</span> <span class="operator">-eq</span> <span class="string">&#x27;wmic.cmd&#x27;</span>) &#123; <span class="variable">$dropLead</span> = <span class="variable">$true</span> &#125;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$alias</span> <span class="operator">-match</span> <span class="string">&#x27;\\wmic(\.exe|\.cmd)?$&#x27;</span>) &#123; <span class="variable">$dropLead</span> = <span class="variable">$true</span> &#125;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$dropLead</span>) &#123;</span><br><span class="line">        <span class="variable">$sp</span> = <span class="variable">$rest</span>.IndexOfAny([<span class="built_in">char</span>[]]<span class="selector-tag">@</span>(<span class="string">&#x27; &#x27;</span>, <span class="string">&quot;`t&quot;</span>))</span><br><span class="line">        <span class="keyword">if</span> (<span class="variable">$sp</span> <span class="operator">-lt</span> <span class="number">0</span>) &#123; <span class="keyword">return</span> &#125;</span><br><span class="line">        <span class="variable">$alias</span> = <span class="variable">$rest</span>.Substring(<span class="number">0</span>, <span class="variable">$sp</span>).Trim().ToLower()</span><br><span class="line">        <span class="variable">$rest</span> = <span class="variable">$rest</span>.Substring(<span class="variable">$sp</span>).Trim()</span><br><span class="line">        <span class="keyword">if</span> ([<span class="built_in">string</span>]::IsNullOrEmpty(<span class="variable">$alias</span>)) &#123; <span class="keyword">return</span> &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># ---------- 输出格式开关（可以出现在任意位置）-----------------</span></span><br><span class="line">    <span class="variable">$format</span> = <span class="string">&#x27;table&#x27;</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$raw</span> <span class="operator">-match</span> <span class="string">&#x27;(?i)/format\s*:\s*list\b&#x27;</span>) &#123; <span class="variable">$format</span> = <span class="string">&#x27;list&#x27;</span> &#125;</span><br><span class="line">    <span class="keyword">elseif</span> (<span class="variable">$raw</span> <span class="operator">-match</span> <span class="string">&#x27;(?i)/format\s*:\s*csv\b&#x27;</span>) &#123; <span class="variable">$format</span> = <span class="string">&#x27;csv&#x27;</span> &#125;</span><br><span class="line">    <span class="keyword">elseif</span> (<span class="variable">$raw</span> <span class="operator">-match</span> <span class="string">&#x27;(?i)(^|\s)/value(\s|$)&#x27;</span>) &#123; <span class="variable">$format</span> = <span class="string">&#x27;list&#x27;</span> &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># ---------- 切出 get 子句 ------------------------------------</span></span><br><span class="line">    <span class="variable">$propText</span> = <span class="variable">$null</span></span><br><span class="line">    <span class="variable">$iGet</span> = <span class="built_in">Find-WmicKeyword</span> <span class="variable">$rest</span> <span class="string">&#x27;get&#x27;</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$iGet</span> <span class="operator">-ge</span> <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="variable">$propText</span> = <span class="variable">$rest</span>.Substring(<span class="variable">$iGet</span> + <span class="number">3</span>).Trim()</span><br><span class="line">        <span class="variable">$rest</span> = <span class="variable">$rest</span>.Substring(<span class="number">0</span>, <span class="variable">$iGet</span>).Trim()</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># ---------- 切出 where 子句 ----------------------------------</span></span><br><span class="line">    <span class="variable">$whereText</span> = <span class="variable">$null</span></span><br><span class="line">    <span class="variable">$iWhere</span> = <span class="built_in">Find-WmicKeyword</span> <span class="variable">$rest</span> <span class="string">&#x27;where&#x27;</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$iWhere</span> <span class="operator">-ge</span> <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="variable">$whereText</span> = <span class="variable">$rest</span>.Substring(<span class="variable">$iWhere</span> + <span class="number">5</span>).Trim()</span><br><span class="line">        <span class="variable">$rest</span> = <span class="variable">$rest</span>.Substring(<span class="number">0</span>, <span class="variable">$iWhere</span>).Trim()</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># ---------- 清掉开关（可能出现在 get / where 之后）-----------</span></span><br><span class="line">    <span class="comment">#    process get name /format:list</span></span><br><span class="line">    <span class="comment">#    process where name=&#x27;x&#x27; /value</span></span><br><span class="line">    <span class="variable">$rest</span> = (<span class="built_in">Remove-WmicSwitches</span> <span class="variable">$rest</span>).Trim()</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$null</span> <span class="operator">-ne</span> <span class="variable">$propText</span>) &#123; <span class="variable">$propText</span> = (<span class="built_in">Remove-WmicSwitches</span> <span class="variable">$propText</span>).Trim() &#125;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$null</span> <span class="operator">-ne</span> <span class="variable">$whereText</span>) &#123; <span class="variable">$whereText</span> = (<span class="built_in">Remove-WmicSwitches</span> <span class="variable">$whereText</span>).Trim() &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$rest</span>.Length <span class="operator">-gt</span> <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="comment"># 别名后面还有无法识别的成分 → 不猜，直接返回</span></span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># ---------- 解析属性列表 -------------------------------------</span></span><br><span class="line">    <span class="variable">$props</span> = <span class="selector-tag">@</span>()</span><br><span class="line">    <span class="keyword">if</span> (<span class="operator">-not</span> [<span class="built_in">string</span>]::IsNullOrWhiteSpace(<span class="variable">$propText</span>)) &#123;</span><br><span class="line">        <span class="keyword">foreach</span> (<span class="variable">$p</span> <span class="keyword">in</span> (<span class="variable">$propText</span> <span class="operator">-split</span> <span class="string">&#x27;,&#x27;</span>)) &#123;</span><br><span class="line">            <span class="variable">$t</span> = <span class="variable">$p</span>.Trim()</span><br><span class="line">            <span class="keyword">if</span> (<span class="variable">$t</span>.Length <span class="operator">-gt</span> <span class="number">0</span> <span class="operator">-and</span> <span class="variable">$t</span> <span class="operator">-ne</span> <span class="string">&#x27;*&#x27;</span>) &#123; <span class="variable">$props</span> += <span class="variable">$t</span> &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (<span class="variable">$props</span>.Count <span class="operator">-eq</span> <span class="number">0</span>) &#123; <span class="variable">$format</span> = <span class="string">&#x27;list&#x27;</span> &#125;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment"># 没有 get → 输出全部属性，wmic 此时也用 list 格式</span></span><br><span class="line">        <span class="variable">$format</span> = <span class="string">&#x27;list&#x27;</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># ---------- 解析类名 -----------------------------------------</span></span><br><span class="line">    <span class="variable">$className</span> = <span class="variable">$null</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$AliasMap</span>.ContainsKey(<span class="variable">$alias</span>)) &#123;</span><br><span class="line">        <span class="variable">$className</span> = <span class="variable">$AliasMap</span>[<span class="variable">$alias</span>]</span><br><span class="line">    &#125; <span class="keyword">elseif</span> (<span class="variable">$alias</span>.StartsWith(<span class="string">&#x27;win32_&#x27;</span>)) &#123;</span><br><span class="line">        <span class="variable">$className</span> = <span class="variable">$alias</span>.Substring(<span class="number">0</span>, <span class="number">1</span>).ToUpper() + <span class="variable">$alias</span>.Substring(<span class="number">1</span>)</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="variable">$className</span> = <span class="string">&#x27;Win32_&#x27;</span> + <span class="variable">$alias</span>.Substring(<span class="number">0</span>, <span class="number">1</span>).ToUpper() + <span class="variable">$alias</span>.Substring(<span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># ---------- 规范化 where 条件 --------------------------------</span></span><br><span class="line">    <span class="variable">$filter</span> = <span class="variable">$null</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="operator">-not</span> [<span class="built_in">string</span>]::IsNullOrWhiteSpace(<span class="variable">$whereText</span>)) &#123;</span><br><span class="line">        <span class="variable">$filter</span> = <span class="variable">$whereText</span></span><br><span class="line">        <span class="comment"># 整体被引号包起来的情况：where &quot;name=&#x27;x&#x27;&quot;</span></span><br><span class="line">        <span class="keyword">if</span> (<span class="variable">$filter</span>.Length <span class="operator">-ge</span> <span class="number">2</span>) &#123;</span><br><span class="line">            <span class="variable">$f0</span> = <span class="variable">$filter</span>.Substring(<span class="number">0</span>, <span class="number">1</span>)</span><br><span class="line">            <span class="variable">$fN</span> = <span class="variable">$filter</span>.Substring(<span class="variable">$filter</span>.Length - <span class="number">1</span>, <span class="number">1</span>)</span><br><span class="line">            <span class="keyword">if</span> ((<span class="variable">$f0</span> <span class="operator">-eq</span> <span class="string">&#x27;&quot;&#x27;</span> <span class="operator">-and</span> <span class="variable">$fN</span> <span class="operator">-eq</span> <span class="string">&#x27;&quot;&#x27;</span>) <span class="operator">-or</span> (<span class="variable">$f0</span> <span class="operator">-eq</span> <span class="string">&quot;&#x27;&quot;</span> <span class="operator">-and</span> <span class="variable">$fN</span> <span class="operator">-eq</span> <span class="string">&quot;&#x27;&quot;</span>)) &#123;</span><br><span class="line">                <span class="variable">$filter</span> = <span class="variable">$filter</span>.Substring(<span class="number">1</span>, <span class="variable">$filter</span>.Length - <span class="number">2</span>).Trim()</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># ---------- 查询 ---------------------------------------------</span></span><br><span class="line">    <span class="variable">$instances</span> = <span class="selector-tag">@</span>()</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$null</span> <span class="operator">-ne</span> <span class="variable">$filter</span>) &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="variable">$instances</span> = <span class="selector-tag">@</span>(<span class="built_in">Get-CimInstance</span> <span class="literal">-ClassName</span> <span class="variable">$className</span> <span class="literal">-Filter</span> <span class="variable">$filter</span> <span class="literal">-ErrorAction</span> Stop)</span><br><span class="line">        &#125; <span class="keyword">catch</span> &#123;</span><br><span class="line">            <span class="comment"># 首次失败：尝试修正属性名大小写后重试一次</span></span><br><span class="line">            <span class="variable">$fixed</span> = <span class="built_in">Repair-WmicFilter</span> <span class="variable">$className</span> <span class="variable">$filter</span></span><br><span class="line">            <span class="keyword">if</span> (<span class="variable">$fixed</span> <span class="operator">-ne</span> <span class="variable">$filter</span>) &#123;</span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    <span class="variable">$instances</span> = <span class="selector-tag">@</span>(<span class="built_in">Get-CimInstance</span> <span class="literal">-ClassName</span> <span class="variable">$className</span> <span class="literal">-Filter</span> <span class="variable">$fixed</span> <span class="literal">-ErrorAction</span> Stop)</span><br><span class="line">                &#125; <span class="keyword">catch</span> &#123; <span class="variable">$instances</span> = <span class="selector-tag">@</span>() &#125;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="variable">$instances</span> = <span class="selector-tag">@</span>()</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="variable">$instances</span> = <span class="selector-tag">@</span>(<span class="built_in">Get-CimInstance</span> <span class="literal">-ClassName</span> <span class="variable">$className</span> <span class="literal">-ErrorAction</span> Stop)</span><br><span class="line">        &#125; <span class="keyword">catch</span> &#123; <span class="variable">$instances</span> = <span class="selector-tag">@</span>() &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$instances</span>.Count <span class="operator">-eq</span> <span class="number">0</span>) &#123; <span class="keyword">return</span> &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># ---------- 属性名统一成类里的规范大小写 ----------------------</span></span><br><span class="line">    <span class="comment"># wmic 输出的是规范名（ExecutablePath / ProcessId）。调用方若按表头匹配，</span></span><br><span class="line">    <span class="comment"># 大小写必须一致；顺手也把写错大小写的属性名纠正过来。</span></span><br><span class="line">    <span class="variable">$canonical</span> = <span class="selector-tag">@</span>&#123;&#125;</span><br><span class="line">    <span class="keyword">foreach</span> (<span class="variable">$cp</span> <span class="keyword">in</span> <span class="variable">$instances</span>[<span class="number">0</span>].CimInstanceProperties) &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="operator">-not</span> [<span class="built_in">string</span>]::IsNullOrEmpty(<span class="variable">$cp</span>.Name)) &#123; <span class="variable">$canonical</span>[<span class="variable">$cp</span><span class="type">.Name.ToLower</span>()] = <span class="variable">$cp</span>.Name &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># ---------- 没指定属性 → 取类的全部属性 ----------------------</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$props</span>.Count <span class="operator">-eq</span> <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">foreach</span> (<span class="variable">$cp</span> <span class="keyword">in</span> <span class="variable">$instances</span>[<span class="number">0</span>].CimInstanceProperties) &#123; <span class="variable">$props</span> += <span class="variable">$cp</span>.Name &#125;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment"># 只保留类里真实存在的属性：属性名写错时宁可返回空，</span></span><br><span class="line">        <span class="comment"># 也不要吐出一堆空行（真 wmic 会直接报 Invalid property）</span></span><br><span class="line">        <span class="variable">$norm</span> = <span class="selector-tag">@</span>()</span><br><span class="line">        <span class="keyword">foreach</span> (<span class="variable">$p</span> <span class="keyword">in</span> <span class="variable">$props</span>) &#123;</span><br><span class="line">            <span class="variable">$key</span> = <span class="variable">$p</span>.ToLower()</span><br><span class="line">            <span class="keyword">if</span> (<span class="variable">$canonical</span>.ContainsKey(<span class="variable">$key</span>)) &#123; <span class="variable">$norm</span> += <span class="variable">$canonical</span>[<span class="variable">$key</span>] &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="variable">$props</span> = <span class="variable">$norm</span></span><br><span class="line">        <span class="keyword">if</span> (<span class="variable">$props</span>.Count <span class="operator">-eq</span> <span class="number">0</span>) &#123; <span class="keyword">return</span> &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># wmic 默认按属性名字母序排列列，这里保持一致</span></span><br><span class="line">    <span class="variable">$props</span> = <span class="selector-tag">@</span>(<span class="variable">$props</span> | <span class="built_in">Sort-Object</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># ---------- 渲染 ---------------------------------------------</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$format</span> <span class="operator">-eq</span> <span class="string">&#x27;list&#x27;</span>) &#123;</span><br><span class="line">        <span class="variable">$first</span> = <span class="variable">$true</span></span><br><span class="line">        <span class="keyword">foreach</span> (<span class="variable">$inst</span> <span class="keyword">in</span> <span class="variable">$instances</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (<span class="operator">-not</span> <span class="variable">$first</span>) &#123; <span class="built_in">Write-Output</span> <span class="string">&#x27;&#x27;</span> &#125;</span><br><span class="line">            <span class="variable">$first</span> = <span class="variable">$false</span></span><br><span class="line">            <span class="keyword">foreach</span> (<span class="variable">$p</span> <span class="keyword">in</span> <span class="variable">$props</span>) &#123;</span><br><span class="line">                <span class="built_in">Write-Output</span> (<span class="variable">$p</span> + <span class="string">&#x27;=&#x27;</span> + (<span class="built_in">Format-WmicValue</span> <span class="variable">$inst</span>.<span class="variable">$p</span>))</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (<span class="variable">$format</span> <span class="operator">-eq</span> <span class="string">&#x27;csv&#x27;</span>) &#123;</span><br><span class="line">        <span class="variable">$hostName</span> = <span class="variable">$env:COMPUTERNAME</span></span><br><span class="line">        <span class="keyword">if</span> ([<span class="built_in">string</span>]::IsNullOrEmpty(<span class="variable">$hostName</span>)) &#123; <span class="variable">$hostName</span> = [<span class="type">System.Environment</span>]::MachineName &#125;</span><br><span class="line">        <span class="built_in">Write-Output</span> (<span class="string">&#x27;Node,&#x27;</span> + (<span class="variable">$props</span> <span class="operator">-join</span> <span class="string">&#x27;,&#x27;</span>))</span><br><span class="line">        <span class="keyword">foreach</span> (<span class="variable">$inst</span> <span class="keyword">in</span> <span class="variable">$instances</span>) &#123;</span><br><span class="line">            <span class="variable">$cells</span> = <span class="selector-tag">@</span>(<span class="variable">$hostName</span>)</span><br><span class="line">            <span class="keyword">foreach</span> (<span class="variable">$p</span> <span class="keyword">in</span> <span class="variable">$props</span>) &#123; <span class="variable">$cells</span> += (<span class="built_in">Format-CsvCell</span> (<span class="built_in">Format-WmicValue</span> <span class="variable">$inst</span>.<span class="variable">$p</span>)) &#125;</span><br><span class="line">            <span class="built_in">Write-Output</span> (<span class="variable">$cells</span> <span class="operator">-join</span> <span class="string">&#x27;,&#x27;</span>)</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment"># table</span></span><br><span class="line">    <span class="variable">$rows</span> = <span class="selector-tag">@</span>()</span><br><span class="line">    <span class="keyword">foreach</span> (<span class="variable">$inst</span> <span class="keyword">in</span> <span class="variable">$instances</span>) &#123;</span><br><span class="line">        <span class="variable">$cells</span> = <span class="selector-tag">@</span>()</span><br><span class="line">        <span class="keyword">foreach</span> (<span class="variable">$p</span> <span class="keyword">in</span> <span class="variable">$props</span>) &#123; <span class="variable">$cells</span> += (<span class="built_in">Format-WmicValue</span> <span class="variable">$inst</span>.<span class="variable">$p</span>) &#125;</span><br><span class="line">        <span class="variable">$rows</span> += , <span class="variable">$cells</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="variable">$widths</span> = <span class="selector-tag">@</span>()</span><br><span class="line">    <span class="keyword">for</span> (<span class="variable">$i</span> = <span class="number">0</span>; <span class="variable">$i</span> <span class="operator">-lt</span> <span class="variable">$props</span>.Count; <span class="variable">$i</span>++) &#123;</span><br><span class="line">        <span class="variable">$w</span> = ([<span class="built_in">string</span>]<span class="variable">$props</span>[<span class="variable">$i</span>]).Length</span><br><span class="line">        <span class="keyword">foreach</span> (<span class="variable">$r</span> <span class="keyword">in</span> <span class="variable">$rows</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (([<span class="built_in">string</span>]<span class="variable">$r</span>[<span class="variable">$i</span>]).Length <span class="operator">-gt</span> <span class="variable">$w</span>) &#123; <span class="variable">$w</span> = ([<span class="built_in">string</span>]<span class="variable">$r</span>[<span class="variable">$i</span>]).Length &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="variable">$widths</span> += <span class="variable">$w</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">Write-Output</span> (Render<span class="literal">-WmicRow</span> <span class="variable">$props</span> <span class="variable">$widths</span>)</span><br><span class="line">    <span class="keyword">foreach</span> (<span class="variable">$r</span> <span class="keyword">in</span> <span class="variable">$rows</span>) &#123; <span class="built_in">Write-Output</span> (Render<span class="literal">-WmicRow</span> <span class="variable">$r</span> <span class="variable">$widths</span>) &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ==== ENTRY ==== （此标记之后为入口，测试时可只取上方的定义部分）</span></span><br><span class="line"><span class="variable">$rawArgs</span> = (<span class="selector-tag">@</span>(<span class="variable">$args</span>) | <span class="built_in">ForEach-Object</span> &#123; [<span class="built_in">string</span>]<span class="variable">$_</span> &#125;) <span class="operator">-join</span> <span class="string">&#x27; &#x27;</span></span><br><span class="line"><span class="keyword">if</span> ([<span class="built_in">string</span>]::IsNullOrWhiteSpace(<span class="variable">$rawArgs</span>)) &#123; <span class="variable">$rawArgs</span> = <span class="variable">$env:WBD_WMIC_ARGS</span> &#125;</span><br><span class="line"><span class="built_in">Invoke-WmicShim</span> <span class="variable">$rawArgs</span></span><br><span class="line"><span class="keyword">exit</span> <span class="number">0</span></span><br></pre></td></tr></table></figure><h3 id="A-3-其余四个脚本"><a href="#A-3-其余四个脚本" class="headerlink" title="A.3 其余四个脚本"></a>A.3 其余四个脚本</h3><details><summary><b>安装-wmic垫片.cmd</b>（管理员）</summary><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line">@<span class="built_in">echo</span> off</span><br><span class="line"><span class="built_in">chcp</span> <span class="number">65001</span> &gt;<span class="built_in">nul</span></span><br><span class="line"><span class="built_in">title</span> 安装 wmic 兼容垫片</span><br><span class="line"><span class="built_in">setlocal</span> EnableExtensions</span><br><span class="line"></span><br><span class="line"><span class="built_in">net</span> session &gt;<span class="built_in">nul</span> <span class="number">2</span>&gt;&amp;<span class="number">1</span></span><br><span class="line"><span class="keyword">if</span> <span class="keyword">errorlevel</span> <span class="number">1</span> (</span><br><span class="line">  <span class="built_in">echo</span>.</span><br><span class="line">  <span class="built_in">echo</span>   [!] 需要管理员权限。</span><br><span class="line">  <span class="built_in">echo</span>       请右键本文件，选择「以管理员身份运行」。</span><br><span class="line">  <span class="built_in">echo</span>.</span><br><span class="line">  <span class="built_in">pause</span></span><br><span class="line">  <span class="keyword">exit</span> /b <span class="number">1</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="built_in">set</span> &quot;SRC=%~dp0&quot;</span><br><span class="line"><span class="built_in">set</span> &quot;DST=<span class="variable">%SystemRoot%</span>\System32\Wbem&quot;</span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span>   源目录 : <span class="variable">%SRC%</span></span><br><span class="line"><span class="built_in">echo</span>   目标   : <span class="variable">%DST%</span></span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span>   正在复制...</span><br><span class="line"><span class="built_in">copy</span> /y &quot;<span class="variable">%SRC%</span>wmic.<span class="built_in">cmd</span>&quot;      &quot;<span class="variable">%DST%</span>\wmic.<span class="built_in">cmd</span>&quot;       &gt;<span class="built_in">nul</span> || <span class="keyword">goto</span> :fail</span><br><span class="line"><span class="built_in">copy</span> /y &quot;<span class="variable">%SRC%</span>wmic-shim.ps1&quot; &quot;<span class="variable">%DST%</span>\wmic-shim.ps1&quot;  &gt;<span class="built_in">nul</span> || <span class="keyword">goto</span> :fail</span><br><span class="line"><span class="built_in">echo</span>   [OK] 复制完成。</span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span>   ---------- 自检 ----------</span><br><span class="line"><span class="built_in">echo</span>   [<span class="number">1</span>] where wmic</span><br><span class="line">where wmic</span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span>   [<span class="number">2</span>] wmic process where name=&#x27;idea64.exe&#x27; get processid,executablepath</span><br><span class="line">wmic process where name=&#x27;idea64.exe&#x27; get processid,executablepath</span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span>   说明：第 [<span class="number">2</span>] 步应输出 idea64.exe 的完整路径。</span><br><span class="line"><span class="built_in">echo</span>         若为空，请先启动 IDEA 再重试。</span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span>   装好后回到 IDEA，重新打开「代码合并工具」即可。</span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">pause</span></span><br><span class="line"><span class="keyword">exit</span> /b <span class="number">0</span></span><br><span class="line"></span><br><span class="line">:fail</span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span>   [X] 复制失败。请确认已用管理员身份运行。</span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">pause</span></span><br><span class="line"><span class="keyword">exit</span> /b <span class="number">1</span></span><br></pre></td></tr></table></figure></details><details><summary><b>安装-wmic垫片-免管理员.cmd</b></summary><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line">@<span class="built_in">echo</span> off</span><br><span class="line"><span class="built_in">chcp</span> <span class="number">65001</span> &gt;<span class="built_in">nul</span></span><br><span class="line"><span class="built_in">title</span> 安装 wmic 兼容垫片（免管理员 / 用户级 <span class="built_in">PATH</span>）</span><br><span class="line"><span class="built_in">setlocal</span> EnableExtensions</span><br><span class="line"></span><br><span class="line"><span class="built_in">set</span> &quot;SRC=%~dp0&quot;</span><br><span class="line"><span class="built_in">set</span> &quot;DST=<span class="variable">%USERPROFILE%</span>\wmic-shim&quot;</span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span>   源目录 : <span class="variable">%SRC%</span></span><br><span class="line"><span class="built_in">echo</span>   安装到 : <span class="variable">%DST%</span></span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> <span class="keyword">not</span> <span class="keyword">exist</span> &quot;<span class="variable">%DST%</span>&quot; <span class="built_in">mkdir</span> &quot;<span class="variable">%DST%</span>&quot;</span><br><span class="line"><span class="built_in">copy</span> /y &quot;<span class="variable">%SRC%</span>wmic.<span class="built_in">cmd</span>&quot;       &quot;<span class="variable">%DST%</span>\wmic.<span class="built_in">cmd</span>&quot;       &gt;<span class="built_in">nul</span> || <span class="keyword">goto</span> :fail</span><br><span class="line"><span class="built_in">copy</span> /y &quot;<span class="variable">%SRC%</span>wmic-shim.ps1&quot;  &quot;<span class="variable">%DST%</span>\wmic-shim.ps1&quot;  &gt;<span class="built_in">nul</span> || <span class="keyword">goto</span> :fail</span><br><span class="line"><span class="built_in">echo</span>   [OK] 文件已复制</span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">rem ---- 把安装目录追加到「用户级 PATH」（不影响系统 PATH）----</span></span><br><span class="line"><span class="built_in">set</span> &quot;UPATH=&quot;</span><br><span class="line"><span class="keyword">for</span> /f &quot;tokens=<span class="number">2</span>,*&quot; <span class="variable">%%a</span> <span class="keyword">in</span> (&#x27;reg query HKCU\Environment /v <span class="built_in">Path</span> <span class="number">2</span>^&gt;<span class="built_in">nul</span> ^| <span class="built_in">findstr</span> /i &quot;<span class="built_in">Path</span>&quot;&#x27;) <span class="keyword">do</span> <span class="built_in">set</span> &quot;UPATH=<span class="variable">%%b</span>&quot;</span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span> <span class="variable">%UPATH%</span> | <span class="built_in">find</span> /i &quot;<span class="variable">%DST%</span>&quot; &gt;<span class="built_in">nul</span></span><br><span class="line"><span class="keyword">if</span> <span class="keyword">not</span> <span class="keyword">errorlevel</span> <span class="number">1</span> (</span><br><span class="line">  <span class="built_in">echo</span>   [--] 用户 <span class="built_in">PATH</span> 中已存在，跳过</span><br><span class="line">) <span class="keyword">else</span> (</span><br><span class="line">  <span class="keyword">if</span> <span class="keyword">defined</span> UPATH (</span><br><span class="line">    setx <span class="built_in">PATH</span> &quot;<span class="variable">%UPATH%</span>;<span class="variable">%DST%</span>&quot; &gt;<span class="built_in">nul</span></span><br><span class="line">  ) <span class="keyword">else</span> (</span><br><span class="line">    setx <span class="built_in">PATH</span> &quot;<span class="variable">%DST%</span>&quot; &gt;<span class="built_in">nul</span></span><br><span class="line">  )</span><br><span class="line">  <span class="built_in">echo</span>   [OK] 已加入用户 <span class="built_in">PATH</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span>   --- 自检 ---</span><br><span class="line">&quot;<span class="variable">%DST%</span>\wmic.<span class="built_in">cmd</span>&quot; process where name=&#x27;idea64.exe&#x27; get processid,executablepath</span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span>   上面若能看到 idea64.exe 的完整路径即为成功。</span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span>   ! 重要：必须完全退出 IDEA（含 JetBrains Toolbox）再重新启动，</span><br><span class="line"><span class="built_in">echo</span>     新进程才会带上更新后的 <span class="built_in">PATH</span>，插件才能找到 wmic。</span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">pause</span></span><br><span class="line"><span class="keyword">exit</span> /b <span class="number">0</span></span><br><span class="line"></span><br><span class="line">:fail</span><br><span class="line"><span class="built_in">echo</span>   [X] 复制失败，请检查目录权限。</span><br><span class="line"><span class="built_in">pause</span></span><br><span class="line"><span class="keyword">exit</span> /b <span class="number">1</span></span><br></pre></td></tr></table></figure></details><details><summary><b>卸载-wmic垫片.cmd</b></summary><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">@<span class="built_in">echo</span> off</span><br><span class="line"><span class="built_in">chcp</span> <span class="number">65001</span> &gt;<span class="built_in">nul</span></span><br><span class="line"><span class="built_in">title</span> 卸载 wmic 兼容垫片</span><br><span class="line"><span class="built_in">setlocal</span> EnableExtensions</span><br><span class="line"></span><br><span class="line"><span class="built_in">net</span> session &gt;<span class="built_in">nul</span> <span class="number">2</span>&gt;&amp;<span class="number">1</span></span><br><span class="line"><span class="keyword">if</span> <span class="keyword">errorlevel</span> <span class="number">1</span> (</span><br><span class="line">  <span class="built_in">echo</span>.</span><br><span class="line">  <span class="built_in">echo</span>   [!] 需要管理员权限。请右键「以管理员身份运行」。</span><br><span class="line">  <span class="built_in">echo</span>.</span><br><span class="line">  <span class="built_in">pause</span></span><br><span class="line">  <span class="keyword">exit</span> /b <span class="number">1</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="built_in">set</span> &quot;DST=<span class="variable">%SystemRoot%</span>\System32\Wbem&quot;</span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span>   正在删除 <span class="variable">%DST%</span>\wmic.<span class="built_in">cmd</span></span><br><span class="line"><span class="built_in">echo</span>         和 <span class="variable">%DST%</span>\wmic-shim.ps1</span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">del</span> /f /q &quot;<span class="variable">%DST%</span>\wmic.<span class="built_in">cmd</span>&quot;      <span class="number">2</span>&gt;<span class="built_in">nul</span> &amp;&amp; <span class="built_in">echo</span>   [OK] 已删除 wmic.<span class="built_in">cmd</span> || <span class="built_in">echo</span>   [--] wmic.<span class="built_in">cmd</span> 不存在</span><br><span class="line"><span class="built_in">del</span> /f /q &quot;<span class="variable">%DST%</span>\wmic-shim.ps1&quot; <span class="number">2</span>&gt;<span class="built_in">nul</span> &amp;&amp; <span class="built_in">echo</span>   [OK] 已删除 wmic-shim.ps1 || <span class="built_in">echo</span>   [--] wmic-shim.ps1 不存在</span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span>   卸载完成，系统已恢复原状。</span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">pause</span></span><br><span class="line"><span class="keyword">exit</span> /b <span class="number">0</span></span><br></pre></td></tr></table></figure></details><details><summary><b>检查安装状态.cmd</b></summary><figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line">@<span class="built_in">echo</span> off</span><br><span class="line"><span class="built_in">chcp</span> <span class="number">65001</span> &gt;<span class="built_in">nul</span></span><br><span class="line"><span class="built_in">title</span> wmic 垫片 - 安装状态自检</span><br><span class="line"><span class="built_in">setlocal</span> EnableExtensions</span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span> ============================================</span><br><span class="line"><span class="built_in">echo</span>   <span class="number">1</span>. 文件是否到位</span><br><span class="line"><span class="built_in">echo</span> ============================================</span><br><span class="line"><span class="keyword">if</span> <span class="keyword">exist</span> &quot;<span class="variable">%SystemRoot%</span>\System32\Wbem\wmic.<span class="built_in">cmd</span>&quot; (</span><br><span class="line">  <span class="built_in">echo</span>   [OK] <span class="variable">%SystemRoot%</span>\System32\Wbem\wmic.<span class="built_in">cmd</span></span><br><span class="line">) <span class="keyword">else</span> (</span><br><span class="line">  <span class="built_in">echo</span>   [X ] <span class="variable">%SystemRoot%</span>\System32\Wbem\wmic.<span class="built_in">cmd</span>  ^&lt;-- 缺失</span><br><span class="line">)</span><br><span class="line"><span class="keyword">if</span> <span class="keyword">exist</span> &quot;<span class="variable">%SystemRoot%</span>\System32\Wbem\wmic-shim.ps1&quot; (</span><br><span class="line">  <span class="built_in">echo</span>   [OK] <span class="variable">%SystemRoot%</span>\System32\Wbem\wmic-shim.ps1</span><br><span class="line">) <span class="keyword">else</span> (</span><br><span class="line">  <span class="built_in">echo</span>   [X ] <span class="variable">%SystemRoot%</span>\System32\Wbem\wmic-shim.ps1  ^&lt;-- 缺失</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span> ============================================</span><br><span class="line"><span class="built_in">echo</span>   <span class="number">2</span>. <span class="built_in">cmd</span> 能否解析到 wmic</span><br><span class="line"><span class="built_in">echo</span> ============================================</span><br><span class="line">where wmic</span><br><span class="line"><span class="keyword">if</span> <span class="keyword">errorlevel</span> <span class="number">1</span> <span class="built_in">echo</span>   [X ] <span class="built_in">PATH</span> 里找不到 wmic</span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span> ============================================</span><br><span class="line"><span class="built_in">echo</span>   <span class="number">3</span>. 实测：查 explorer.exe（一直在运行，必定有结果）</span><br><span class="line"><span class="built_in">echo</span> ============================================</span><br><span class="line">wmic process where name=&#x27;explorer.exe&#x27; get processid,executablepath</span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span> ============================================</span><br><span class="line"><span class="built_in">echo</span>   <span class="number">4</span>. 实测：查 idea64.exe</span><br><span class="line"><span class="built_in">echo</span> ============================================</span><br><span class="line">wmic process where name=&#x27;idea64.exe&#x27; get processid,executablepath</span><br><span class="line"><span class="built_in">echo</span>   ^(IDEA 没打开时，这里为空是正常的^)</span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">echo</span>   判定标准：</span><br><span class="line"><span class="built_in">echo</span>     第 <span class="number">3</span> 步有路径  = 垫片工作正常</span><br><span class="line"><span class="built_in">echo</span>     第 <span class="number">4</span> 步有路径  = IDEA 正在运行，插件也能检测到</span><br><span class="line"><span class="built_in">echo</span>.</span><br><span class="line"><span class="built_in">pause</span></span><br><span class="line"><span class="keyword">exit</span> /b <span class="number">0</span></span><br></pre></td></tr></table></figure></details><hr><h2 id="附录-B：排查命令速查"><a href="#附录-B：排查命令速查" class="headerlink" title="附录 B：排查命令速查"></a>附录 B：排查命令速查</h2><h3 id="B-1-确认-WMIC-状态"><a href="#B-1-确认-WMIC-状态" class="headerlink" title="B.1 确认 WMIC 状态"></a>B.1 确认 WMIC 状态</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 系统版本</span></span><br><span class="line">(<span class="built_in">Get-CimInstance</span> Win32_OperatingSystem).Caption</span><br><span class="line">(<span class="built_in">Get-ItemProperty</span> <span class="string">&#x27;HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion&#x27;</span>).DisplayVersion</span><br><span class="line">(<span class="built_in">Get-ItemProperty</span> <span class="string">&#x27;HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion&#x27;</span>).UBR</span><br><span class="line"></span><br><span class="line"><span class="comment"># wmic 是否还在</span></span><br><span class="line"><span class="built_in">Test-Path</span> <span class="string">&quot;<span class="variable">$env:SystemRoot</span>\System32\wmic.exe&quot;</span></span><br><span class="line"><span class="built_in">Test-Path</span> <span class="string">&quot;<span class="variable">$env:SystemRoot</span>\System32\wbem\wmic.exe&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># WMI 服务本身是否正常（正常 ≠ wmic 还在）</span></span><br><span class="line"><span class="built_in">Get-Service</span> Winmgmt | <span class="built_in">Format-List</span> Name, Status, StartType</span><br><span class="line"></span><br><span class="line"><span class="comment"># 组件存储里是否还有 wmic.exe 的载荷</span></span><br><span class="line"><span class="built_in">Get-ChildItem</span> <span class="string">&quot;<span class="variable">$env:SystemRoot</span>\WinSxS&quot;</span> <span class="literal">-Directory</span> <span class="literal">-Filter</span> <span class="string">&quot;*wmic*&quot;</span> |</span><br><span class="line">  <span class="built_in">Select-Object</span> <span class="literal">-ExpandProperty</span> Name</span><br><span class="line"><span class="comment"># 只剩 wmi-wmiclnt 就说明载荷已被彻底删除</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 是否有待重启</span></span><br><span class="line"><span class="built_in">Test-Path</span> <span class="string">&quot;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending&quot;</span></span><br></pre></td></tr></table></figure><h3 id="B-2-用-CIM-代替-wmic-查询"><a href="#B-2-用-CIM-代替-wmic-查询" class="headerlink" title="B.2 用 CIM 代替 wmic 查询"></a>B.2 用 CIM 代替 wmic 查询</h3><table><thead><tr><th>原来（wmic）</th><th>现在（PowerShell）</th></tr></thead><tbody><tr><td><code>wmic process where name=&#39;idea64.exe&#39; get processid,executablepath</code></td><td><code>Get-CimInstance Win32_Process -Filter &quot;Name=&#39;idea64.exe&#39;&quot; | Select ProcessId,ExecutablePath</code></td></tr><tr><td><code>wmic process get name</code></td><td><code>Get-CimInstance Win32_Process | Select-Object Name</code></td></tr><tr><td><code>wmic process where processid=1234 get executablepath</code></td><td><code>(Get-CimInstance Win32_Process -Filter &quot;ProcessId=1234&quot;).ExecutablePath</code></td></tr><tr><td><code>wmic os get caption</code></td><td><code>(Get-CimInstance Win32_OperatingSystem).Caption</code></td></tr><tr><td><code>wmic logicaldisk get name,size</code></td><td><code>Get-CimInstance Win32_LogicalDisk | Select DeviceID,Size</code></td></tr><tr><td><code>wmic service where state=&#39;Running&#39; get name</code></td><td><code>Get-CimInstance Win32_Service -Filter &quot;State=&#39;Running&#39;&quot; | Select Name</code></td></tr><tr><td><code>wmic qfe get hotfixid</code></td><td><code>Get-CimInstance Win32_QuickFixEngineering | Select HotFixID</code></td></tr></tbody></table><blockquote><p><code>Get-WmiObject</code> 是老的 PowerShell 5.1 写法，PowerShell 7 里已被移除，<br>新脚本统一用 <strong><code>Get-CimInstance</code></strong>。</p></blockquote><h3 id="B-3-排查某个程序是否在用-wmic"><a href="#B-3-排查某个程序是否在用-wmic" class="headerlink" title="B.3 排查某个程序是否在用 wmic"></a>B.3 排查某个程序是否在用 wmic</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. 搜脚本仓库（Git Bash / bash）</span></span><br><span class="line"><span class="comment">#    grep -ri wmic .</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 看程序日志</span></span><br><span class="line"><span class="built_in">Select-String</span> <span class="literal">-Path</span> <span class="string">&quot;<span class="variable">$env:LOCALAPPDATA</span>\&lt;程序&gt;\log\*.log&quot;</span> <span class="literal">-Pattern</span> <span class="string">&quot;wmic&quot;</span> |</span><br><span class="line">  <span class="built_in">Select-Object</span> <span class="literal">-Last</span> <span class="number">40</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 反编译 Java 程序（JDK 自带 javap）</span></span><br><span class="line"><span class="comment">#    unzip -l app.jar | grep &#x27;\.class&#x27;</span></span><br><span class="line"><span class="comment">#    javap -c -p -constants com/example/util/e.class</span></span><br></pre></td></tr></table></figure><blockquote><p>⚠️ Java 字节码里<strong>类名和方法名在常量池中是分开存储的</strong>，<br>所以想找「谁调用了 <code>util.e.a()</code>」不能直接搜 <code>util.e.a:</code> 这种拼接串，<br>要分别匹配类名和方法名 + 描述符。更稳的办法是 <code>javap</code> 输出后按行 grep。</p></blockquote><h3 id="B-4-查看进程创建记录（谁在调-wmic）"><a href="#B-4-查看进程创建记录（谁在调-wmic）" class="headerlink" title="B.4 查看进程创建记录（谁在调 wmic）"></a>B.4 查看进程创建记录（谁在调 wmic）</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 装了 Sysmon 的话</span></span><br><span class="line"><span class="built_in">Get-WinEvent</span> <span class="literal">-LogName</span> <span class="string">&quot;Microsoft-Windows-Sysmon/Operational&quot;</span> <span class="literal">-MaxEvents</span> <span class="number">500</span> |</span><br><span class="line">  <span class="built_in">Where-Object</span> &#123; <span class="variable">$_</span>.Id <span class="operator">-eq</span> <span class="number">1</span> <span class="operator">-and</span> <span class="variable">$_</span>.Message <span class="operator">-match</span> <span class="string">&#x27;wmic&#x27;</span> &#125; |</span><br><span class="line">  <span class="built_in">Select-Object</span> TimeCreated, Message</span><br></pre></td></tr></table></figure><p>没有 Sysmon 就用 Process Monitor：过滤 <code>Operation = Process Start</code>，<br>在 Command Line 列里搜 <code>wmic</code>。</p><hr><h2 id="附录-C：案例复盘-——-蓝凌-KMSS-IDEA-插件"><a href="#附录-C：案例复盘-——-蓝凌-KMSS-IDEA-插件" class="headerlink" title="附录 C：案例复盘 —— 蓝凌 KMSS IDEA 插件"></a>附录 C：案例复盘 —— 蓝凌 KMSS IDEA 插件</h2><blockquote><p>这一节是具体案例，正文的通用方法在这里落地。<strong>只想用垫片的话可以跳过。</strong></p></blockquote><p><strong>环境</strong></p><table><thead><tr><th>项</th><th>值</th></tr></thead><tbody><tr><td>系统</td><td>Windows 11 家庭版 25H2，Build 26200.9457</td></tr><tr><td>IDE</td><td>IntelliJ IDEA Ultimate 2026.1 &#x2F; 2026.2（JetBrains Toolbox 安装）</td></tr><tr><td>IDE 路径</td><td><code>D:\SoftWare\JetBrains\Apps\IntelliJ IDEA Ultimate\bin\idea64.exe</code></td></tr><tr><td>插件</td><td><code>kmssDevPluginIdea-1.0.16.v20251020.jar</code></td></tr><tr><td>插件位置</td><td><code>%APPDATA%\JetBrains\IntelliJIdea2026.2\plugins\kmssDevPluginIdea\lib\</code></td></tr></tbody></table><p><strong>现象</strong>：用「代码合并工具」合并代码时报<br>「调用idea程序出错，无法弹出比对代码窗口，详情请检查日志」，<br>插件窗口里「idea程序位置」始终为空。</p><h3 id="C-1-第-1-步：它到底在调什么"><a href="#C-1-第-1-步：它到底在调什么" class="headerlink" title="C.1 第 1 步：它到底在调什么"></a>C.1 第 1 步：它到底在调什么</h3><p>日志路径：<code>%LOCALAPPDATA%\JetBrains\&lt;IDE 版本&gt;\log\idea.log</code></p><p>搜 <code>landray</code> 关键字，拿到确凿证据：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">com.landray.kmss.plugin.util.RunExecUtil - bat执行出错，worker.exit=1，</span><br><span class="line">  bat=cmd.exe /c wmic process where name=&#x27;idea64.exe&#x27; get processid,executablepath</span><br><span class="line">Error:&#x27;wmic&#x27; 不是内部或外部命令，也不是可运行的程序</span><br><span class="line">com.landray.kmss.plugin.util.e - ideaPath64 为空，bat=wmic process where name=&#x27;idea64.exe&#x27; ...</span><br></pre></td></tr></table></figure><p>结论很直接：<strong>插件靠 <code>wmic</code> 找 IDEA 的安装路径，wmic 没了 → 路径为空 → 弹框。</strong></p><h3 id="C-2-第-2-步：wmic-确实没了"><a href="#C-2-第-2-步：wmic-确实没了" class="headerlink" title="C.2 第 2 步：wmic 确实没了"></a>C.2 第 2 步：wmic 确实没了</h3><p><code>Test-Path</code> 两个位置都是 <code>False</code>，<code>where wmic</code> 找不到，<br>但 <code>Winmgmt</code> 服务是 <code>Running / Automatic</code> —— 典型的「外壳没了、能力还在」。</p><h3 id="C-3-第-3-步：有没有绕过的口子（反编译确认）"><a href="#C-3-第-3-步：有没有绕过的口子（反编译确认）" class="headerlink" title="C.3 第 3 步：有没有绕过的口子（反编译确认）"></a>C.3 第 3 步：有没有绕过的口子（反编译确认）</h3><p>不看代码就只能瞎猜，所以直接把 jar 拆开：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">ls</span> <span class="string">&quot;%APPDATA%\JetBrains\IntelliJIdea2026.2\plugins\kmssDevPluginIdea\lib\&quot;</span></span><br><span class="line"><span class="string">javap -c -p -constants com/landray/kmss/plugin/util/e.class</span></span><br></pre></td></tr></table></figure><p>几个关键类：</p><table><thead><tr><th>类</th><th>职责</th></tr></thead><tbody><tr><td><code>util.RunExecUtil</code></td><td>执行外部命令，<strong>超时 2000ms 后强杀进程</strong></td></tr><tr><td><code>util.e</code></td><td><code>a()</code> 方法做 IDEA 路径<strong>自动检测</strong>（Windows 走 wmic，macOS 走 <code>ps -ef|grep MacOS/idea</code>）</td></tr><tr><td><code>dialog.a</code></td><td>「代码合并工具」对话框</td></tr><tr><td><code>view.c</code></td><td>对话框里的一行「标签 + 控件」</td></tr><tr><td><code>view.a</code></td><td>真正拼 diff 命令、启动 IDEA 对比窗口的地方</td></tr><tr><td><code>service.ComparatorService</code></td><td>持久化组件，存到项目 <code>.idea/kmss_dev_config.xml</code></td></tr></tbody></table><p><strong>三个重要发现：</strong></p><p><strong>① 「idea程序位置」是只读的，填不了</strong></p><table><thead><tr><th>界面元素</th><th>实际类型</th><th>能否输入</th></tr></thead><tbody><tr><td>开发包位置</td><td><code>TextFieldWithBrowseButton</code></td><td>✅ 可输入（存为 <code>idPath</code>）</td></tr><tr><td>idea程序位置</td><td><strong><code>JLabel</code></strong></td><td>❌ <strong>只读</strong></td></tr></tbody></table><p>界面上也能佐证：开发包位置右边有「…」浏览按钮，idea程序位置没有 ——<br><code>TextFieldWithBrowseButton</code> 一定带浏览按钮，没有就说明它不是输入框。</p><p><strong>② 改 <code>.idea/kmss_dev_config.xml</code> 也没用</strong></p><p>调用链是单向的：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">util.e.a() 自动检测  ──►  dialog.a 显示在 JLabel 上</span><br><span class="line">                              │</span><br><span class="line">                              └─ 点「下一步」时才 setIdeaPath() 写进</span><br><span class="line">                                 ComparatorService ──► kmss_dev_config.xml</span><br></pre></td></tr></table></figure><p>全 jar 扫下来，<strong>没有任何代码读回 <code>ideaPath</code></strong>（没有 <code>getIdeaPath</code> 调用，也没有字段读取）。<br>它是个只写不读的缓存，改了不生效，而且 IDEA 退出时还会用内存里的空值覆盖掉你的修改。</p><p><strong>③ 真正要用路径的是 <code>view.a</code>，而且它会现场再检测一次</strong></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">String</span> <span class="variable">ideaPath</span> <span class="operator">=</span> <span class="built_in">this</span>.l;                       <span class="comment">// 对话框传进来的</span></span><br><span class="line"><span class="keyword">if</span> (util.o.a(ideaPath) || !<span class="keyword">new</span> <span class="title class_">File</span>(ideaPath).exists()) &#123;</span><br><span class="line">    ideaPath = util.e.a();                      <span class="comment">// ← 再调一次 wmic 检测</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">if</span> (util.o.a(ideaPath) || !<span class="keyword">new</span> <span class="title class_">File</span>(ideaPath).exists()) &#123;</span><br><span class="line">    <span class="comment">// 就是用户看到的那个报错</span></span><br><span class="line">    <span class="keyword">return</span> <span class="string">&quot;调用idea程序出错，无法弹出比对代码窗口，详情请检查日志&quot;</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 拼命令：D: &amp;&amp; cd &quot;&lt;IDEA目录&gt;&quot; &amp;&amp; idea64.exe diff &quot;文件1&quot; &quot;文件2&quot;</span></span><br></pre></td></tr></table></figure><p><strong>结论：IDEA 路径只能靠自动检测拿到，wmic 不通就一定失败，没有任何手工绕过的口子。</strong><br>→ 只能走第四章的垫片方案。</p><h3 id="C-4-结果"><a href="#C-4-结果" class="headerlink" title="C.4 结果"></a>C.4 结果</h3><p>垫片装好后：</p><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">wmic process where name=&#x27;idea64.exe&#x27; get processid,executablepath</span><br><span class="line">:: ExecutablePath                                                     ProcessId</span><br><span class="line">:: D:\SoftWare\JetBrains\Apps\IntelliJ IDEA Ultimate\bin\idea64.exe  <span class="number">26660</span></span><br></pre></td></tr></table></figure><p>插件在 <code>RunExecUtil</code> 的 2000 ms 超时内拿到路径，比对窗口正常弹出。<br>插件本身<strong>一行都没改</strong>。</p><hr><h2 id="附：一页速查"><a href="#附：一页速查" class="headerlink" title="附：一页速查"></a>附：一页速查</h2><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">问题：Win11 24H2+ 移除了 wmic，依赖它的老程序报错或静默失效</span><br><span class="line"></span><br><span class="line">诊断三步：</span><br><span class="line">  1. 找出程序执行的命令    → 程序日志 / Process Monitor / 字符串搜索 / 反编译</span><br><span class="line">  2. 确认 wmic 真没了      → Test-Path System32\wbem\wmic.exe</span><br><span class="line">  3. 有没有绕过的口子      → 看代码！「有配置字段」≠「改了有用」</span><br><span class="line"></span><br><span class="line">解决：把 wmic.cmd + wmic-shim.ps1 放进 C:\Windows\System32\Wbem\</span><br><span class="line">      （该目录本就在 PATH 上，wmic.exe 已不存在 → cmd 会继续往后找到 .cmd）</span><br><span class="line"></span><br><span class="line">验证：cmd /c &quot;wmic process where name=&#x27;explorer.exe&#x27; get processid,executablepath&quot;</span><br><span class="line">      有路径 = 垫片正常</span><br><span class="line"></span><br><span class="line">别踩：DISM /Add-Capability WMIC 会显示「成功」但什么都没装</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Windows-11-移除-WMIC-后，如何让依赖-wmic-的老程序继续工作&quot;&gt;&lt;a href=&quot;#Windows-11-移除-WMIC-后，如何让依赖-wmic-的老程序继续工作&quot; class=&quot;headerlink&quot; title=&quot;Windows 11 移</summary>
      
    
    
    
    <category term="🍭小敏の半糖" scheme="https://xmblog.chrislin.eu.org/categories/%F0%9F%8D%AD%E5%B0%8F%E6%95%8F%E3%81%AE%E5%8D%8A%E7%B3%96/"/>
    
    
    <category term="🅔晚风のEKP" scheme="https://xmblog.chrislin.eu.org/tags/%F0%9F%85%94%E6%99%9A%E9%A3%8E%E3%81%AEEKP/"/>
    
    <category term="🖥️晚风のWin" scheme="https://xmblog.chrislin.eu.org/tags/%F0%9F%96%A5%EF%B8%8F%E6%99%9A%E9%A3%8E%E3%81%AEWin/"/>
    
  </entry>
  
  <entry>
    <title>使用域名+Cloudflare搭建自己的Docker镜像代理</title>
    <link href="https://xmblog.chrislin.eu.org/posts/20260617160000.html"/>
    <id>https://xmblog.chrislin.eu.org/posts/20260617160000.html</id>
    <published>2026-06-17T16:00:00.000Z</published>
    <updated>2026-11-10T13:02:16.260Z</updated>
    
    <content type="html"><![CDATA[<p>用<code>docker</code>的应该都知道 <code>dockerhub</code> 现在在国内无法直接访问，在用<code>docker</code>取拉取镜像的时候会失败连接超时，我们要么取网上找各种第三方镜像加速器，但会出现一个问题，不稳定，也不是最新版本。如下图，连接超时。</p><p><img src="https://img.chrislin.eu.org/2026/06/d05290fde47a698308b019fc37dc96f5.webp" alt="image-20260618085841588"></p><h1 id="域名"><a href="#域名" class="headerlink" title="域名"></a>域名</h1><p>本文标题说了是域名+<code>cloudflare</code>所以我们的有一个域名</p><p>域名获取方法就不在这里多说了，要么去买要么取获取免费的二级子域名（例如我在用的：<code>eu.org</code> <code>eu.cc</code> <code>cc.cd</code>）</p><h2 id="简单说下（eu-cc-cc-cd）域名（需要实名认证）获取："><a href="#简单说下（eu-cc-cc-cd）域名（需要实名认证）获取：" class="headerlink" title="简单说下（eu.cc cc.cd）域名（需要实名认证）获取："></a>简单说下（<code>eu.cc</code> <code>cc.cd</code>）域名（需要实名认证）获取：</h2><h3 id="获取免费额度"><a href="#获取免费额度" class="headerlink" title="获取免费额度"></a>获取免费额度</h3><ul><li>链接：<a href="https://www.juyu.com/ymzc_dfs.htm">免费注册 .eu.cc后缀-聚域网</a></li><li><img src="https://img.chrislin.eu.org/2026/06/002f098af3ddeae24e54409e9692f634.webp" alt="image-20260618093029540"></li><li>剩下的教程，网上大概都搜得到，就不多说了</li></ul><h3 id="将获取到的域名托管到cloudflare"><a href="#将获取到的域名托管到cloudflare" class="headerlink" title="将获取到的域名托管到cloudflare"></a>将获取到的域名托管到<code>cloudflare</code></h3><ul><li><p>没有账号可以去注册一个</p></li><li><p>记得修改<code>DNS</code>到<code>cloudflare</code>就行（需要实名制）</p></li></ul><h1 id="在cloudflare搭建Worker"><a href="#在cloudflare搭建Worker" class="headerlink" title="在cloudflare搭建Worker"></a>在<code>cloudflare</code>搭建<code>Worker</code></h1><h2 id="创建子域名"><a href="#创建子域名" class="headerlink" title="创建子域名"></a>创建子域名</h2><p>进入<code>cloudflare</code>控制台，选择已经配置好的域名，然后进入记录添加一条A记录，子域名自己命名就行，<code>IPv4</code>要么填公网也可以填写<code>114.114.114.114</code></p><p>注意：小黄云一定要打开哦！（代理状态：已代理）</p><p><img src="https://img.chrislin.eu.org/2026/06/295fec57c5069a43adb6841256900954.webp" alt="image-20260618093811502"></p><p>为了方便演示我加了一个<code>docker-image2</code></p><p><img src="https://img.chrislin.eu.org/2026/06/91f30bd5dee5c919ebe8e8975c02c9c1.webp" alt="image-20260618100650960"></p><h2 id="创建Worker"><a href="#创建Worker" class="headerlink" title="创建Worker"></a>创建<code>Worker</code></h2><ul><li>进入控制台</li><li>找到计算下面的<code>Workers 和 Pages</code></li><li>创建应用</li></ul><p><img src="https://img.chrislin.eu.org/2026/06/01e45026109369cd020c7dd069905130.webp" alt="image-20260618094432470"></p><ul><li>我们创建一个 <code>worker</code> 选择 <code>hello world</code>模板就行</li></ul><p><img src="https://img.chrislin.eu.org/2026/06/c14149baa966004f6a562db15014265d.webp" alt="image-20260618094715422"></p><ul><li>名称我们可以根据自己的需求来填写就行</li><li>代码内容暂时默认就行</li><li>我这个是因为已经创建了，所以名称后面显示 <code>×</code></li></ul><p><img src="https://img.chrislin.eu.org/2026/06/a23384fe784cbc09679750261d5efd3f.webp" alt="image-20260618094908948"></p><ul><li><p>为了方便演示，我创建了一个名称为<code>docker-image2</code>的<code>worker</code></p></li><li><p>点击编辑代码将图片下方提供的代码粘贴进去</p></li><li><p>编写好后点击部署</p><p><img src="https://img.chrislin.eu.org/2026/06/abf64fb22d4d8376030e4b5b16014264.webp" alt="image-20260618095145797"></p><p><img src="https://img.chrislin.eu.org/2026/06/0a2c85db9ec087150d210adc0c45043c.webp" alt="image-20260618095510337"></p></li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// _worker.js</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Docker镜像仓库主机地址</span></span><br><span class="line"><span class="keyword">let</span> hub_host = <span class="string">&#x27;registry-1.docker.io&#x27;</span>;</span><br><span class="line"><span class="comment">// Docker认证服务器地址</span></span><br><span class="line"><span class="keyword">const</span> auth_url = <span class="string">&#x27;https://auth.docker.io&#x27;</span>;</span><br><span class="line"><span class="comment">// 自定义的工作服务器地址</span></span><br><span class="line"><span class="keyword">let</span> workers_url = <span class="string">&#x27;https://xxx/&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> 屏蔽爬虫<span class="variable constant_">UA</span> = [<span class="string">&#x27;netcraft&#x27;</span>];</span><br><span class="line"></span><br><span class="line"><span class="comment">// 根据主机名选择对应的上游地址</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">routeByHosts</span>(<span class="params">host</span>) &#123;</span><br><span class="line"><span class="comment">// 定义路由表</span></span><br><span class="line"><span class="keyword">const</span> routes = &#123;</span><br><span class="line"><span class="comment">// 生产环境</span></span><br><span class="line"><span class="string">&quot;quay&quot;</span>: <span class="string">&quot;quay.io&quot;</span>,</span><br><span class="line"><span class="string">&quot;gcr&quot;</span>: <span class="string">&quot;gcr.io&quot;</span>,</span><br><span class="line"><span class="string">&quot;k8s-gcr&quot;</span>: <span class="string">&quot;k8s.gcr.io&quot;</span>,</span><br><span class="line"><span class="string">&quot;k8s&quot;</span>: <span class="string">&quot;registry.k8s.io&quot;</span>,</span><br><span class="line"><span class="string">&quot;ghcr&quot;</span>: <span class="string">&quot;ghcr.io&quot;</span>,</span><br><span class="line"><span class="string">&quot;cloudsmith&quot;</span>: <span class="string">&quot;docker.cloudsmith.io&quot;</span>,</span><br><span class="line"><span class="string">&quot;nvcr&quot;</span>: <span class="string">&quot;nvcr.io&quot;</span>,</span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试环境</span></span><br><span class="line"><span class="string">&quot;test&quot;</span>: <span class="string">&quot;registry-1.docker.io&quot;</span>,</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (host <span class="keyword">in</span> routes) <span class="keyword">return</span> [ routes[host], <span class="literal">false</span> ];</span><br><span class="line"><span class="keyword">else</span> <span class="keyword">return</span> [ hub_host, <span class="literal">true</span> ];</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** <span class="doctag">@type</span> &#123;<span class="type">RequestInit</span>&#125; */</span></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">PREFLIGHT_INIT</span> = &#123;</span><br><span class="line"><span class="comment">// 预检请求配置</span></span><br><span class="line"><span class="attr">headers</span>: <span class="keyword">new</span> <span class="title class_">Headers</span>(&#123;</span><br><span class="line"><span class="string">&#x27;access-control-allow-origin&#x27;</span>: <span class="string">&#x27;*&#x27;</span>, <span class="comment">// 允许所有来源</span></span><br><span class="line"><span class="string">&#x27;access-control-allow-methods&#x27;</span>: <span class="string">&#x27;GET,POST,PUT,PATCH,TRACE,DELETE,HEAD,OPTIONS&#x27;</span>, <span class="comment">// 允许的HTTP方法</span></span><br><span class="line"><span class="string">&#x27;access-control-max-age&#x27;</span>: <span class="string">&#x27;1728000&#x27;</span>, <span class="comment">// 预检请求的缓存时间</span></span><br><span class="line">&#125;),</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 构造响应</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">any</span>&#125; body 响应体</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">number</span>&#125; status 响应状态码</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">Object&lt;string, string&gt;</span>&#125; headers 响应头</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">makeRes</span>(<span class="params">body, status = <span class="number">200</span>, headers = &#123;&#125;</span>) &#123;</span><br><span class="line">headers[<span class="string">&#x27;access-control-allow-origin&#x27;</span>] = <span class="string">&#x27;*&#x27;</span> <span class="comment">// 允许所有来源</span></span><br><span class="line"><span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Response</span>(body, &#123; status, headers &#125;) <span class="comment">// 返回新构造的响应</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 构造新的URL对象</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">string</span>&#125; urlStr URL字符串</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">newUrl</span>(<span class="params">urlStr</span>) &#123;</span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">new</span> <span class="title function_">URL</span>(urlStr) <span class="comment">// 尝试构造新的URL对象</span></span><br><span class="line">&#125; <span class="keyword">catch</span> (err) &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="literal">null</span> <span class="comment">// 构造失败返回null</span></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">isUUID</span>(<span class="params">uuid</span>) &#123;</span><br><span class="line"><span class="comment">// 定义一个正则表达式来匹配 UUID 格式</span></span><br><span class="line"><span class="keyword">const</span> uuidRegex = <span class="regexp">/^[0-9a-f]&#123;8&#125;-[0-9a-f]&#123;4&#125;-[4][0-9a-f]&#123;3&#125;-[89ab][0-9a-f]&#123;3&#125;-[0-9a-f]&#123;12&#125;$/i</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用正则表达式测试 UUID 字符串</span></span><br><span class="line"><span class="keyword">return</span> uuidRegex.<span class="title function_">test</span>(uuid);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">nginx</span>(<span class="params"></span>) &#123;</span><br><span class="line"><span class="keyword">const</span> text = <span class="string">`</span></span><br><span class="line"><span class="string">&lt;!DOCTYPE html&gt;</span></span><br><span class="line"><span class="string">&lt;html&gt;</span></span><br><span class="line"><span class="string">&lt;head&gt;</span></span><br><span class="line"><span class="string">&lt;title&gt;Welcome to nginx!&lt;/title&gt;</span></span><br><span class="line"><span class="string">&lt;style&gt;</span></span><br><span class="line"><span class="string">body &#123;</span></span><br><span class="line"><span class="string">width: 35em;</span></span><br><span class="line"><span class="string">margin: 0 auto;</span></span><br><span class="line"><span class="string">font-family: Tahoma, Verdana, Arial, sans-serif;</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">&lt;/style&gt;</span></span><br><span class="line"><span class="string">&lt;/head&gt;</span></span><br><span class="line"><span class="string">&lt;body&gt;</span></span><br><span class="line"><span class="string">&lt;h1&gt;Welcome to nginx!&lt;/h1&gt;</span></span><br><span class="line"><span class="string">&lt;p&gt;If you see this page, the nginx web server is successfully installed and</span></span><br><span class="line"><span class="string">working. Further configuration is required.&lt;/p&gt;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">&lt;p&gt;For online documentation and support please refer to</span></span><br><span class="line"><span class="string">&lt;a href=&quot;http://nginx.org/&quot;&gt;nginx.org&lt;/a&gt;.&lt;br/&gt;</span></span><br><span class="line"><span class="string">Commercial support is available at</span></span><br><span class="line"><span class="string">&lt;a href=&quot;http://nginx.com/&quot;&gt;nginx.com&lt;/a&gt;.&lt;/p&gt;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">&lt;p&gt;&lt;em&gt;Thank you for using nginx.&lt;/em&gt;&lt;/p&gt;</span></span><br><span class="line"><span class="string">&lt;/body&gt;</span></span><br><span class="line"><span class="string">&lt;/html&gt;</span></span><br><span class="line"><span class="string">`</span></span><br><span class="line"><span class="keyword">return</span> text;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">searchInterface</span>(<span class="params"></span>) &#123;</span><br><span class="line"><span class="keyword">const</span> text = <span class="string">`</span></span><br><span class="line"><span class="string">&lt;!DOCTYPE html&gt;</span></span><br><span class="line"><span class="string">&lt;html&gt;</span></span><br><span class="line"><span class="string">&lt;head&gt;</span></span><br><span class="line"><span class="string">&lt;title&gt;Docker Hub Search&lt;/title&gt;</span></span><br><span class="line"><span class="string">&lt;style&gt;</span></span><br><span class="line"><span class="string">body &#123;</span></span><br><span class="line"><span class="string">font-family: Arial, sans-serif;</span></span><br><span class="line"><span class="string">display: flex;</span></span><br><span class="line"><span class="string">flex-direction: column;</span></span><br><span class="line"><span class="string">align-items: center;</span></span><br><span class="line"><span class="string">justify-content: center;</span></span><br><span class="line"><span class="string">height: 100vh;</span></span><br><span class="line"><span class="string">margin: 0;</span></span><br><span class="line"><span class="string">background: linear-gradient(to right, rgb(28, 143, 237), rgb(29, 99, 237));</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">.logo &#123;</span></span><br><span class="line"><span class="string">margin-bottom: 20px;</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">.search-container &#123;</span></span><br><span class="line"><span class="string">display: flex;</span></span><br><span class="line"><span class="string">align-items: center;</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">#search-input &#123;</span></span><br><span class="line"><span class="string">padding: 10px;</span></span><br><span class="line"><span class="string">font-size: 16px;</span></span><br><span class="line"><span class="string">border: 1px solid #ddd;</span></span><br><span class="line"><span class="string">border-radius: 4px;</span></span><br><span class="line"><span class="string">width: 300px;</span></span><br><span class="line"><span class="string">margin-right: 10px;</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">#search-button &#123;</span></span><br><span class="line"><span class="string">padding: 10px;</span></span><br><span class="line"><span class="string">background-color: rgba(255, 255, 255, 0.2); /* 设置白色，透明度为10% */</span></span><br><span class="line"><span class="string">border: none;</span></span><br><span class="line"><span class="string">border-radius: 4px;</span></span><br><span class="line"><span class="string">cursor: pointer;</span></span><br><span class="line"><span class="string">width: 44px;</span></span><br><span class="line"><span class="string">height: 44px;</span></span><br><span class="line"><span class="string">display: flex;</span></span><br><span class="line"><span class="string">align-items: center;</span></span><br><span class="line"><span class="string">justify-content: center;</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">#search-button svg &#123;</span></span><br><span class="line"><span class="string">width: 24px;</span></span><br><span class="line"><span class="string">height: 24px;</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">&lt;/style&gt;</span></span><br><span class="line"><span class="string">&lt;/head&gt;</span></span><br><span class="line"><span class="string">&lt;body&gt;</span></span><br><span class="line"><span class="string">&lt;div class=&quot;logo&quot;&gt;</span></span><br><span class="line"><span class="string">&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 24 18&quot; fill=&quot;#ffffff&quot; width=&quot;100&quot; height=&quot;75&quot;&gt;</span></span><br><span class="line"><span class="string">&lt;path d=&quot;M23.763 6.886c-.065-.053-.673-.512-1.954-.512-.32 0-.659.03-1.01.087-.248-1.703-1.651-2.533-1.716-2.57l-.345-.2-.227.328a4.596 4.596 0 0 0-.611 1.433c-.23.972-.09 1.884.403 2.666-.596.331-1.546.418-1.744.42H.752a.753.753 0 0 0-.75.749c-.007 1.456.233 2.864.692 4.07.545 1.43 1.355 2.483 2.409 3.13 1.181.725 3.104 1.14 5.276 1.14 1.016 0 2.03-.092 2.93-.266 1.417-.273 2.705-.742 3.826-1.391a10.497 10.497 0 0 0 2.61-2.14c1.252-1.42 1.998-3.005 2.553-4.408.075.003.148.005.221.005 1.371 0 2.215-.55 2.68-1.01.505-.5.685-.998.704-1.053L24 7.076l-.237-.19Z&quot;&gt;&lt;/path&gt;</span></span><br><span class="line"><span class="string">&lt;path d=&quot;M2.216 8.075h2.119a.186.186 0 0 0 .185-.186V6a.186.186 0 0 0-.185-.186H2.216A.186.186 0 0 0 2.031 6v1.89c0 .103.083.186.185.186Zm2.92 0h2.118a.185.185 0 0 0 .185-.186V6a.185.185 0 0 0-.185-.186H5.136A.185.185 0 0 0 4.95 6v1.89c0 .103.083.186.186.186Zm2.964 0h2.118a.186.186 0 0 0 .185-.186V6a.186.186 0 0 0-.185-.186H8.1A.185.185 0 0 0 7.914 6v1.89c0 .103.083.186.186.186Zm2.928 0h2.119a.185.185 0 0 0 .185-.186V6a.185.185 0 0 0-.185-.186h-2.119a.186.186 0 0 0-.185.186v1.89c0 .103.083.186.185.186Zm-5.892-2.72h2.118a.185.185 0 0 0 .185-.186V3.28a.186.186 0 0 0-.185-.186H5.136a.186.186 0 0 0-.186.186v1.89c0 .103.083.186.186.186Zm2.964 0h2.118a.186.186 0 0 0 .185-.186V3.28a.186.186 0 0 0-.185-.186H8.1a.186.186 0 0 0-.186.186v1.89c0 .103.083.186.186.186Zm2.928 0h2.119a.185.185 0 0 0 .185-.186V3.28a.186.186 0 0 0-.185-.186h-2.119a.186.186 0 0 0-.185.186v1.89c0 .103.083.186.185.186Zm0-2.72h2.119a.186.186 0 0 0 .185-.186V.56a.185.185 0 0 0-.185-.186h-2.119a.186.186 0 0 0-.185.186v1.89c0 .103.083.186.185.186Zm2.955 5.44h2.118a.185.185 0 0 0 .186-.186V6a.185.185 0 0 0-.186-.186h-2.118a.185.185 0 0 0-.185.186v1.89c0 .103.083.186.185.186Z&quot;&gt;&lt;/path&gt;</span></span><br><span class="line"><span class="string">&lt;/svg&gt;</span></span><br><span class="line"><span class="string">&lt;/div&gt;</span></span><br><span class="line"><span class="string">&lt;div class=&quot;search-container&quot;&gt;</span></span><br><span class="line"><span class="string">&lt;input type=&quot;text&quot; id=&quot;search-input&quot; placeholder=&quot;Search Docker Hub&quot;&gt;</span></span><br><span class="line"><span class="string">&lt;button id=&quot;search-button&quot;&gt;</span></span><br><span class="line"><span class="string">&lt;svg focusable=&quot;false&quot; aria-hidden=&quot;true&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;</span></span><br><span class="line"><span class="string">&lt;path d=&quot;M21 21L16.65 16.65M19 11C19 15.4183 15.4183 19 11 19C6.58172 19 3 15.4183 3 11C3 6.58172 6.58172 3 11 3C15.4183 3 19 6.58172 19 11Z&quot; stroke=&quot;white&quot; fill=&quot;none&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;/path&gt;</span></span><br><span class="line"><span class="string">&lt;/svg&gt;</span></span><br><span class="line"><span class="string">&lt;/button&gt;</span></span><br><span class="line"><span class="string">&lt;/div&gt;</span></span><br><span class="line"><span class="string">&lt;script&gt;</span></span><br><span class="line"><span class="string">function performSearch() &#123;</span></span><br><span class="line"><span class="string">const query = document.getElementById(&#x27;search-input&#x27;).value;</span></span><br><span class="line"><span class="string">if (query) &#123;</span></span><br><span class="line"><span class="string">window.location.href = &#x27;/search?q=&#x27; + encodeURIComponent(query);</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">document.getElementById(&#x27;search-button&#x27;).addEventListener(&#x27;click&#x27;, performSearch);</span></span><br><span class="line"><span class="string">document.getElementById(&#x27;search-input&#x27;).addEventListener(&#x27;keypress&#x27;, function(event) &#123;</span></span><br><span class="line"><span class="string">if (event.key === &#x27;Enter&#x27;) &#123;</span></span><br><span class="line"><span class="string">performSearch();</span></span><br><span class="line"><span class="string">&#125;</span></span><br><span class="line"><span class="string">&#125;);</span></span><br><span class="line"><span class="string">&lt;/script&gt;</span></span><br><span class="line"><span class="string">&lt;/body&gt;</span></span><br><span class="line"><span class="string">&lt;/html&gt;</span></span><br><span class="line"><span class="string">`</span>;</span><br><span class="line"><span class="keyword">return</span> text;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line"><span class="keyword">async</span> <span class="title function_">fetch</span>(<span class="params">request, env, ctx</span>) &#123;</span><br><span class="line"><span class="keyword">const</span> <span class="title function_">getReqHeader</span> = (<span class="params">key</span>) =&gt; request.<span class="property">headers</span>.<span class="title function_">get</span>(key); <span class="comment">// 获取请求头</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> url = <span class="keyword">new</span> <span class="title function_">URL</span>(request.<span class="property">url</span>); <span class="comment">// 解析请求URL</span></span><br><span class="line"><span class="keyword">const</span> userAgentHeader = request.<span class="property">headers</span>.<span class="title function_">get</span>(<span class="string">&#x27;User-Agent&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> userAgent = userAgentHeader ? userAgentHeader.<span class="title function_">toLowerCase</span>() : <span class="string">&quot;null&quot;</span>;</span><br><span class="line"><span class="keyword">if</span> (env.<span class="property">UA</span>) 屏蔽爬虫<span class="variable constant_">UA</span> = 屏蔽爬虫<span class="variable constant_">UA</span>.<span class="title function_">concat</span>(<span class="keyword">await</span> <span class="title function_">ADD</span>(env.<span class="property">UA</span>));</span><br><span class="line">workers_url = <span class="string">`https://<span class="subst">$&#123;url.hostname&#125;</span>`</span>;</span><br><span class="line"><span class="keyword">const</span> pathname = url.<span class="property">pathname</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取请求参数中的 ns</span></span><br><span class="line"><span class="keyword">const</span> ns = url.<span class="property">searchParams</span>.<span class="title function_">get</span>(<span class="string">&#x27;ns&#x27;</span>); </span><br><span class="line"><span class="keyword">const</span> hostname = url.<span class="property">searchParams</span>.<span class="title function_">get</span>(<span class="string">&#x27;hubhost&#x27;</span>) || url.<span class="property">hostname</span>;</span><br><span class="line"><span class="keyword">const</span> hostTop = hostname.<span class="title function_">split</span>(<span class="string">&#x27;.&#x27;</span>)[<span class="number">0</span>]; <span class="comment">// 获取主机名的第一部分</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> checkHost; <span class="comment">// 在这里定义 checkHost 变量</span></span><br><span class="line"><span class="comment">// 如果存在 ns 参数，优先使用它来确定 hub_host</span></span><br><span class="line"><span class="keyword">if</span> (ns) &#123;</span><br><span class="line"><span class="keyword">if</span> (ns === <span class="string">&#x27;docker.io&#x27;</span>) &#123;</span><br><span class="line">hub_host = <span class="string">&#x27;registry-1.docker.io&#x27;</span>; <span class="comment">// 设置上游地址为 registry-1.docker.io</span></span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">hub_host = ns; <span class="comment">// 直接使用 ns 作为 hub_host</span></span><br><span class="line">&#125;</span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">checkHost = <span class="title function_">routeByHosts</span>(hostTop);</span><br><span class="line">hub_host = checkHost[<span class="number">0</span>]; <span class="comment">// 获取上游地址</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> fakePage = checkHost ? checkHost[<span class="number">1</span>] : <span class="literal">false</span>; <span class="comment">// 确保 fakePage 不为 undefined</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`域名头部: <span class="subst">$&#123;hostTop&#125;</span>\n反代地址: <span class="subst">$&#123;hub_host&#125;</span>\n伪装首页: <span class="subst">$&#123;fakePage&#125;</span>`</span>);</span><br><span class="line"><span class="keyword">const</span> isUuid = <span class="title function_">isUUID</span>(pathname.<span class="title function_">split</span>(<span class="string">&#x27;/&#x27;</span>)[<span class="number">1</span>].<span class="title function_">split</span>(<span class="string">&#x27;/&#x27;</span>)[<span class="number">0</span>]);</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (屏蔽爬虫<span class="variable constant_">UA</span>.<span class="title function_">some</span>(<span class="function"><span class="params">fxxk</span> =&gt;</span> userAgent.<span class="title function_">includes</span>(fxxk)) &amp;&amp; 屏蔽爬虫<span class="variable constant_">UA</span>.<span class="property">length</span> &gt; <span class="number">0</span>) &#123;</span><br><span class="line"><span class="comment">// 首页改成一个nginx伪装页</span></span><br><span class="line"><span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Response</span>(<span class="keyword">await</span> <span class="title function_">nginx</span>(), &#123;</span><br><span class="line"><span class="attr">headers</span>: &#123;</span><br><span class="line"><span class="string">&#x27;Content-Type&#x27;</span>: <span class="string">&#x27;text/html; charset=UTF-8&#x27;</span>,</span><br><span class="line">&#125;,</span><br><span class="line">&#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> conditions = [</span><br><span class="line">isUuid,</span><br><span class="line">pathname.<span class="title function_">includes</span>(<span class="string">&#x27;/_&#x27;</span>),</span><br><span class="line">pathname.<span class="title function_">includes</span>(<span class="string">&#x27;/r/&#x27;</span>),</span><br><span class="line">pathname.<span class="title function_">includes</span>(<span class="string">&#x27;/v2/repositories&#x27;</span>),</span><br><span class="line">pathname.<span class="title function_">includes</span>(<span class="string">&#x27;/v2/user&#x27;</span>),</span><br><span class="line">pathname.<span class="title function_">includes</span>(<span class="string">&#x27;/v2/orgs&#x27;</span>),</span><br><span class="line">pathname.<span class="title function_">includes</span>(<span class="string">&#x27;/v2/_catalog&#x27;</span>),</span><br><span class="line">pathname.<span class="title function_">includes</span>(<span class="string">&#x27;/v2/categories&#x27;</span>),</span><br><span class="line">pathname.<span class="title function_">includes</span>(<span class="string">&#x27;/v2/feature-flags&#x27;</span>),</span><br><span class="line">pathname.<span class="title function_">includes</span>(<span class="string">&#x27;search&#x27;</span>),</span><br><span class="line">pathname.<span class="title function_">includes</span>(<span class="string">&#x27;source&#x27;</span>),</span><br><span class="line">pathname == <span class="string">&#x27;/&#x27;</span>,</span><br><span class="line">pathname == <span class="string">&#x27;/favicon.ico&#x27;</span>,</span><br><span class="line">pathname == <span class="string">&#x27;/auth/profile&#x27;</span>,</span><br><span class="line">];</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (conditions.<span class="title function_">some</span>(<span class="function"><span class="params">condition</span> =&gt;</span> condition) &amp;&amp; (fakePage === <span class="literal">true</span> || hostTop == <span class="string">&#x27;docker&#x27;</span>)) &#123;</span><br><span class="line"><span class="keyword">if</span> (env.<span class="property">URL302</span>) &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="title class_">Response</span>.<span class="title function_">redirect</span>(env.<span class="property">URL302</span>, <span class="number">302</span>);</span><br><span class="line">&#125; <span class="keyword">else</span> <span class="keyword">if</span> (env.<span class="property">URL</span>) &#123;</span><br><span class="line"><span class="keyword">if</span> (env.<span class="property">URL</span>.<span class="title function_">toLowerCase</span>() == <span class="string">&#x27;nginx&#x27;</span>) &#123;</span><br><span class="line"><span class="comment">//首页改成一个nginx伪装页</span></span><br><span class="line"><span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Response</span>(<span class="keyword">await</span> <span class="title function_">nginx</span>(), &#123;</span><br><span class="line"><span class="attr">headers</span>: &#123;</span><br><span class="line"><span class="string">&#x27;Content-Type&#x27;</span>: <span class="string">&#x27;text/html; charset=UTF-8&#x27;</span>,</span><br><span class="line">&#125;,</span><br><span class="line">&#125;);</span><br><span class="line">&#125; <span class="keyword">else</span> <span class="keyword">return</span> <span class="title function_">fetch</span>(<span class="keyword">new</span> <span class="title class_">Request</span>(env.<span class="property">URL</span>, request));</span><br><span class="line">&#125; <span class="keyword">else</span> <span class="keyword">if</span> (url.<span class="property">pathname</span> == <span class="string">&#x27;/&#x27;</span>)&#123;</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Response</span>(<span class="keyword">await</span> <span class="title function_">searchInterface</span>(), &#123;</span><br><span class="line"><span class="attr">headers</span>: &#123;</span><br><span class="line">  <span class="string">&#x27;Content-Type&#x27;</span>: <span class="string">&#x27;text/html; charset=UTF-8&#x27;</span>,</span><br><span class="line">&#125;,</span><br><span class="line">&#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> newUrl = <span class="keyword">new</span> <span class="title function_">URL</span>(<span class="string">&quot;https://registry.hub.docker.com&quot;</span> + pathname + url.<span class="property">search</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 复制原始请求的标头</span></span><br><span class="line"><span class="keyword">const</span> headers = <span class="keyword">new</span> <span class="title class_">Headers</span>(request.<span class="property">headers</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 确保 Host 头部被替换为 hub.docker.com</span></span><br><span class="line">headers.<span class="title function_">set</span>(<span class="string">&#x27;Host&#x27;</span>, <span class="string">&#x27;registry.hub.docker.com&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> newRequest = <span class="keyword">new</span> <span class="title class_">Request</span>(newUrl, &#123;</span><br><span class="line"><span class="attr">method</span>: request.<span class="property">method</span>,</span><br><span class="line"><span class="attr">headers</span>: headers,</span><br><span class="line"><span class="attr">body</span>: request.<span class="property">method</span> !== <span class="string">&#x27;GET&#x27;</span> &amp;&amp; request.<span class="property">method</span> !== <span class="string">&#x27;HEAD&#x27;</span> ? <span class="keyword">await</span> request.<span class="title function_">blob</span>() : <span class="literal">null</span>,</span><br><span class="line"><span class="attr">redirect</span>: <span class="string">&#x27;follow&#x27;</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="title function_">fetch</span>(newRequest);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 修改包含 %2F 和 %3A 的请求</span></span><br><span class="line"><span class="keyword">if</span> (!<span class="regexp">/%2F/</span>.<span class="title function_">test</span>(url.<span class="property">search</span>) &amp;&amp; <span class="regexp">/%3A/</span>.<span class="title function_">test</span>(url.<span class="title function_">toString</span>())) &#123;</span><br><span class="line"><span class="keyword">let</span> modifiedUrl = url.<span class="title function_">toString</span>().<span class="title function_">replace</span>(<span class="regexp">/%3A(?=.*?&amp;)/</span>, <span class="string">&#x27;%3Alibrary%2F&#x27;</span>);</span><br><span class="line">url = <span class="keyword">new</span> <span class="title function_">URL</span>(modifiedUrl);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`handle_url: <span class="subst">$&#123;url&#125;</span>`</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 处理token请求</span></span><br><span class="line"><span class="keyword">if</span> (url.<span class="property">pathname</span>.<span class="title function_">includes</span>(<span class="string">&#x27;/token&#x27;</span>)) &#123;</span><br><span class="line"><span class="keyword">let</span> token_parameter = &#123;</span><br><span class="line"><span class="attr">headers</span>: &#123;</span><br><span class="line"><span class="string">&#x27;Host&#x27;</span>: <span class="string">&#x27;auth.docker.io&#x27;</span>,</span><br><span class="line"><span class="string">&#x27;User-Agent&#x27;</span>: <span class="title function_">getReqHeader</span>(<span class="string">&quot;User-Agent&quot;</span>),</span><br><span class="line"><span class="string">&#x27;Accept&#x27;</span>: <span class="title function_">getReqHeader</span>(<span class="string">&quot;Accept&quot;</span>),</span><br><span class="line"><span class="string">&#x27;Accept-Language&#x27;</span>: <span class="title function_">getReqHeader</span>(<span class="string">&quot;Accept-Language&quot;</span>),</span><br><span class="line"><span class="string">&#x27;Accept-Encoding&#x27;</span>: <span class="title function_">getReqHeader</span>(<span class="string">&quot;Accept-Encoding&quot;</span>),</span><br><span class="line"><span class="string">&#x27;Connection&#x27;</span>: <span class="string">&#x27;keep-alive&#x27;</span>,</span><br><span class="line"><span class="string">&#x27;Cache-Control&#x27;</span>: <span class="string">&#x27;max-age=0&#x27;</span></span><br><span class="line">&#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">let</span> token_url = auth_url + url.<span class="property">pathname</span> + url.<span class="property">search</span>;</span><br><span class="line"><span class="keyword">return</span> <span class="title function_">fetch</span>(<span class="keyword">new</span> <span class="title class_">Request</span>(token_url, request), token_parameter);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 修改 /v2/ 请求路径</span></span><br><span class="line"><span class="keyword">if</span> ( hub_host == <span class="string">&#x27;registry-1.docker.io&#x27;</span> &amp;&amp; <span class="regexp">/^\/v2\/[^/]+\/[^/]+\/[^/]+$/</span>.<span class="title function_">test</span>(url.<span class="property">pathname</span>) &amp;&amp; !<span class="regexp">/^\/v2\/library/</span>.<span class="title function_">test</span>(url.<span class="property">pathname</span>)) &#123;</span><br><span class="line"><span class="comment">//url.pathname = url.pathname.replace(/\/v2\//, &#x27;/v2/library/&#x27;);</span></span><br><span class="line">url.<span class="property">pathname</span> = <span class="string">&#x27;/v2/library/&#x27;</span> + url.<span class="property">pathname</span>.<span class="title function_">split</span>(<span class="string">&#x27;/v2/&#x27;</span>)[<span class="number">1</span>];</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`modified_url: <span class="subst">$&#123;url.pathname&#125;</span>`</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 更改请求的主机名</span></span><br><span class="line">url.<span class="property">hostname</span> = hub_host;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 构造请求参数</span></span><br><span class="line"><span class="keyword">let</span> parameter = &#123;</span><br><span class="line"><span class="attr">headers</span>: &#123;</span><br><span class="line"><span class="string">&#x27;Host&#x27;</span>: hub_host,</span><br><span class="line"><span class="string">&#x27;User-Agent&#x27;</span>: <span class="title function_">getReqHeader</span>(<span class="string">&quot;User-Agent&quot;</span>),</span><br><span class="line"><span class="string">&#x27;Accept&#x27;</span>: <span class="title function_">getReqHeader</span>(<span class="string">&quot;Accept&quot;</span>),</span><br><span class="line"><span class="string">&#x27;Accept-Language&#x27;</span>: <span class="title function_">getReqHeader</span>(<span class="string">&quot;Accept-Language&quot;</span>),</span><br><span class="line"><span class="string">&#x27;Accept-Encoding&#x27;</span>: <span class="title function_">getReqHeader</span>(<span class="string">&quot;Accept-Encoding&quot;</span>),</span><br><span class="line"><span class="string">&#x27;Connection&#x27;</span>: <span class="string">&#x27;keep-alive&#x27;</span>,</span><br><span class="line"><span class="string">&#x27;Cache-Control&#x27;</span>: <span class="string">&#x27;max-age=0&#x27;</span></span><br><span class="line">&#125;,</span><br><span class="line"><span class="attr">cacheTtl</span>: <span class="number">3600</span> <span class="comment">// 缓存时间</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 添加Authorization头</span></span><br><span class="line"><span class="keyword">if</span> (request.<span class="property">headers</span>.<span class="title function_">has</span>(<span class="string">&quot;Authorization&quot;</span>)) &#123;</span><br><span class="line">parameter.<span class="property">headers</span>.<span class="property">Authorization</span> = <span class="title function_">getReqHeader</span>(<span class="string">&quot;Authorization&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 发起请求并处理响应</span></span><br><span class="line"><span class="keyword">let</span> original_response = <span class="keyword">await</span> <span class="title function_">fetch</span>(<span class="keyword">new</span> <span class="title class_">Request</span>(url, request), parameter);</span><br><span class="line"><span class="keyword">let</span> original_response_clone = original_response.<span class="title function_">clone</span>();</span><br><span class="line"><span class="keyword">let</span> original_text = original_response_clone.<span class="property">body</span>;</span><br><span class="line"><span class="keyword">let</span> response_headers = original_response.<span class="property">headers</span>;</span><br><span class="line"><span class="keyword">let</span> new_response_headers = <span class="keyword">new</span> <span class="title class_">Headers</span>(response_headers);</span><br><span class="line"><span class="keyword">let</span> status = original_response.<span class="property">status</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 修改 Www-Authenticate 头</span></span><br><span class="line"><span class="keyword">if</span> (new_response_headers.<span class="title function_">get</span>(<span class="string">&quot;Www-Authenticate&quot;</span>)) &#123;</span><br><span class="line"><span class="keyword">let</span> auth = new_response_headers.<span class="title function_">get</span>(<span class="string">&quot;Www-Authenticate&quot;</span>);</span><br><span class="line"><span class="keyword">let</span> re = <span class="keyword">new</span> <span class="title class_">RegExp</span>(auth_url, <span class="string">&#x27;g&#x27;</span>);</span><br><span class="line">new_response_headers.<span class="title function_">set</span>(<span class="string">&quot;Www-Authenticate&quot;</span>, response_headers.<span class="title function_">get</span>(<span class="string">&quot;Www-Authenticate&quot;</span>).<span class="title function_">replace</span>(re, workers_url));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 处理重定向</span></span><br><span class="line"><span class="keyword">if</span> (new_response_headers.<span class="title function_">get</span>(<span class="string">&quot;Location&quot;</span>)) &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="title function_">httpHandler</span>(request, new_response_headers.<span class="title function_">get</span>(<span class="string">&quot;Location&quot;</span>));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 返回修改后的响应</span></span><br><span class="line"><span class="keyword">let</span> response = <span class="keyword">new</span> <span class="title class_">Response</span>(original_text, &#123;</span><br><span class="line">status,</span><br><span class="line"><span class="attr">headers</span>: new_response_headers</span><br><span class="line">&#125;);</span><br><span class="line"><span class="keyword">return</span> response;</span><br><span class="line">&#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 处理HTTP请求</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">Request</span>&#125; req 请求对象</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">string</span>&#125; pathname 请求路径</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">httpHandler</span>(<span class="params">req, pathname</span>) &#123;</span><br><span class="line"><span class="keyword">const</span> reqHdrRaw = req.<span class="property">headers</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 处理预检请求</span></span><br><span class="line"><span class="keyword">if</span> (req.<span class="property">method</span> === <span class="string">&#x27;OPTIONS&#x27;</span> &amp;&amp;</span><br><span class="line">reqHdrRaw.<span class="title function_">has</span>(<span class="string">&#x27;access-control-request-headers&#x27;</span>)</span><br><span class="line">) &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Response</span>(<span class="literal">null</span>, <span class="variable constant_">PREFLIGHT_INIT</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> rawLen = <span class="string">&#x27;&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> reqHdrNew = <span class="keyword">new</span> <span class="title class_">Headers</span>(reqHdrRaw);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> refer = reqHdrNew.<span class="title function_">get</span>(<span class="string">&#x27;referer&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> urlStr = pathname;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> urlObj = <span class="title function_">newUrl</span>(urlStr);</span><br><span class="line"></span><br><span class="line"><span class="comment">/** <span class="doctag">@type</span> &#123;<span class="type">RequestInit</span>&#125; */</span></span><br><span class="line"><span class="keyword">const</span> reqInit = &#123;</span><br><span class="line"><span class="attr">method</span>: req.<span class="property">method</span>,</span><br><span class="line"><span class="attr">headers</span>: reqHdrNew,</span><br><span class="line"><span class="attr">redirect</span>: <span class="string">&#x27;follow&#x27;</span>,</span><br><span class="line"><span class="attr">body</span>: req.<span class="property">body</span></span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">return</span> <span class="title function_">proxy</span>(urlObj, reqInit, rawLen);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 代理请求</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">URL</span>&#125; urlObj URL对象</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">RequestInit</span>&#125; reqInit 请求初始化对象</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">string</span>&#125; rawLen 原始长度</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">proxy</span>(<span class="params">urlObj, reqInit, rawLen</span>) &#123;</span><br><span class="line"><span class="keyword">const</span> res = <span class="keyword">await</span> <span class="title function_">fetch</span>(urlObj.<span class="property">href</span>, reqInit);</span><br><span class="line"><span class="keyword">const</span> resHdrOld = res.<span class="property">headers</span>;</span><br><span class="line"><span class="keyword">const</span> resHdrNew = <span class="keyword">new</span> <span class="title class_">Headers</span>(resHdrOld);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 验证长度</span></span><br><span class="line"><span class="keyword">if</span> (rawLen) &#123;</span><br><span class="line"><span class="keyword">const</span> newLen = resHdrOld.<span class="title function_">get</span>(<span class="string">&#x27;content-length&#x27;</span>) || <span class="string">&#x27;&#x27;</span>;</span><br><span class="line"><span class="keyword">const</span> badLen = (rawLen !== newLen);</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (badLen) &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="title function_">makeRes</span>(res.<span class="property">body</span>, <span class="number">400</span>, &#123;</span><br><span class="line"><span class="string">&#x27;--error&#x27;</span>: <span class="string">`bad len: <span class="subst">$&#123;newLen&#125;</span>, except: <span class="subst">$&#123;rawLen&#125;</span>`</span>,</span><br><span class="line"><span class="string">&#x27;access-control-expose-headers&#x27;</span>: <span class="string">&#x27;--error&#x27;</span>,</span><br><span class="line">&#125;);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> status = res.<span class="property">status</span>;</span><br><span class="line">resHdrNew.<span class="title function_">set</span>(<span class="string">&#x27;access-control-expose-headers&#x27;</span>, <span class="string">&#x27;*&#x27;</span>);</span><br><span class="line">resHdrNew.<span class="title function_">set</span>(<span class="string">&#x27;access-control-allow-origin&#x27;</span>, <span class="string">&#x27;*&#x27;</span>);</span><br><span class="line">resHdrNew.<span class="title function_">set</span>(<span class="string">&#x27;Cache-Control&#x27;</span>, <span class="string">&#x27;max-age=1500&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 删除不必要的头</span></span><br><span class="line">resHdrNew.<span class="title function_">delete</span>(<span class="string">&#x27;content-security-policy&#x27;</span>);</span><br><span class="line">resHdrNew.<span class="title function_">delete</span>(<span class="string">&#x27;content-security-policy-report-only&#x27;</span>);</span><br><span class="line">resHdrNew.<span class="title function_">delete</span>(<span class="string">&#x27;clear-site-data&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Response</span>(res.<span class="property">body</span>, &#123;</span><br><span class="line">status,</span><br><span class="line"><span class="attr">headers</span>: resHdrNew</span><br><span class="line">&#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">ADD</span>(<span class="params">envadd</span>) &#123;</span><br><span class="line"><span class="keyword">var</span> addtext = envadd.<span class="title function_">replace</span>(<span class="regexp">/[ |&quot;&#x27;\r\n]+/g</span>, <span class="string">&#x27;,&#x27;</span>).<span class="title function_">replace</span>(<span class="regexp">/,+/g</span>, <span class="string">&#x27;,&#x27;</span>);<span class="comment">// 将空格、双引号、单引号和换行符替换为逗号</span></span><br><span class="line"><span class="keyword">if</span> (addtext.<span class="title function_">charAt</span>(<span class="number">0</span>) == <span class="string">&#x27;,&#x27;</span>) addtext = addtext.<span class="title function_">slice</span>(<span class="number">1</span>);</span><br><span class="line"><span class="keyword">if</span> (addtext.<span class="title function_">charAt</span>(addtext.<span class="property">length</span> - <span class="number">1</span>) == <span class="string">&#x27;,&#x27;</span>) addtext = addtext.<span class="title function_">slice</span>(<span class="number">0</span>, addtext.<span class="property">length</span> - <span class="number">1</span>);</span><br><span class="line"><span class="keyword">const</span> add = addtext.<span class="title function_">split</span>(<span class="string">&#x27;,&#x27;</span>);</span><br><span class="line"><span class="keyword">return</span> add;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="配置路由（域）"><a href="#配置路由（域）" class="headerlink" title="配置路由（域）"></a>配置路由（域）</h2><ul><li>在当前<code>worker</code>点击<code>域</code>然后 添加域名</li></ul><p><img src="https://img.chrislin.eu.org/2026/06/2093fc313f7f74b22dd09bb71e05265e.webp" alt="image-20260618100025189"></p><ul><li>选择我们最开始配置子域名的子域名</li><li><img src="https://img.chrislin.eu.org/2026/06/63e7f3a71125c5398199df3e18ffaa5b.webp" alt="image-20260618100221311"></li><li>选择路由模式</li><li>路由模式：我们的二级域名相当于主域名<code>jieniyou.eu.org</code>那么我们按照前面配置的子域名就是<code>docker-image2.jieniyou.eu.org/*</code></li><li>到这里就基本结束啦</li><li><img src="https://img.chrislin.eu.org/2026/06/ae9bcee505469aafe33b3f8555f5a713.webp" alt="image-20260618100306990"></li><li>一般来讲能访问到这个页面就可以了（例如我的链接：<a href="https://docker-image2.jieniyou.eu.org/">Docker Hub Search</a>）</li><li><img src="https://img.chrislin.eu.org/2026/06/373f013cd65af57293f3189a40df84fd.webp" alt="image-20260618100837335"></li><li>使用方法就是在官方镜像前加<code>docker-image2.jieniyou.eu.org/</code>就行</li><li>例如：<code>docker pull docker-image2.jieniyou.eu.org/synctvorg/synctv</code></li><li><img src="https://img.chrislin.eu.org/2026/06/e295495dae2f61858d6dac5cba517eb9.webp" alt="image-20260618101201419"></li></ul><h1 id="更改Docker镜像加速器（可选）"><a href="#更改Docker镜像加速器（可选）" class="headerlink" title="更改Docker镜像加速器（可选）"></a>更改Docker镜像加速器（可选）</h1><h2 id="编辑-etc-docker-daemon-json-文件，没有则创建一个。"><a href="#编辑-etc-docker-daemon-json-文件，没有则创建一个。" class="headerlink" title="编辑/etc/docker/daemon.json 文件，没有则创建一个。"></a>编辑<code>/etc/docker/daemon.json</code> 文件，没有则创建一个。</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo vim /etc/docker/daemon.json</span><br></pre></td></tr></table></figure><h2 id="添加以下镜像配置（其中域名替换成你自己的），然后输入wq命令保存文件。"><a href="#添加以下镜像配置（其中域名替换成你自己的），然后输入wq命令保存文件。" class="headerlink" title="添加以下镜像配置（其中域名替换成你自己的），然后输入wq命令保存文件。"></a>添加以下镜像配置（其中域名替换成你自己的），然后输入wq命令保存文件。</h2><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;registry-mirrors&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">            <span class="string">&quot;https://docker-image.jieniyou.eu.org&quot;</span></span><br><span class="line">    <span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h2 id="重启docker使配置生效"><a href="#重启docker使配置生效" class="headerlink" title="重启docker使配置生效"></a>重启docker使配置生效</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo systemctl daemon-reload</span><br><span class="line">sudo systemctl restart docker</span><br></pre></td></tr></table></figure><h2 id="验证成功可以输入"><a href="#验证成功可以输入" class="headerlink" title="验证成功可以输入"></a>验证成功可以输入</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker info</span><br></pre></td></tr></table></figure><h2 id="运行一下hello-world验证是否可以成功拉取镜像"><a href="#运行一下hello-world验证是否可以成功拉取镜像" class="headerlink" title="运行一下hello-world验证是否可以成功拉取镜像"></a>运行一下hello-world验证是否可以成功拉取镜像</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run hello-world</span><br></pre></td></tr></table></figure><p>好了，大概就差不多到这里就结束啦！！！</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;用&lt;code&gt;docker&lt;/code&gt;的应该都知道 &lt;code&gt;dockerhub&lt;/code&gt; 现在在国内无法直接访问，在用&lt;code&gt;docker&lt;/code&gt;取拉取镜像的时候会失败连接超时，我们要么取网上找各种第三方镜像加速器，但会出现一个问题，不稳定，也不是最新版</summary>
      
    
    
    
    <category term="🍭小敏の半糖" scheme="https://xmblog.chrislin.eu.org/categories/%F0%9F%8D%AD%E5%B0%8F%E6%95%8F%E3%81%AE%E5%8D%8A%E7%B3%96/"/>
    
    
    <category term="⭐晚风の星匣" scheme="https://xmblog.chrislin.eu.org/tags/%E2%AD%90%E6%99%9A%E9%A3%8E%E3%81%AE%E6%98%9F%E5%8C%A3/"/>
    
  </entry>
  
  <entry>
    <title>Codex的Key登录方式插件的使用方法</title>
    <link href="https://xmblog.chrislin.eu.org/posts/20260608011115.html"/>
    <id>https://xmblog.chrislin.eu.org/posts/20260608011115.html</id>
    <published>2026-06-08T01:11:15.000Z</published>
    <updated>2026-11-10T13:02:16.260Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Codex-APP如果需要使用插件可以下载Codex-进行使用插件"><a href="#Codex-APP如果需要使用插件可以下载Codex-进行使用插件" class="headerlink" title="Codex APP如果需要使用插件可以下载Codex++进行使用插件"></a><code>Codex APP</code>如果需要使用插件可以下载Codex++进行使用插件</h1><p><a href="https://github.com/BigPizzaV3/CodexPlusPlus">BigPizzaV3&#x2F;CodexPlusPlus: An enhanced tool for CodexApp, striving to make Codex better to use and more comfortable 一个CodexApp的增强工具，努力让Codex变得更好用更舒服</a></p><p><img src="https://img.chrislin.eu.org/2026/06/35600dcf64261e9d4932f8de84db0082.webp" alt="image-20260608160730585"></p><p><img src="https://img.chrislin.eu.org/2026/06/6d04efb6895854a3fbb655cba9c694fa.webp" alt="image-20260608160925715"></p><p>安装好了之后桌面上一般会出现两个图标</p><p><img src="https://img.chrislin.eu.org/2026/06/16e5ea81e8ce104a66ee6c4cd5fcfaaa.webp" alt="image-20260608161035296"></p><p>我们可以直接运行<code>codex++</code>也可以打开 <code>codex++管理工具</code></p><p><img src="https://img.chrislin.eu.org/2026/06/738685a4b06729b7c3991692f4b19a1e.webp" alt="image-20260608161233447"></p><p><img src="https://img.chrislin.eu.org/2026/06/a469f0a6610f274efc2ad50713a926eb.webp" alt="image-20260608161414104"></p><p><code>codex</code>使用key登录的插件使用到这里就结束啦！！！</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Codex-APP如果需要使用插件可以下载Codex-进行使用插件&quot;&gt;&lt;a href=&quot;#Codex-APP如果需要使用插件可以下载Codex-进行使用插件&quot; class=&quot;headerlink&quot; title=&quot;Codex APP如果需要使用插件可以下载Codex</summary>
      
    
    
    
    <category term="🍭小敏の半糖" scheme="https://xmblog.chrislin.eu.org/categories/%F0%9F%8D%AD%E5%B0%8F%E6%95%8F%E3%81%AE%E5%8D%8A%E7%B3%96/"/>
    
    
    <category term="⭐晚风の星匣" scheme="https://xmblog.chrislin.eu.org/tags/%E2%AD%90%E6%99%9A%E9%A3%8E%E3%81%AE%E6%98%9F%E5%8C%A3/"/>
    
    <category term="API" scheme="https://xmblog.chrislin.eu.org/tags/API/"/>
    
  </entry>
  
  <entry>
    <title>MCのAPI使用方法</title>
    <link href="https://xmblog.chrislin.eu.org/posts/20260608011015.html"/>
    <id>https://xmblog.chrislin.eu.org/posts/20260608011015.html</id>
    <published>2026-06-08T01:10:15.000Z</published>
    <updated>2026-11-10T13:02:16.260Z</updated>
    
    <content type="html"><![CDATA[<h1 id="codex-cli安装使用"><a href="#codex-cli安装使用" class="headerlink" title="codex cli安装使用"></a><code>codex cli</code>安装使用</h1><h1 id="MCのAPI-地址："><a href="#MCのAPI-地址：" class="headerlink" title="MCのAPI 地址："></a><code>MCのAPI</code> 地址：</h1><p><a href="https://ai-api.chrislin.eu.org/">https://ai-api.chrislin.eu.org</a></p><p><a href="https://ai-api.xiaocai.eu.cc/">https://ai-api.xiaocai.eu.cc</a></p><h1 id="使用说明："><a href="#使用说明：" class="headerlink" title="使用说明："></a>使用说明：</h1><h2 id="按照下图可以进行登录（没有账户的可自行注册）"><a href="#按照下图可以进行登录（没有账户的可自行注册）" class="headerlink" title="按照下图可以进行登录（没有账户的可自行注册）"></a>按照下图可以进行登录（没有账户的可自行注册）<img src="https://img.chrislin.eu.org/2026/06/19a5a2c4794dd02f0e5e907fd8de9700.webp" alt="image-20260608091838808"></h2><h2 id="如果注册途中需要填写邀请码可填写（VIP-XIAOMIN）或者点击-创建账户-MCのAPI-直达"><a href="#如果注册途中需要填写邀请码可填写（VIP-XIAOMIN）或者点击-创建账户-MCのAPI-直达" class="headerlink" title="如果注册途中需要填写邀请码可填写（VIP-XIAOMIN）或者点击 创建账户 - MCのAPI 直达"></a>如果注册途中需要填写邀请码可填写（<code>VIP-XIAOMIN</code>）或者点击 <a href="https://ai-api.chrislin.eu.org/register?aff=VIP-XIAOMIN">创建账户 - MCのAPI</a> 直达</h2><p><img src="https://img.chrislin.eu.org/2026/06/ff1addd75d2c955c6c4972bd59010811.webp" alt="image-20260608092138624"></p><h2 id="进入控制台后会有注册礼包-5可用"><a href="#进入控制台后会有注册礼包-5可用" class="headerlink" title="进入控制台后会有注册礼包$5可用"></a>进入控制台后会有注册礼包<code>$5</code>可用</h2><p><img src="https://img.chrislin.eu.org/2026/06/7b9e1adee6334aef2034fd281cbcf2d1.webp" alt="image-20260608092905647"></p><h2 id="API密钥的使用"><a href="#API密钥的使用" class="headerlink" title="API密钥的使用"></a><code>API密钥</code>的使用</h2><h3 id="点击右边的创建密钥按钮进行创建"><a href="#点击右边的创建密钥按钮进行创建" class="headerlink" title="点击右边的创建密钥按钮进行创建"></a>点击右边的创建<code>密钥按钮</code>进行创建</h3><p><img src="https://img.chrislin.eu.org/2026/06/1facf2925f9eea1c26dd503d59118a33.webp" alt="image-20260608093057465"></p><h3 id="创建密钥信息的填写可参考下图所示，一般情况填写名称和选择分组即可"><a href="#创建密钥信息的填写可参考下图所示，一般情况填写名称和选择分组即可" class="headerlink" title="创建密钥信息的填写可参考下图所示，一般情况填写名称和选择分组即可"></a>创建密钥信息的填写可参考下图所示，一般情况填写名称和选择分组即可</h3><h3 id=""><a href="#" class="headerlink" title=""></a><img src="https://img.chrislin.eu.org/2026/06/494e350c209383d61488d50c2363f7ff.webp" alt="image-20260608093222812"></h3><h3 id="创建好之后我们开始点击使用密钥"><a href="#创建好之后我们开始点击使用密钥" class="headerlink" title="创建好之后我们开始点击使用密钥"></a>创建好之后我们开始点击使用密钥</h3><p><img src="https://img.chrislin.eu.org/2026/06/831d400b7f768ed25afd6c4dcc8dc709.webp" alt="image-20260608093358940"></p><h3 id="我们开始配置本地环境信息"><a href="#我们开始配置本地环境信息" class="headerlink" title="我们开始配置本地环境信息"></a>我们开始配置本地环境信息</h3><p><img src="https://img.chrislin.eu.org/2026/06/a6eb8da8cddf08dc7397c908a1ed00c2.webp" alt="image-20260608094439567"></p><h3 id="参考如下"><a href="#参考如下" class="headerlink" title="参考如下"></a>参考如下</h3><p><img src="https://img.chrislin.eu.org/2026/06/7b1e98665aa35c59f0d970f46e251b60.webp" alt="image-20260608094626354"></p><p><img src="https://img.chrislin.eu.org/2026/06/cc4b37a26b313c806b35311c095b0742.webp" alt="image-20260608094833537"></p><p><img src="https://img.chrislin.eu.org/2026/06/cbdc5148e9b3f5635b55086cd2b52071.webp" alt="image-20260608095146493"></p><p><img src="https://img.chrislin.eu.org/2026/06/857edf04fa6d6fb7ccbeeac8ae0ba84d.webp" alt="image-20260608095336848"></p><h2 id="配置完成后，我们需要重启正在使用对应的软件例如："><a href="#配置完成后，我们需要重启正在使用对应的软件例如：" class="headerlink" title="配置完成后，我们需要重启正在使用对应的软件例如："></a>配置完成后，我们需要重启正在使用对应的软件例如：</h2><h3 id="IDEA"><a href="#IDEA" class="headerlink" title="IDEA"></a><code>IDEA</code></h3><h3 id="WebStorm"><a href="#WebStorm" class="headerlink" title="WebStorm"></a><code>WebStorm</code></h3><h3 id="VSCode"><a href="#VSCode" class="headerlink" title="VSCode"></a><code>VSCode</code></h3><h3 id="也就是涉及到的命令行形式都需要关闭重新启动加载配置才能生效"><a href="#也就是涉及到的命令行形式都需要关闭重新启动加载配置才能生效" class="headerlink" title="也就是涉及到的命令行形式都需要关闭重新启动加载配置才能生效"></a>也就是涉及到的命令行形式都需要关闭重新启动加载配置才能生效</h3><h3 id="注意：codex-app最好是先退出登录，然后重新打开-然后进行key登录"><a href="#注意：codex-app最好是先退出登录，然后重新打开-然后进行key登录" class="headerlink" title="注意：codex app最好是先退出登录，然后重新打开,然后进行key登录"></a>注意：<code>codex app</code>最好是先退出登录，然后重新打开,然后进行key登录</h3><h4 id="没有codex-app-的可前往微软商店-（Microsoft-Store）下载"><a href="#没有codex-app-的可前往微软商店-（Microsoft-Store）下载" class="headerlink" title="没有codex app 的可前往微软商店 （Microsoft Store）下载"></a>没有<code>codex app</code> 的可前往<code>微软商店 （Microsoft Store）</code>下载</h4><p><img src="https://img.chrislin.eu.org/2026/06/775356decbaf8576fa66cce4e512b41c.webp" alt="image-20260608173631776"></p><h4 id="下面是key方式的使用教程"><a href="#下面是key方式的使用教程" class="headerlink" title="下面是key方式的使用教程"></a>下面是<code>key</code>方式的使用教程</h4><p><img src="https://img.chrislin.eu.org/2026/06/00f14eec808b71b559668f0f6b2b6aba.webp" alt="image-20260608100840288"></p><p><img src="https://img.chrislin.eu.org/2026/06/d0823bd29e709011a98a8968b65cd61a.webp" alt="image-20260608100937498"></p><h2 id="codex-app使用插件可以参考这篇文章"><a href="#codex-app使用插件可以参考这篇文章" class="headerlink" title="codex app使用插件可以参考这篇文章 "></a><code>codex app</code>使用插件可以参考这篇文章 <a href="/posts/20260608011115.html" title="Codex的Key登录方式插件的使用方法">Codex的Key登录方式插件的使用方法</a></h2>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;codex-cli安装使用&quot;&gt;&lt;a href=&quot;#codex-cli安装使用&quot; class=&quot;headerlink&quot; title=&quot;codex cli安装使用&quot;&gt;&lt;/a&gt;&lt;code&gt;codex cli&lt;/code&gt;安装使用&lt;/h1&gt;&lt;h1 id=&quot;MCのAPI-地</summary>
      
    
    
    
    <category term="🍭小敏の半糖" scheme="https://xmblog.chrislin.eu.org/categories/%F0%9F%8D%AD%E5%B0%8F%E6%95%8F%E3%81%AE%E5%8D%8A%E7%B3%96/"/>
    
    
    <category term="⭐晚风の星匣" scheme="https://xmblog.chrislin.eu.org/tags/%E2%AD%90%E6%99%9A%E9%A3%8E%E3%81%AE%E6%98%9F%E5%8C%A3/"/>
    
    <category term="API" scheme="https://xmblog.chrislin.eu.org/tags/API/"/>
    
  </entry>
  
  <entry>
    <title>记录2026·一键激活JetBarin全家桶</title>
    <link href="https://xmblog.chrislin.eu.org/posts/20260416010421.html"/>
    <id>https://xmblog.chrislin.eu.org/posts/20260416010421.html</id>
    <published>2026-04-16T01:04:21.000Z</published>
    <updated>2026-11-10T13:02:16.260Z</updated>
    
    <content type="html"><![CDATA[<p>这里整合了一套<strong>全自动激活方案</strong>，适配 <code>Win/Linux/Mac</code> 三大系统，实测覆盖 <code>IDEA、PyCharm、WebStorm </code>等全系列工具，激活有效期直接拉满到 <strong>2099 年 12 月 31 日</strong>！</p><p>官网地址：<a href="https://ckey.run/">CodeKey Run</a></p><h5 id="Windows-系统"><a href="#Windows-系统" class="headerlink" title="Windows 系统"></a><strong>Windows 系统</strong></h5><ol><li><p><strong>打开管理员权限 <code>PowerShell</code></strong>：按<code>Win+X</code>，选择<code>Windows PowerShell(管理员)</code></p></li><li><p><strong>复制执行激活命令</strong>（切勿手输！）：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">irm ckey.run|iex</span><br></pre></td></tr></table></figure></li><li><p><strong>Debug 模式</strong>（查看详细日志）：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">irm ckey.run/debug|iex</span><br></pre></td></tr></table></figure></li><li><p><strong>查看脚本源码</strong>：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">irm ckey.run</span><br></pre></td></tr></table></figure></li></ol><h5 id="Linux-系统"><a href="#Linux-系统" class="headerlink" title="Linux 系统"></a><strong>Linux 系统</strong></h5><ol><li><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wget --no-check-certificate ckey.run -O ckey.run &amp;&amp; bash ckey.run</span><br></pre></td></tr></table></figure></li><li><p><strong>Debug 模式</strong>（查看详细日志）：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wget --no-check-certificate ckey.run/debug -O ckey.run &amp;&amp; bash ckey.run</span><br></pre></td></tr></table></figure></li></ol><h5 id="Mac-系统"><a href="#Mac-系统" class="headerlink" title="Mac 系统"></a><strong>Mac 系统</strong></h5><ol><li><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -L -o ckey.run ckey.run &amp;&amp; bash ckey.run</span><br></pre></td></tr></table></figure></li><li><p><strong>Debug 模式</strong>（查看详细日志）：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -L -o ckey.run ckey.run/debug &amp;&amp; bash ckey.run</span><br></pre></td></tr></table></figure></li><li><p><strong>注意</strong>：<code>Mac </code>默认无 <code>wget</code>，推荐用 <code>curl</code>；若已安装 <code>wget</code>，可直接使用 <code>Linux </code>命令</p></li></ol><h4 id="实测环境与激活效果"><a href="#实测环境与激活效果" class="headerlink" title="实测环境与激活效果"></a><strong>实测环境与激活效果</strong></h4><h5 id="测试系统"><a href="#测试系统" class="headerlink" title="测试系统"></a><strong>测试系统</strong></h5><ul><li>Windows 11</li></ul><h5 id="激活示例"><a href="#激活示例" class="headerlink" title="激活示例"></a><strong>激活示例</strong></h5><h5 id="IDEA-2026-1"><a href="#IDEA-2026-1" class="headerlink" title="IDEA 2026.1"></a><strong>IDEA 2026.1</strong></h5><p>命令截图：</p><p><img src="https://img.chrislin.eu.org/2026/04/40205c748ad70fd79cfccce60b7c8a80.webp" alt="image-20260416091401527" style="height: 400px" /><img src="https://img.chrislin.eu.org/2026/04/dd2dbd67f993dff33ad7848b7827565a.webp" alt="image-20260416091431162" style="height: 400px" /></p><p>激活后<code>idea</code>截图：</p><img src="https://img.chrislin.eu.org/2026/04/55296d35c846c4a58707ec9077ca05e9.webp" alt="image-20260416091502859" style="width:600px;" /><p>激活后<code>webstorm</code>截图：</p><img src="https://img.chrislin.eu.org/2026/04/da397cfcdff8c5959226b0082748e516.webp" alt="image-20260416091534768" style="width:600px;" /><p>激活后<code>pycharm</code>截图：</p><img src="https://img.chrislin.eu.org/2026/04/41d240eb01e89c96e9711aaa653a6951.webp" alt="image-20260416091614990" style="width:600px;" /><h4 id="激活原理"><a href="#激活原理" class="headerlink" title="激活原理"></a>激活原理</h4><p>它激活仍然是用的<code>ja-netfilter</code> 而且版本是<code>ja-netfilter 2022.2.0</code></p><p>从如下目录也可以看到下载的文件：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">C:\Users\Public\.jb_run\</span><br></pre></td></tr></table></figure><p><strong>！！！这个目录不要删除！！！</strong></p><p>上面那个脚本，只是把整个过程自动化了。</p><h4 id="注意事项与常见问题"><a href="#注意事项与常见问题" class="headerlink" title="注意事项与常见问题"></a><strong>注意事项与常见问题</strong></h4><ol><li><strong>激活前准备</strong>：请关闭所有 <code>JetBrains </code>软件，避免冲突</li><li><strong>Mac 激活失败解决方案</strong>：若之前使用过其他工具，需彻底删除缓存文件（路径示例：<code>~/Library/Application Support/JetBrains</code>）</li><li><strong>安全提示</strong>：脚本源码可通过<code>irm ckey.run</code>查看，建议在执行前确认代码安全性</li></ol>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;这里整合了一套&lt;strong&gt;全自动激活方案&lt;/strong&gt;，适配 &lt;code&gt;Win/Linux/Mac&lt;/code&gt; 三大系统，实测覆盖 &lt;code&gt;IDEA、PyCharm、WebStorm &lt;/code&gt;等全系列工具，激活有效期直接拉满到 &lt;strong&gt;2099</summary>
      
    
    
    
    <category term="🍭小敏の半糖" scheme="https://xmblog.chrislin.eu.org/categories/%F0%9F%8D%AD%E5%B0%8F%E6%95%8F%E3%81%AE%E5%8D%8A%E7%B3%96/"/>
    
    
    <category term="⭐晚风の星匣" scheme="https://xmblog.chrislin.eu.org/tags/%E2%AD%90%E6%99%9A%E9%A3%8E%E3%81%AE%E6%98%9F%E5%8C%A3/"/>
    
    <category term="JetBrains" scheme="https://xmblog.chrislin.eu.org/tags/JetBrains/"/>
    
  </entry>
  
  <entry>
    <title>EKP流程复制案例</title>
    <link href="https://xmblog.chrislin.eu.org/posts/20260313095341.html"/>
    <id>https://xmblog.chrislin.eu.org/posts/20260313095341.html</id>
    <published>2026-03-13T09:53:41.000Z</published>
    <updated>2026-11-10T13:02:16.260Z</updated>
    
    <content type="html"><![CDATA[<h2 id="项目来源-SPRJ202509171552-SCAJ"><a href="#项目来源-SPRJ202509171552-SCAJ" class="headerlink" title="项目来源 SPRJ202509171552_SCAJ"></a>项目来源 <code>SPRJ202509171552_SCAJ</code></h2><h2 id="前端请求方法"><a href="#前端请求方法" class="headerlink" title="前端请求方法"></a>前端请求方法</h2><ul><li><p>先是进行的检查<code>checkTemplate</code>是否有新版本，并且提示信息</p></li><li><p>然后弹窗确认是否复制流程(<code>copyUrl</code>通过按钮<code>copyDoc</code>传入)</p></li></ul><figure class="highlight jsp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">&lt;%--复制--%&gt;</span><br><span class="line">&lt;kmss:<span class="type">auth</span> <span class="variable">requestURL</span><span class="operator">=</span><span class="string">&quot;/fssc/invoice/fssc_invoice_payable/fsscInvoicePayable.do?method=add&amp;invoiceId=$&#123;param.fdId&#125;&amp;fdId=$&#123;param.fdId&#125;&quot;</span> requestMethod=<span class="string">&quot;GET&quot;</span>&gt;</span><br><span class="line">    &lt;ui:<span class="type">button</span> <span class="variable">text</span><span class="operator">=</span><span class="string">&quot;$&#123;lfn:message(&#x27;fssc-invoice:fsscInvoicePayable.copy&#x27;) &#125;&quot;</span> order=<span class="string">&quot;5&quot;</span> onclick=<span class="string">&quot;copyDoc(&#x27;$&#123;LUI_ContextPath&#125;/fssc/invoice/fssc_invoice_payable/fsscInvoicePayable.do?method=add&amp;invoiceId=$&#123;param.fdId&#125;&amp;i.docTemplate=$&#123;fsscInvoicePayableForm.docTemplateId&#125;&amp;fdReviewIdSource=copy&#x27;);&quot;</span>&gt;</span><br><span class="line">    &lt;/ui:button&gt;</span><br><span class="line">&lt;/kmss:auth&gt;</span><br><span class="line">&lt;script&gt;</span><br><span class="line">    <span class="type">function</span> <span class="title function_">copyDoc</span><span class="params">(copyUrl)</span> &#123;</span><br><span class="line">        seajs.use([<span class="string">&#x27;lui/dialog&#x27;</span>], function(dialog) &#123;</span><br><span class="line">            <span class="comment">// 检查模板表单是否有更新</span></span><br><span class="line">            $.ajax(&#123;</span><br><span class="line">                url : <span class="string">&#x27;&lt;c:url value=&quot;/fssc/invoice/fssc_invoice_payable/fsscInvoicePayable.do&quot; /&gt;?method=checkTemplate&amp;invoiceId=$&#123;param.fdId&#125;&amp;docTemplateId=$&#123;fsscInvoicePayableForm.docTemplateId&#125;&#x27;</span>,</span><br><span class="line">                <span class="comment">// 这里的请求如果是异步，在打开新窗口时会被浏览器阻止，所以设置为同步，缺点：在点击“复制流程”时，会有一点点卡顿</span></span><br><span class="line">                async : <span class="literal">false</span>,</span><br><span class="line">                dataType : <span class="string">&#x27;json&#x27;</span>,</span><br><span class="line">                success : function(json) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (json == <span class="literal">false</span>) &#123;</span><br><span class="line">                        Com_OpenWindow(copyUrl, <span class="string">&#x27;_blank&#x27;</span>);</span><br><span class="line">                    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                        dialog.confirm(<span class="string">&#x27;&lt;bean:message bundle=&quot;fssc-invoice&quot; key=&quot;fsscInvoicePayable.copy.comfirm&quot;/&gt;&#x27;</span>, function(isOk) &#123;</span><br><span class="line">                            <span class="keyword">if</span> (isOk) &#123;</span><br><span class="line">                                Com_OpenWindow(copyUrl, <span class="string">&#x27;_blank&#x27;</span>);</span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;);</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;</span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="创建表单的时候设置信息"><a href="#创建表单的时候设置信息" class="headerlink" title="创建表单的时候设置信息"></a>创建表单的时候设置信息</h2><ul><li>拿到传递的参数<code>invoiceId</code>去查询实体</li><li>先将实体转换赋值到表单中<code>copyForm</code></li><li>其次清空部分参数和赋值部分参数</li></ul><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="type">ActionForm</span> <span class="title function_">createNewForm</span><span class="params">(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    <span class="built_in">super</span>.createNewForm(mapping, form, request, response);</span><br><span class="line">    ((IFsscInvoicePayableService) getServiceImp(request)).initFormSetting((IExtendForm) form, <span class="keyword">new</span> <span class="title class_">RequestContext</span>(request));</span><br><span class="line">    <span class="comment">/*add by 增加复制流程功能 start*/</span></span><br><span class="line">    <span class="type">FsscInvoicePayableForm</span> <span class="variable">newForm</span> <span class="operator">=</span> (FsscInvoicePayableForm) form;</span><br><span class="line">    <span class="type">String</span> <span class="variable">invoiceId</span> <span class="operator">=</span> request.getParameter(<span class="string">&quot;invoiceId&quot;</span>);</span><br><span class="line">    <span class="comment">// 复制流程时，尽可能复制原文档的数据</span></span><br><span class="line">    <span class="keyword">if</span> (StringUtil.isNotNull(invoiceId)) &#123;</span><br><span class="line">        <span class="type">FsscInvoicePayable</span> <span class="variable">fsscInvoicePayable</span> <span class="operator">=</span> (FsscInvoicePayable) getServiceImp(request).findByPrimaryKey(invoiceId);</span><br><span class="line">        <span class="type">String</span> <span class="variable">authReaderIds</span> <span class="operator">=</span> newForm.getAuthReaderIds();</span><br><span class="line">        <span class="type">String</span> <span class="variable">authReaderNames</span> <span class="operator">=</span> newForm.getAuthReaderNames();</span><br><span class="line">        <span class="type">String</span> <span class="variable">authAttCopyIds</span> <span class="operator">=</span> newForm.getAuthAttCopyIds();</span><br><span class="line">        <span class="type">String</span> <span class="variable">authAttCopyNames</span> <span class="operator">=</span> newForm.getAuthAttCopyNames();</span><br><span class="line">        <span class="type">String</span> <span class="variable">authAttNoCopy</span> <span class="operator">=</span> newForm.getAuthAttNocopy();</span><br><span class="line">        <span class="type">String</span> <span class="variable">authAttDownloadIds</span> <span class="operator">=</span> newForm.getAuthAttDownloadIds();</span><br><span class="line">        <span class="type">String</span> <span class="variable">authAttDownloadNames</span> <span class="operator">=</span> newForm.getAuthAttDownloadNames();</span><br><span class="line">        <span class="type">String</span> <span class="variable">authAttNodownload</span> <span class="operator">=</span> newForm.getAuthAttNodownload();</span><br><span class="line">        <span class="type">String</span> <span class="variable">authAttPrintIds</span> <span class="operator">=</span> newForm.getAuthAttPrintIds();</span><br><span class="line">        <span class="type">String</span> <span class="variable">authAttPrintNames</span> <span class="operator">=</span> newForm.getAuthAttPrintNames();</span><br><span class="line">        <span class="type">String</span> <span class="variable">authAttNoprint</span> <span class="operator">=</span> newForm.getAuthAttNoprint();</span><br><span class="line">        <span class="type">String</span> <span class="variable">extendFilePath</span> <span class="operator">=</span> newForm.getExtendDataFormInfo().getExtendFilePath();</span><br><span class="line"></span><br><span class="line">        <span class="type">Map</span>&lt;String, Object&gt; <span class="variable">newDataMap</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">HashMap</span>();</span><br><span class="line">        <span class="type">boolean</span> <span class="variable">isUpdate</span> <span class="operator">=</span> Boolean.valueOf(<span class="built_in">this</span>.checkTemplateUpdate(mapping, form, request, response, newDataMap));</span><br><span class="line">        <span class="type">FsscInvoicePayableForm</span> <span class="variable">copyForm</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="keyword">if</span> (fsscInvoicePayable != <span class="literal">null</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (!UserUtil.checkAuthentication(ModelUtil.getModelUrl(fsscInvoicePayable), <span class="string">&quot;GET&quot;</span>)) &#123;</span><br><span class="line">                <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">KmssRuntimeException</span>(<span class="keyword">new</span> <span class="title class_">KmssMessage</span>(<span class="string">&quot;fssc-invoice:fsscInvoicePayable.auth.copy.error&quot;</span>));</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="type">RequestContext</span> <span class="variable">requestContext</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">RequestContext</span>(request);</span><br><span class="line">            requestContext.setParameter(<span class="string">&quot;extendDataClone&quot;</span>, <span class="string">&quot;true&quot;</span>);</span><br><span class="line">            copyForm = (FsscInvoicePayableForm)<span class="built_in">this</span>.getServiceImp(request).cloneModelToForm(newForm, fsscInvoicePayable, requestContext);</span><br><span class="line">        &#125;</span><br><span class="line">        newForm.setDocNumber((String)<span class="literal">null</span>);</span><br><span class="line">        newForm.setDocCreateTime(DateUtil.convertDateToString(<span class="keyword">new</span> <span class="title class_">Date</span>(), <span class="string">&quot;datetime&quot;</span>, request.getLocale()));</span><br><span class="line">        newForm.setDocCreatorId(UserUtil.getUser().getFdId());</span><br><span class="line">        newForm.setDocCreatorName(UserUtil.getUserName(request));</span><br><span class="line">        newForm.setDocStatus(<span class="string">&quot;10&quot;</span>);</span><br><span class="line">        newForm.setDocPublishTime((String)<span class="literal">null</span>);</span><br><span class="line">        <span class="type">Map</span>&lt;String, Object&gt; <span class="variable">oldDataMap</span> <span class="operator">=</span> copyForm.getExtendDataFormInfo().getFormData();</span><br><span class="line">        <span class="type">DictLoadService</span> <span class="variable">sysFormDictLoadService</span> <span class="operator">=</span> (DictLoadService)SpringBeanUtil.getBean(<span class="string">&quot;sysFormDictLoadService&quot;</span>);</span><br><span class="line">        <span class="type">SysDictExtendModel</span> <span class="variable">dictExtendModel</span> <span class="operator">=</span> sysFormDictLoadService.loadDictByFileName(extendFilePath);</span><br><span class="line">        request.setAttribute(newForm.getModelClass().getName() + <span class="string">&quot;#&quot;</span> + newForm.getFdId(), dictExtendModel);</span><br><span class="line">        <span class="type">Map</span>&lt;String, SysDictCommonProperty&gt; <span class="variable">propertyMap</span> <span class="operator">=</span> dictExtendModel.getPropertyMap();</span><br><span class="line">        <span class="keyword">if</span> (isUpdate) &#123;</span><br><span class="line">            <span class="keyword">for</span>(String key : oldDataMap.keySet()) &#123;</span><br><span class="line">                <span class="keyword">if</span> (newDataMap.containsKey(key)) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (<span class="built_in">this</span>.isNotCopy(propertyMap, key)) &#123;</span><br><span class="line">                        <span class="built_in">this</span>.putDefaultValue(newDataMap, key);</span><br><span class="line">                    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                        <span class="type">Object</span> <span class="variable">value</span> <span class="operator">=</span> oldDataMap.get(key);</span><br><span class="line">                        <span class="keyword">if</span> (!<span class="built_in">this</span>.isNull(value)) &#123;</span><br><span class="line">                            <span class="keyword">if</span> (key.indexOf(<span class="string">&quot;_index&quot;</span>) &gt; -<span class="number">1</span>) &#123;</span><br><span class="line">                                <span class="type">String</span>[] <span class="variable">keyArr</span> <span class="operator">=</span> key.split(<span class="string">&quot;_index&quot;</span>);</span><br><span class="line">                                value = oldDataMap.get(keyArr[<span class="number">0</span>]);</span><br><span class="line">                                <span class="keyword">if</span> (value == <span class="literal">null</span>) &#123;</span><br><span class="line">                                    <span class="keyword">continue</span>;</span><br><span class="line">                                &#125;</span><br><span class="line"></span><br><span class="line">                                <span class="keyword">if</span> (propertyMap.containsKey(keyArr[<span class="number">0</span>]) &amp;&amp; propertyMap.get(keyArr[<span class="number">0</span>]) <span class="keyword">instanceof</span> SysDictExtendSubTableProperty) &#123;</span><br><span class="line">                                    <span class="type">List</span>&lt;?&gt; <span class="variable">_values</span> <span class="operator">=</span> (List)value;</span><br><span class="line">                                    <span class="keyword">new</span> <span class="title class_">HashMap</span>();</span><br><span class="line">                                    <span class="type">HashMap</span>&lt;String, Object&gt; <span class="variable">var75</span> <span class="operator">=</span> (HashMap)newDataMap.get(key);</span><br><span class="line"></span><br><span class="line">                                    <span class="keyword">for</span>(<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; _values.size(); ++i) &#123;</span><br><span class="line">                                        <span class="keyword">if</span> (_values.get(i) <span class="keyword">instanceof</span> HashMap) &#123;</span><br><span class="line">                                            <span class="type">HashMap</span>&lt;String, Object&gt; <span class="variable">_map</span> <span class="operator">=</span> (HashMap)_values.get(i);</span><br><span class="line"></span><br><span class="line">                                            <span class="keyword">for</span>(String _key : var75.keySet()) &#123;</span><br><span class="line">                                                <span class="keyword">if</span> (!_map.containsKey(_key)) &#123;</span><br><span class="line">                                                    _map.put(_key, var75.get(_key));</span><br><span class="line">                                                &#125;</span><br><span class="line">                                            &#125;</span><br><span class="line">                                        &#125;</span><br><span class="line">                                    &#125;</span><br><span class="line"></span><br><span class="line">                                    value = _values;</span><br><span class="line">                                &#125;</span><br><span class="line">                            &#125;</span><br><span class="line"></span><br><span class="line">                            <span class="built_in">this</span>.putDefaultValue(newDataMap, key);</span><br><span class="line">                            newDataMap.put(key, value);</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">for</span>(String key : oldDataMap.keySet()) &#123;</span><br><span class="line">                <span class="keyword">if</span> (<span class="built_in">this</span>.isNotCopy(propertyMap, key)) &#123;</span><br><span class="line">                    <span class="built_in">this</span>.putDefaultValue(newDataMap, key);</span><br><span class="line">                    <span class="keyword">if</span> (!newDataMap.containsKey(key)) &#123;</span><br><span class="line">                        newDataMap.put(key, (Object)<span class="literal">null</span>);</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (!key.endsWith(<span class="string">&quot;_index_&quot;</span>)) &#123;</span><br><span class="line">                    <span class="built_in">this</span>.setSubTableValue(propertyMap, oldDataMap, newDataMap, key);</span><br><span class="line">                    <span class="type">Object</span> <span class="variable">value</span> <span class="operator">=</span> oldDataMap.get(key);</span><br><span class="line">                    <span class="keyword">if</span> (!<span class="built_in">this</span>.isNull(value)) &#123;</span><br><span class="line">                        <span class="keyword">if</span> (propertyMap.containsKey(key) &amp;&amp; propertyMap.get(key) <span class="keyword">instanceof</span> SysDictExtendSubTableProperty) &#123;</span><br><span class="line">                            <span class="type">List</span>&lt;?&gt; <span class="variable">_values</span> <span class="operator">=</span> (List)value;</span><br><span class="line">                            <span class="type">HashMap</span>&lt;String, Object&gt; <span class="variable">_newMap</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">HashMap</span>();</span><br><span class="line">                            <span class="keyword">if</span> (newDataMap.containsKey(key + <span class="string">&quot;_index_&quot;</span>)) &#123;</span><br><span class="line">                                _newMap = (HashMap)newDataMap.get(key + <span class="string">&quot;_index_&quot;</span>);</span><br><span class="line">                            &#125;</span><br><span class="line"></span><br><span class="line">                            <span class="keyword">for</span>(<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; _values.size(); ++i) &#123;</span><br><span class="line">                                <span class="keyword">if</span> (_values.get(i) <span class="keyword">instanceof</span> HashMap) &#123;</span><br><span class="line">                                    <span class="type">HashMap</span>&lt;String, Object&gt; <span class="variable">_map</span> <span class="operator">=</span> (HashMap)_values.get(i);</span><br><span class="line"></span><br><span class="line">                                    <span class="keyword">for</span>(String _key : _newMap.keySet()) &#123;</span><br><span class="line">                                        <span class="keyword">if</span> (!_map.containsKey(_key)) &#123;</span><br><span class="line">                                            _map.put(_key, _newMap.get(_key));</span><br><span class="line">                                        &#125;</span><br><span class="line">                                    &#125;</span><br><span class="line">                                &#125;</span><br><span class="line">                            &#125;</span><br><span class="line"></span><br><span class="line">                            value = _values;</span><br><span class="line">                        &#125;</span><br><span class="line"></span><br><span class="line">                        <span class="built_in">this</span>.putDefaultValue(newDataMap, key);</span><br><span class="line">                        newDataMap.put(key, value);</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        newForm.getExtendDataFormInfo().setExtendFilePath(extendFilePath);</span><br><span class="line">        <span class="type">Map</span>&lt;String, Object&gt; <span class="variable">formData</span> <span class="operator">=</span> newForm.getExtendDataFormInfo().getFormData();</span><br><span class="line">        formData.putAll(newDataMap);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span>(String key : formData.keySet()) &#123;</span><br><span class="line">            <span class="keyword">if</span> (propertyMap.containsKey(key) &amp;&amp; propertyMap.get(key) <span class="keyword">instanceof</span> SysDictExtendSubTableProperty) &#123;</span><br><span class="line">                <span class="type">List</span>&lt;?&gt; <span class="variable">list</span> <span class="operator">=</span> (List)formData.get(key);</span><br><span class="line"></span><br><span class="line">                <span class="keyword">for</span>(<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; list.size(); ++i) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (list.get(i) <span class="keyword">instanceof</span> Map) &#123;</span><br><span class="line">                        ((Map)list.get(i)).put(<span class="string">&quot;fdId&quot;</span>, IDGenerator.generateID(System.currentTimeMillis() + (<span class="type">long</span>)i));</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="built_in">this</span>.removeEnumValue(formData, propertyMap, oldDataMap);</span><br><span class="line">        newForm.setAuthReaderIds(authReaderIds);</span><br><span class="line">        newForm.setAuthReaderNames(authReaderNames);</span><br><span class="line">        newForm.setAuthAttCopyIds(authAttCopyIds);</span><br><span class="line">        newForm.setAuthAttCopyNames(authAttCopyNames);</span><br><span class="line">        newForm.setAuthAttNocopy(authAttNoCopy);</span><br><span class="line">        newForm.setAuthAttDownloadIds(authAttDownloadIds);</span><br><span class="line">        newForm.setAuthAttDownloadNames(authAttDownloadNames);</span><br><span class="line">        newForm.setAuthAttNodownload(authAttNodownload);</span><br><span class="line">        newForm.setAuthAttPrintIds(authAttPrintIds);</span><br><span class="line">        newForm.setAuthAttPrintNames(authAttPrintNames);</span><br><span class="line">        newForm.setAuthAttNoprint(authAttNoprint);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/*add by 增加复制流程功能end*/</span></span><br><span class="line">    <span class="keyword">return</span> newForm;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="处理详细信息和封装的工具方法"><a href="#处理详细信息和封装的工具方法" class="headerlink" title="处理详细信息和封装的工具方法"></a>处理详细信息和封装的工具方法</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*add by 新增复制流程 start */</span></span><br><span class="line"><span class="keyword">private</span> <span class="type">void</span> <span class="title function_">setSubTableMap</span><span class="params">(Map&lt;String, Object&gt; oldDataMap, Map&lt;String, Object&gt; newDataMap, String key, SysDictExtendProperty extpro, String key_index)</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (oldDataMap.containsKey(key) &amp;&amp; oldDataMap.get(key) <span class="keyword">instanceof</span> ArrayList &amp;&amp; oldDataMap.containsKey(key_index) &amp;&amp; oldDataMap.get(key_index) <span class="keyword">instanceof</span> Map) &#123;</span><br><span class="line">        <span class="type">ArrayList</span> <span class="variable">subtableMapList</span> <span class="operator">=</span> (ArrayList)oldDataMap.get(key);</span><br><span class="line">        <span class="type">Map</span> <span class="variable">newSubtableMap</span> <span class="operator">=</span> (Map)newDataMap.get(key_index);</span><br><span class="line">        <span class="type">Map</span> <span class="variable">oldSubtableMap_index</span> <span class="operator">=</span> (Map)oldDataMap.get(key_index);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span>(Object subTableObj : subtableMapList) &#123;</span><br><span class="line">            <span class="keyword">if</span> (subTableObj <span class="keyword">instanceof</span> Map) &#123;</span><br><span class="line">                <span class="type">Map</span> <span class="variable">oldSubTableMap</span> <span class="operator">=</span> (Map)subTableObj;</span><br><span class="line">                <span class="built_in">this</span>.putDefaultValue(newSubtableMap, extpro.getName());</span><br><span class="line">                oldSubtableMap_index.put(extpro.getName(), newSubtableMap.get(extpro.getName()));</span><br><span class="line">                oldSubTableMap.put(extpro.getName(), newSubtableMap.get(extpro.getName()));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="type">void</span> <span class="title function_">setSubTableValue</span><span class="params">(Map&lt;String, SysDictCommonProperty&gt; propertyMap, Map&lt;String, Object&gt; oldDataMap, Map&lt;String, Object&gt; newDataMap, String key)</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (propertyMap.containsKey(key) &amp;&amp; propertyMap.get(key) <span class="keyword">instanceof</span> SysDictExtendSubTableProperty) &#123;</span><br><span class="line">        <span class="type">SysDictExtendSubTableProperty</span> <span class="variable">property</span> <span class="operator">=</span> (SysDictExtendSubTableProperty)propertyMap.get(key);</span><br><span class="line">        <span class="keyword">if</span> (property.getElementDictExtendModel() == <span class="literal">null</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="type">SysDictExtendModel</span> <span class="variable">model</span> <span class="operator">=</span> property.getElementDictExtendModel();</span><br><span class="line">        <span class="keyword">if</span> (model.getPropertyList() == <span class="literal">null</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span>(SysDictCommonProperty compro : model.getPropertyList()) &#123;</span><br><span class="line">            <span class="keyword">if</span> (compro <span class="keyword">instanceof</span> SysDictExtendElementProperty || compro <span class="keyword">instanceof</span> SysDictExtendSimpleProperty) &#123;</span><br><span class="line">                <span class="type">SysDictExtendProperty</span> <span class="variable">extpro</span> <span class="operator">=</span> (SysDictExtendProperty)compro;</span><br><span class="line">                <span class="type">String</span> <span class="variable">key_index</span> <span class="operator">=</span> key + <span class="string">&quot;_index_&quot;</span>;</span><br><span class="line">                <span class="keyword">if</span> (<span class="string">&quot;datetime&quot;</span>.equals(extpro.getBusinessType()) &amp;&amp; StringUtil.isNotNull(extpro.getDefaultValue())) &#123;</span><br><span class="line">                    <span class="built_in">this</span>.setSubTableMap(oldDataMap, newDataMap, key, extpro, key_index);</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="string">&quot;new_address&quot;</span>.equals(extpro.getBusinessType()) &amp;&amp; StringUtil.isNotNull(extpro.getDefaultValue())) &#123;</span><br><span class="line">                    <span class="built_in">this</span>.setSubTableMap(oldDataMap, newDataMap, key, extpro, key_index);</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="string">&quot;address&quot;</span>.equals(extpro.getBusinessType()) &amp;&amp; StringUtil.isNotNull(extpro.getDefaultValue())) &#123;</span><br><span class="line">                    <span class="built_in">this</span>.setSubTableMap(oldDataMap, newDataMap, key, extpro, key_index);</span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (oldDataMap.containsKey(key) &amp;&amp; oldDataMap.get(key) <span class="keyword">instanceof</span> ArrayList &amp;&amp; oldDataMap.containsKey(key_index) &amp;&amp; oldDataMap.get(key_index) <span class="keyword">instanceof</span> Map) &#123;</span><br><span class="line">                    <span class="type">ArrayList</span> <span class="variable">subtableMapList</span> <span class="operator">=</span> (ArrayList)oldDataMap.get(key);</span><br><span class="line">                    <span class="type">Map</span> <span class="variable">newSubtableMap</span> <span class="operator">=</span> (Map)newDataMap.get(key_index);</span><br><span class="line"></span><br><span class="line">                    <span class="keyword">for</span>(Object subTableObj : subtableMapList) &#123;</span><br><span class="line">                        <span class="keyword">if</span> (subTableObj <span class="keyword">instanceof</span> Map) &#123;</span><br><span class="line">                            <span class="built_in">this</span>.putDefaultValue(newSubtableMap, extpro.getName());</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="type">void</span> <span class="title function_">removeEnumValue</span><span class="params">(Map&lt;String, Object&gt; formData, Map&lt;String, SysDictCommonProperty&gt; propertyMap, Map&lt;String, Object&gt; oldDataMap)</span> &#123;</span><br><span class="line">    <span class="keyword">for</span>(Object key : <span class="keyword">new</span> <span class="title class_">ArrayList</span>(formData.keySet())) &#123;</span><br><span class="line">        <span class="keyword">if</span> (propertyMap.containsKey(key) &amp;&amp; propertyMap.get(key) <span class="keyword">instanceof</span> SysDictExtendSubTableProperty) &#123;</span><br><span class="line">            <span class="type">SysDictExtendSubTableProperty</span> <span class="variable">property</span> <span class="operator">=</span> (SysDictExtendSubTableProperty)propertyMap.get(key);</span><br><span class="line">            <span class="keyword">if</span> (property.getElementDictExtendModel() != <span class="literal">null</span>) &#123;</span><br><span class="line">                <span class="type">SysDictExtendModel</span> <span class="variable">model</span> <span class="operator">=</span> property.getElementDictExtendModel();</span><br><span class="line">                <span class="keyword">if</span> (model.getPropertyList() != <span class="literal">null</span>) &#123;</span><br><span class="line">                    <span class="type">Map</span>&lt;String, SysDictCommonProperty&gt; <span class="variable">subPropertyMap</span> <span class="operator">=</span> model.getPropertyMap();</span><br><span class="line"></span><br><span class="line">                    <span class="keyword">for</span>(Object o : (ArrayList)formData.get(key)) &#123;</span><br><span class="line">                        <span class="type">HashMap</span>&lt;String, Object&gt; <span class="variable">hashMap</span> <span class="operator">=</span> (HashMap)o;</span><br><span class="line">                        <span class="type">Iterator</span>&lt;String&gt; <span class="variable">iterator</span> <span class="operator">=</span> hashMap.keySet().iterator();</span><br><span class="line"></span><br><span class="line">                        <span class="keyword">while</span>(iterator.hasNext()) &#123;</span><br><span class="line">                            <span class="type">String</span> <span class="variable">subKey</span> <span class="operator">=</span> (String)iterator.next();</span><br><span class="line">                            <span class="keyword">if</span> (subPropertyMap.containsKey(subKey) &amp;&amp; (subPropertyMap.get(subKey) <span class="keyword">instanceof</span> SysDictExtendElementProperty || subPropertyMap.get(subKey) <span class="keyword">instanceof</span> SysDictExtendSimpleProperty)) &#123;</span><br><span class="line">                                <span class="type">SysDictExtendProperty</span> <span class="variable">subProperty</span> <span class="operator">=</span> (SysDictExtendProperty)subPropertyMap.get(subKey);</span><br><span class="line">                                <span class="keyword">if</span> (StringUtil.isNotNull(subProperty.getEnumValues())) &#123;</span><br><span class="line">                                    <span class="type">String</span>[] <span class="variable">enumValues</span> <span class="operator">=</span> subProperty.getEnumValues().split(<span class="string">&quot;;&quot;</span>);</span><br><span class="line">                                    <span class="type">String</span> <span class="variable">oldVal</span> <span class="operator">=</span> hashMap.get(subKey).toString();</span><br><span class="line">                                    oldVal = StringUtil.XMLUnEscape(oldVal);</span><br><span class="line">                                    <span class="type">String</span>[] <span class="variable">olds</span> <span class="operator">=</span> oldVal.split(<span class="string">&quot;;&quot;</span>);</span><br><span class="line">                                    <span class="type">List</span>&lt;String&gt; <span class="variable">list</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span>();</span><br><span class="line"></span><br><span class="line">                                    <span class="keyword">for</span>(String enumValue : enumValues) &#123;</span><br><span class="line">                                        <span class="type">String</span>[] <span class="variable">values</span> <span class="operator">=</span> enumValue.split(<span class="string">&quot;\\|&quot;</span>);</span><br><span class="line">                                        <span class="keyword">if</span> (values.length == <span class="number">2</span>) &#123;</span><br><span class="line">                                            list.add(values[<span class="number">1</span>]);</span><br><span class="line">                                        &#125;</span><br><span class="line">                                    &#125;</span><br><span class="line"></span><br><span class="line">                                    <span class="type">boolean</span> <span class="variable">isHave</span> <span class="operator">=</span> <span class="literal">true</span>;</span><br><span class="line"></span><br><span class="line">                                    <span class="keyword">for</span>(String old : olds) &#123;</span><br><span class="line">                                        <span class="keyword">if</span> (!list.contains(old)) &#123;</span><br><span class="line">                                            isHave = <span class="literal">false</span>;</span><br><span class="line">                                            <span class="keyword">break</span>;</span><br><span class="line">                                        &#125;</span><br><span class="line">                                    &#125;</span><br><span class="line"></span><br><span class="line">                                    <span class="keyword">if</span> (!isHave) &#123;</span><br><span class="line">                                        iterator.remove();</span><br><span class="line">                                    &#125;</span><br><span class="line">                                &#125;</span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (propertyMap.containsKey(key) &amp;&amp; (propertyMap.get(key) <span class="keyword">instanceof</span> SysDictExtendElementProperty || propertyMap.get(key) <span class="keyword">instanceof</span> SysDictExtendSimpleProperty)) &#123;</span><br><span class="line">            <span class="type">SysDictExtendProperty</span> <span class="variable">property</span> <span class="operator">=</span> (SysDictExtendProperty)propertyMap.get(key);</span><br><span class="line">            <span class="keyword">if</span> (StringUtil.isNotNull(property.getEnumValues())) &#123;</span><br><span class="line">                <span class="type">String</span>[] <span class="variable">enumValues</span> <span class="operator">=</span> property.getEnumValues().split(<span class="string">&quot;;&quot;</span>);</span><br><span class="line">                <span class="type">boolean</span> <span class="variable">isHave</span> <span class="operator">=</span> <span class="literal">true</span>;</span><br><span class="line">                <span class="type">List</span>&lt;String&gt; <span class="variable">list</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span>();</span><br><span class="line"></span><br><span class="line">                <span class="keyword">for</span>(String enumValue : enumValues) &#123;</span><br><span class="line">                    <span class="type">String</span>[] <span class="variable">values</span> <span class="operator">=</span> enumValue.split(<span class="string">&quot;\\|&quot;</span>);</span><br><span class="line">                    <span class="keyword">if</span> (values.length == <span class="number">2</span>) &#123;</span><br><span class="line">                        list.add(values[<span class="number">1</span>]);</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="type">String</span> <span class="variable">oldVal</span> <span class="operator">=</span> formData.get(key).toString();</span><br><span class="line">                oldVal = StringUtil.XMLUnEscape(oldVal);</span><br><span class="line">                <span class="type">String</span>[] <span class="variable">split</span> <span class="operator">=</span> oldVal.split(<span class="string">&quot;;&quot;</span>);</span><br><span class="line"></span><br><span class="line">                <span class="keyword">for</span>(String old : split) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (!list.contains(old)) &#123;</span><br><span class="line">                        isHave = <span class="literal">false</span>;</span><br><span class="line">                        <span class="keyword">break</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                <span class="keyword">if</span> (!isHave) &#123;</span><br><span class="line">                    formData.remove(key);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="type">boolean</span> <span class="title function_">isNull</span><span class="params">(Object obj)</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (obj == <span class="literal">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (obj <span class="keyword">instanceof</span> String) &#123;</span><br><span class="line">        <span class="keyword">return</span> StringUtil.isNull((String)obj);</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (obj <span class="keyword">instanceof</span> Collection) &#123;</span><br><span class="line">        <span class="keyword">return</span> ((Collection)obj).size() == <span class="number">0</span>;</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (obj <span class="keyword">instanceof</span> Map) &#123;</span><br><span class="line">        <span class="keyword">return</span> ((Map)obj).size() == <span class="number">0</span>;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="type">void</span> <span class="title function_">putDefaultValue</span><span class="params">(Map&lt;String, Object&gt; newDataMap, String key)</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (newDataMap.get(key) != <span class="literal">null</span>) &#123;</span><br><span class="line">        newDataMap.put(key + <span class="string">&quot;_NoCopy&quot;</span>, newDataMap.get(key));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="type">boolean</span> <span class="title function_">isNotCopy</span><span class="params">(Map&lt;String, SysDictCommonProperty&gt; propertyMap, String key)</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (propertyMap.containsKey(key) &amp;&amp; (propertyMap.get(key) <span class="keyword">instanceof</span> SysDictExtendElementProperty || propertyMap.get(key) <span class="keyword">instanceof</span> SysDictExtendSimpleProperty)) &#123;</span><br><span class="line">        <span class="type">SysDictExtendProperty</span> <span class="variable">property</span> <span class="operator">=</span> (SysDictExtendProperty)propertyMap.get(key);</span><br><span class="line">        <span class="keyword">if</span> (<span class="string">&quot;datetime&quot;</span>.equals(property.getBusinessType()) &amp;&amp; StringUtil.isNotNull(property.getDefaultValue())) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (<span class="string">&quot;new_address&quot;</span>.equals(property.getBusinessType()) &amp;&amp; StringUtil.isNotNull(property.getDefaultValue())) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (<span class="string">&quot;address&quot;</span>.equals(property.getBusinessType()) &amp;&amp; StringUtil.isNotNull(property.getDefaultValue())) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="type">String</span> <span class="title function_">checkTemplateUpdate</span><span class="params">(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, Map&lt;String, Object&gt; newDataMap)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    ((IFsscInvoicePayableService) getServiceImp(request)).initFormSetting((IExtendForm)form, <span class="keyword">new</span> <span class="title class_">RequestContext</span>(request));</span><br><span class="line">    <span class="type">FsscInvoicePayableForm</span> <span class="variable">newForm</span> <span class="operator">=</span> (FsscInvoicePayableForm)form;</span><br><span class="line">    <span class="type">String</span> <span class="variable">invoiceId</span> <span class="operator">=</span> request.getParameter(<span class="string">&quot;invoiceId&quot;</span>);</span><br><span class="line">    <span class="type">FsscInvoicePayableForm</span> <span class="variable">copyForm</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">    <span class="type">FsscInvoicePayable</span> <span class="variable">fsscInvoicePayable</span> <span class="operator">=</span> (FsscInvoicePayable)<span class="built_in">this</span>.getServiceImp(request).findByPrimaryKey(invoiceId);</span><br><span class="line">    <span class="keyword">if</span> (fsscInvoicePayable != <span class="literal">null</span>) &#123;</span><br><span class="line">        copyForm = (FsscInvoicePayableForm)<span class="built_in">this</span>.getServiceImp(request).convertModelToForm(<span class="keyword">new</span> <span class="title class_">FsscInvoicePayableForm</span>(), fsscInvoicePayable, <span class="keyword">new</span> <span class="title class_">RequestContext</span>());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (newDataMap != <span class="literal">null</span>) &#123;</span><br><span class="line">        newDataMap.putAll(newForm.getExtendDataFormInfo().getFormData());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">this</span>.isUpdate(newForm, copyForm);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="type">String</span> <span class="title function_">isUpdate</span><span class="params">(FsscInvoicePayableForm newForm, FsscInvoicePayableForm copyForm)</span> &#123;</span><br><span class="line">    <span class="type">String</span> <span class="variable">isUpdate</span> <span class="operator">=</span> <span class="string">&quot;false&quot;</span>;</span><br><span class="line">    <span class="type">String</span> <span class="variable">newFilePath</span> <span class="operator">=</span> newForm.getExtendDataFormInfo().getExtendFilePath();</span><br><span class="line">    <span class="type">String</span> <span class="variable">copyFilePath</span> <span class="operator">=</span> copyForm.getExtendDataFormInfo().getExtendFilePath();</span><br><span class="line">    <span class="keyword">if</span> (StringUtil.isNotNull(newFilePath)) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!newFilePath.equals(copyFilePath)) &#123;</span><br><span class="line">            isUpdate = <span class="string">&quot;true&quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (StringUtil.isNotNull(copyFilePath)) &#123;</span><br><span class="line">        isUpdate = <span class="string">&quot;true&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> isUpdate;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="type">void</span> <span class="title function_">checkTemplate</span><span class="params">(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">    response.getWriter().print(<span class="built_in">this</span>.checkTemplateUpdate(mapping, form, request, response, (Map)<span class="literal">null</span>));</span><br><span class="line">    response.getWriter().flush();</span><br><span class="line">    response.getWriter().close();</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">/*add by 新增复制流程 end */</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;项目来源-SPRJ202509171552-SCAJ&quot;&gt;&lt;a href=&quot;#项目来源-SPRJ202509171552-SCAJ&quot; class=&quot;headerlink&quot; title=&quot;项目来源 SPRJ202509171552_SCAJ&quot;&gt;&lt;/a&gt;项目来源 &lt;co</summary>
      
    
    
    
    <category term="📕小敏の手札" scheme="https://xmblog.chrislin.eu.org/categories/%F0%9F%93%95%E5%B0%8F%E6%95%8F%E3%81%AE%E6%89%8B%E6%9C%AD/"/>
    
    
    <category term="🅔晚风のEKP" scheme="https://xmblog.chrislin.eu.org/tags/%F0%9F%85%94%E6%99%9A%E9%A3%8E%E3%81%AEEKP/"/>
    
  </entry>
  
  <entry>
    <title>网站迁移【CloudFlare Pages】</title>
    <link href="https://xmblog.chrislin.eu.org/posts/20260306061946.html"/>
    <id>https://xmblog.chrislin.eu.org/posts/20260306061946.html</id>
    <published>2026-03-06T06:19:46.000Z</published>
    <updated>2026-11-10T13:02:16.260Z</updated>
    
    <content type="html"><![CDATA[<h2 id="关于本项目迁移到CloudFlare-Pages上的注意事项："><a href="#关于本项目迁移到CloudFlare-Pages上的注意事项：" class="headerlink" title="关于本项目迁移到CloudFlare Pages上的注意事项："></a>关于本项目迁移到<code>CloudFlare Pages</code>上的注意事项：</h2><h2 id="两种方式"><a href="#两种方式" class="headerlink" title="两种方式"></a>两种方式</h2><ol><li><h3 id="GitHub"><a href="#GitHub" class="headerlink" title="GitHub"></a><code>GitHub</code></h3><ol><li><p>关联<code>github</code>授权仓库</p></li><li><p>选择项目</p></li><li><p>构建命令如果跟我一样是<code>yarn</code>,可以参考构建命令</p></li><li><pre><code class="language-bash">yarn install --refresh-lockfile &amp;&amp; yarn hexo clean &amp;&amp; yarn hexo generate</code></pre></li><li><p>等待构建部署</p></li></ol></li><li><h3 id="上传产物"><a href="#上传产物" class="headerlink" title="上传产物"></a>上传产物</h3><ol><li>直接命名一个项目名称</li><li>上传本地项目构建的静态文件</li><li>等待发布就行</li></ol></li></ol><h2 id="pretty-url"><a href="#pretty-url" class="headerlink" title="pretty url"></a><code>pretty url</code></h2><ol><li><h3 id="它会自动把网站末尾带-html的地址自动去掉-html来美化显示"><a href="#它会自动把网站末尾带-html的地址自动去掉-html来美化显示" class="headerlink" title="它会自动把网站末尾带.html的地址自动去掉.html来美化显示"></a>它会自动把网站末尾带<code>.html</code>的地址自动去掉<code>.html</code>来美化显示</h3></li><li><h3 id="个人感觉部分场景下并不友好，例如我的评论区"><a href="#个人感觉部分场景下并不友好，例如我的评论区" class="headerlink" title="个人感觉部分场景下并不友好，例如我的评论区"></a>个人感觉部分场景下并不友好，例如我的评论区</h3></li></ol><h2 id="本站的评论区"><a href="#本站的评论区" class="headerlink" title="本站的评论区"></a>本站的评论区</h2><ol><li>由于美化了我的<code>url</code>导致我以前的评论都会不显示，但是统计总数却还是带<code>.html</code>统计的</li><li>我的文章生成规则是<code>permalink: posts/:year:month:day:hour:minute:second.html</code></li><li>其他问题再看情况吧</li><li>还好评论的人不多！！！</li></ol><p>只希望哪一天<code>CloudFlare Pages</code>官方能允许这块支持自定义吧，<strong>一个开关就行</strong></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;关于本项目迁移到CloudFlare-Pages上的注意事项：&quot;&gt;&lt;a href=&quot;#关于本项目迁移到CloudFlare-Pages上的注意事项：&quot; class=&quot;headerlink&quot; title=&quot;关于本项目迁移到CloudFlare Pages上的注意事项</summary>
      
    
    
    
    <category term="📕小敏の手札" scheme="https://xmblog.chrislin.eu.org/categories/%F0%9F%93%95%E5%B0%8F%E6%95%8F%E3%81%AE%E6%89%8B%E6%9C%AD/"/>
    
    
    <category term="⭐晚风の星匣" scheme="https://xmblog.chrislin.eu.org/tags/%E2%AD%90%E6%99%9A%E9%A3%8E%E3%81%AE%E6%98%9F%E5%8C%A3/"/>
    
  </entry>
  
  <entry>
    <title>Windows搭建RabbitMQ和Erlang环境（zip安装）</title>
    <link href="https://xmblog.chrislin.eu.org/posts/20251217080314.html"/>
    <id>https://xmblog.chrislin.eu.org/posts/20251217080314.html</id>
    <published>2025-12-17T08:03:14.000Z</published>
    <updated>2026-11-10T13:02:16.260Z</updated>
    
    <content type="html"><![CDATA[<h1 id="版本说明"><a href="#版本说明" class="headerlink" title="版本说明"></a>版本说明</h1><p>安装 <code>Erlang</code> 时要注意安装的<code>RabbitMQ</code>所依赖的<code>Erlang</code>版本，这里以我安装的来进行说明：</p><ul><li><p><code>Erlang</code>：<a href="https://www.erlang.org/patches/otp-27.3.4.2"><code>27.3.4.2</code></a>、<a href="https://github.com/erlang/otp/releases/download/OTP-27.3.4.2/otp_win64_27.3.4.2.zip"><code>GitHub zip</code>下载链接</a></p></li><li><p><code>RabbitMQ</code>：<code>4.1.2</code>、<a href="https://github.com/rabbitmq/rabbitmq-server/releases/download/v4.1.2/rabbitmq-server-windows-4.1.2.zip"><code>GitHub zip</code>下载链接</a>、<a href="https://www.rabbitmq.com/docs/install-windows">官网<code>windows</code>最新下载页</a></p></li></ul><p>以上是我提供的我的版本和下载链接，<code>RabbitMQ</code>历史版本可以到<code>github</code>上下载，除此之外，也可以参考版本对比安装最新版本</p><p>通往<code>RabbitMQ</code>和<code>Erlang/OPT</code>兼容性矩阵：<a href="https://rabbitmq.org.cn/docs/which-erlang#compatibility-matrix"><code>Erlang</code> 版本要求 | <code>RabbitMQ</code> 消息队列</a> </p><img src="https://img.chrislin.eu.org/2025/12/30fdc6e4894e0908eecb5add91c0d73c.webp" alt="image-20251217174520480" style="width: 650px;" /><h1 id="安装-Erlang"><a href="#安装-Erlang" class="headerlink" title="安装 Erlang"></a>安装 <code>Erlang</code></h1><h2 id="解压"><a href="#解压" class="headerlink" title="解压"></a>解压</h2><p>下载zip格式版本后解压到自定义位置（例如我的<code>D:\SoftWare\Erlang</code>）</p><img src="https://img.chrislin.eu.org/2025/12/9b61d8673ee030f4293e67ec0d300e11.webp" alt="image-20251217211619283" style="width: 650px;" /><h2 id="配置环境变量-ERLANG-HOME"><a href="#配置环境变量-ERLANG-HOME" class="headerlink" title="配置环境变量 ERLANG_HOME"></a>配置环境变量 <code>ERLANG_HOME</code></h2><img src="https://img.chrislin.eu.org/2025/12/6c92bd0ce4e6d4125f7e47cde0c03fb3.webp" alt="image-20251217211748086" style="width: 650px;" /><h2 id="验证"><a href="#验证" class="headerlink" title="验证"></a>验证</h2><p>（<strong><a href="#%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F-Path"><code>Path</code> 需要添加变量</a></strong>）运行命令 <code>erl</code>出现以下便是配置成功了</p><img src="https://img.chrislin.eu.org/2025/12/9def7b319bd1a2385bcc9ba85e58cf54.webp" alt="image-20251217212446646" style="width: 650px;" /><h1 id="安装-RabbitMQ"><a href="#安装-RabbitMQ" class="headerlink" title="安装 RabbitMQ"></a>安装 <code>RabbitMQ</code></h1><h2 id="解压-1"><a href="#解压-1" class="headerlink" title="解压"></a>解压</h2><p>下载zip格式版本后解压到自定义位置（例如我的<code>D:\SoftWare\RabbitMQ</code>）</p><img src="https://img.chrislin.eu.org/2025/12/2df8546790c617585515499a5b14c9b8.webp" alt="image-20251217213246235" style="width: 650px;" /><h2 id="配置环境变量-RABBITMQ-SERVER-HOME"><a href="#配置环境变量-RABBITMQ-SERVER-HOME" class="headerlink" title="配置环境变量 RABBITMQ_SERVER_HOME"></a>配置环境变量 <code>RABBITMQ_SERVER_HOME</code></h2><img src="https://img.chrislin.eu.org/2025/12/75d484fa969d9dbe2ccb8a5ae7073624.webp" alt="image-20251217211815992" style="width: 650px;" /><h2 id="验证-1"><a href="#验证-1" class="headerlink" title="验证"></a>验证</h2><p>（<strong><a href="#%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F-Path"><code>Path</code> 需要添加变量</a></strong>）运行以下命令，若提示没有那就是环境变量配置不正确，若要验证环境变量是否配置正确可以先执行以下<code>rabbitmq-plugins</code></p><img src="https://img.chrislin.eu.org/2025/12/20d7074271e44b3e20c7a8ffb782ad52.webp" alt="image-20251217213914962" style="width: 650px" /><p>命令建议使用管理员权限执行，否则可能报错</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">安装管理插件</span></span><br><span class="line">rabbitmq-plugins enable rabbitmq_management </span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">服务的安装</span></span><br><span class="line">rabbitmq-service install</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">其他操作</span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">启动/停止</span></span><br><span class="line">rabbitmq-service start</span><br><span class="line">rabbitmq-service stop</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">状态</span></span><br><span class="line">rabbitmqctl status</span><br></pre></td></tr></table></figure><p>服务安装完成，在服务中会出现<code>RabbitMQ</code>服务</p><img src="https://img.chrislin.eu.org/2025/12/ef48cd041bf9eb09083b968ed3e213d6.webp" alt="image-20251217221844561" style="width: 650px" /><h1 id="环境变量-Path"><a href="#环境变量-Path" class="headerlink" title="环境变量 Path"></a>环境变量 <code>Path</code></h1><p>环境变量 <code>Path</code> 中添加以下两个变量 <code>%ERLANG_HOME%\bin</code>、<code>%RABBITMQ_SERVER_HOME%\sbin</code></p><img src="https://img.chrislin.eu.org/2025/12/d3aa8bcf1411a03aec2c958d2f71e892.webp" alt="image-20251217212047376" style="width: 650px" /><h1 id="访问"><a href="#访问" class="headerlink" title="访问"></a>访问</h1><p>（服务已启动）访问<code>http://localhost:15672</code> 账号密码 <code>guest/guest</code></p><img src="https://img.chrislin.eu.org/2025/12/a8d33ff08a1c6d301b280f7680c0d6d8.webp" alt="image-20251217214802394" style="width: 650px;" /><p>出现登录页就基本完成了，这是登陆后的样子</p><img src="https://img.chrislin.eu.org/2025/12/46d463192c3c31e33adb55e527bf9baa.webp" alt="image-20251217214937345" style="width: 650px;" />]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;版本说明&quot;&gt;&lt;a href=&quot;#版本说明&quot; class=&quot;headerlink&quot; title=&quot;版本说明&quot;&gt;&lt;/a&gt;版本说明&lt;/h1&gt;&lt;p&gt;安装 &lt;code&gt;Erlang&lt;/code&gt; 时要注意安装的&lt;code&gt;RabbitMQ&lt;/code&gt;所依赖的&lt;code&gt;E</summary>
      
    
    
    
    <category term="📕小敏の手札" scheme="https://xmblog.chrislin.eu.org/categories/%F0%9F%93%95%E5%B0%8F%E6%95%8F%E3%81%AE%E6%89%8B%E6%9C%AD/"/>
    
    
    <category term="⭐晚风の星匣" scheme="https://xmblog.chrislin.eu.org/tags/%E2%AD%90%E6%99%9A%E9%A3%8E%E3%81%AE%E6%98%9F%E5%8C%A3/"/>
    
  </entry>
  
  <entry>
    <title>Java 对象映射与 Map 处理实用方案（注解式 + KV 式 + 扁平化工具）</title>
    <link href="https://xmblog.chrislin.eu.org/posts/20251201064814.html"/>
    <id>https://xmblog.chrislin.eu.org/posts/20251201064814.html</id>
    <published>2025-12-01T06:48:14.000Z</published>
    <updated>2026-11-10T13:02:16.260Z</updated>
    
    <content type="html"><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>本文提供三种 <code>Java</code> 数据处理核心方案，涵盖对象与 <code>Map</code> 的双向映射及复杂 <code>Map</code> 结构扁平化，适用于接口参数转换、数据同步、跨系统数据传输等场景：</p><ul><li>注解式映射（推荐）：通过自定义注解标记字段映射关系，侵入性低、配置直观，适配复杂嵌套对象</li><li><code>KV</code> 配置式映射：基于 <code>Hutool</code> 工具类，通过 <code>Map</code> 配置字段对应关系，适合简单对象快速转换</li><li><code>Map</code> 扁平化工具：将嵌套 <code>Map/List</code> 结构转为单层键值对，适配 <code>URL</code> 参数拼接、简单配置输出等场景</li></ul><p>其中注解式映射因无需额外配置类、可读性强、支持多层嵌套，更推荐作为优先方案。</p><h1 id="方案一：注解式对象-Map-映射（推荐）"><a href="#方案一：注解式对象-Map-映射（推荐）" class="headerlink" title="方案一：注解式对象 - Map 映射（推荐）"></a>方案一：注解式对象 - <code>Map</code> 映射（推荐）</h1><p>通过自定义 <code>@Table</code> 和 <code>@Table.Col</code> 注解，直接在 <code>JavaBean</code> 字段上标记目标映射键名，配合工具类实现对象与 <code>Map</code> 的双向递归转换，适配含嵌套对象、集合的复杂场景。</p><h2 id="核心注解定义（-Table-Table-Col）"><a href="#核心注解定义（-Table-Table-Col）" class="headerlink" title="核心注解定义（@Table + @Table.Col）"></a>核心注解定义（<code>@Table</code> + <code>@Table.Col</code>）</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.landray.kmss.shunan.travel.annotations;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.lang.annotation.*;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 类级注解：标记该类支持字段映射功能（用于对象-Map双向转换）</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Target(ElementType.TYPE)</span></span><br><span class="line"><span class="meta">@Retention(RetentionPolicy.RUNTIME)</span></span><br><span class="line"><span class="keyword">public</span> <span class="meta">@interface</span> Table &#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 字段级注解：指定当前字段对应的目标键名（支持数据库列名、接口参数名等场景）</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Target(ElementType.FIELD)</span></span><br><span class="line">    <span class="meta">@Retention(RetentionPolicy.RUNTIME)</span></span><br><span class="line">    <span class="meta">@interface</span> Col &#123;</span><br><span class="line">        <span class="type">String</span> <span class="title function_">value</span><span class="params">()</span>;   <span class="comment">// 目标映射键名（如接口参数名、数据库列名）</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="注解使用示例（出差申请单数据模型）"><a href="#注解使用示例（出差申请单数据模型）" class="headerlink" title="注解使用示例（出差申请单数据模型）"></a>注解使用示例（出差申请单数据模型）</h2><p>以出差申请单同步接口的请求参数模型为例，通过注解标记每个字段对应的目标键名，支持嵌套对象（如<code>SuperiorDepartment</code>）、集合（如<code>List&lt;PassengerDetail&gt;</code>）的多层映射：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.landray.kmss.shunan.travel.sync.data;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.landray.kmss.shunan.travel.annotations.Table;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 出差申请单同步接口（FCAPPLY_OUTAPI_TripModify）的请求参数数据类</span></span><br><span class="line"><span class="comment"> * 注：仅标注文档明确标“Y”的必填项，非标注项按文档描述为准</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Table</span> <span class="comment">// 类级注解：标记该类支持映射转换</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">TripApplyData</span> &#123;</span><br><span class="line">    <span class="comment">// ====================== 文档明确标注“Y”的显式必填项 ======================</span></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 出差申请单号，必填（文档明确标“Y”）</span></span><br><span class="line"><span class="comment">     * 对应外系统申请单号</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Table</span>.Col(<span class="string">&quot;fd_approval_number&quot;</span>) <span class="comment">// 字段级注解：映射目标键名</span></span><br><span class="line">    <span class="keyword">private</span> String approvalNumber;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 操作类型，必填（文档明确标“Y”）</span></span><br><span class="line"><span class="comment">     * 枚举：0=更新，1=新增，2=作废，3=修改状态，4=校验是否行程重复</span></span><br><span class="line"><span class="comment">     * 默认值：0</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Table</span>.Col(<span class="string">&quot;fd_op_code&quot;</span>)</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> <span class="variable">opCode</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// ... 中间字段省略（保持原代码结构） ...</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 上级部门集合，非必填（文档标“N”）</span></span><br><span class="line"><span class="comment">     * 元素类型：SuperiorDepartment（上级部门信息）- 嵌套对象同样支持注解映射</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Table</span>.Col(<span class="string">&quot;fd_superior_depart_list&quot;</span>)</span><br><span class="line">    <span class="keyword">private</span> List&lt;SuperiorDepartment&gt; superiorDepartList;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// ====================== 嵌套内部类（均支持注解映射） ======================</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 上级部门信息（对应superiorDepartList）</span></span><br><span class="line"><span class="comment">     * 注：所有字段均为非必填（文档标“N”）</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Table</span> <span class="comment">// 嵌套类同样需要添加@Table注解</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">class</span> <span class="title class_">SuperiorDepartment</span> &#123;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 上级部门编号，非必填（文档标“N”）</span></span><br><span class="line"><span class="comment">         * 说明：按顺序传入，顶级部门位于第一个</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="meta">@Table</span>.Col(<span class="string">&quot;fd_dept_id&quot;</span>)</span><br><span class="line">        <span class="keyword">private</span> String deptId;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// ... 其他字段及getter/setter省略 ...</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 出行人详情（对应passengerList）</span></span><br><span class="line"><span class="comment">     * 注：仅标注文档明确“Y”的必填项</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Table</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">class</span> <span class="title class_">PassengerDetail</span> &#123;</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 姓名，必填（文档明确标“Y”）</span></span><br><span class="line"><span class="comment">         * 支持：数字、大小写字母、中文、右斜杠/、空格</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        <span class="meta">@Table</span>.Col(<span class="string">&quot;fd_name&quot;</span>)</span><br><span class="line">        <span class="keyword">private</span> String name;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// ... 其他字段及getter/setter省略 ...</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// ... 其他内部类及全局getter/setter省略 ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="注解映射核心工具类（BeanMapMapper）"><a href="#注解映射核心工具类（BeanMapMapper）" class="headerlink" title="注解映射核心工具类（BeanMapMapper）"></a>注解映射核心工具类（<code>BeanMapMapper</code>）</h2><p>基于 <code>Hutool</code> 反射工具实现，支持：</p><ul><li>对象 → <code>Map</code>：递归转换嵌套对象、集合（集合元素需标注<code>@Table</code>）</li><li><code>Map</code> → 对象：根据映射关系反向构建对象，自动处理嵌套结构和集合类型</li><li>空值过滤：忽略值为 <code>null</code> 的字段，避免无效数据传输</li></ul><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.landray.kmss.shunan.travel.util;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> cn.hutool.core.util.ObjUtil;</span><br><span class="line"><span class="keyword">import</span> cn.hutool.core.util.ReflectUtil;</span><br><span class="line"><span class="keyword">import</span> com.landray.kmss.shunan.travel.annotations.Table;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.lang.reflect.Field;</span><br><span class="line"><span class="keyword">import</span> java.lang.reflect.ParameterizedType;</span><br><span class="line"><span class="keyword">import</span> java.lang.reflect.Type;</span><br><span class="line"><span class="keyword">import</span> java.util.*;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 注解式对象-Map双向转换工具类</span></span><br><span class="line"><span class="comment"> * 依赖：Hutool反射工具（ReflectUtil）、空值判断工具（ObjUtil）</span></span><br><span class="line"><span class="comment"> * 核心功能：基于<span class="doctag">@Table</span>和<span class="doctag">@Table</span>.Col注解，实现复杂对象与Map的递归转换</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">final</span> <span class="keyword">class</span> <span class="title class_">BeanMapMapper</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 私有构造器：禁止实例化工具类</span></span><br><span class="line">    <span class="type">private</span> <span class="title function_">BeanMapMapper</span><span class="params">()</span> &#123;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* ==================== 1. 实体对象 → Map（支持嵌套/集合） ==================== */</span></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 将标注<span class="doctag">@Table</span>的实体对象转为Map，字段名对应<span class="doctag">@Table</span>.Col的value值</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> bean 待转换的实体对象（必须标注<span class="doctag">@Table</span>注解）</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> 转换后的Map（空对象/未标注注解返回null）</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">Map</span>&lt;String, Object&gt; <span class="title function_">toMap</span><span class="params">(Object bean)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (ObjUtil.isNull(bean)) <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="type">Class</span>&lt;?&gt; <span class="variable">clazz</span> <span class="operator">=</span> bean.getClass();</span><br><span class="line">        <span class="keyword">if</span> (!clazz.isAnnotationPresent(Table.class)) <span class="keyword">return</span> <span class="literal">null</span>; <span class="comment">// 未标注@Table直接返回null</span></span><br><span class="line"></span><br><span class="line">        <span class="type">Map</span>&lt;String, Object&gt; <span class="variable">map</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">LinkedHashMap</span>&lt;&gt;(); <span class="comment">// 保持字段顺序</span></span><br><span class="line">        <span class="type">Field</span>[] <span class="variable">fields</span> <span class="operator">=</span> ReflectUtil.getFields(clazz); <span class="comment">// 获取所有字段（含私有）</span></span><br><span class="line">        <span class="keyword">for</span> (Field f : fields) &#123;</span><br><span class="line">            Table.<span class="type">Col</span> <span class="variable">col</span> <span class="operator">=</span> f.getAnnotation(Table.Col.class);</span><br><span class="line">            <span class="keyword">if</span> (ObjUtil.isNull(col)) <span class="keyword">continue</span>; <span class="comment">// 未标注@Table.Col的字段忽略</span></span><br><span class="line">            <span class="type">Object</span> <span class="variable">val</span> <span class="operator">=</span> ReflectUtil.getFieldValue(bean, f);</span><br><span class="line">            <span class="keyword">if</span> (ObjUtil.isNull(val)) <span class="keyword">continue</span>; <span class="comment">// 空值字段忽略</span></span><br><span class="line"></span><br><span class="line">            <span class="comment">// 处理集合类型（List/Set）：递归转换集合中的@Table标注对象</span></span><br><span class="line">            <span class="keyword">if</span> (Collection.class.isAssignableFrom(f.getType())) &#123;</span><br><span class="line">                <span class="type">Type</span> <span class="variable">generic</span> <span class="operator">=</span> f.getGenericType();</span><br><span class="line">                <span class="keyword">if</span> (generic <span class="keyword">instanceof</span> ParameterizedType) &#123;</span><br><span class="line">                    <span class="type">ParameterizedType</span> <span class="variable">pt</span> <span class="operator">=</span> (ParameterizedType) generic;</span><br><span class="line">                    <span class="type">Class</span>&lt;?&gt; <span class="variable">actual</span> <span class="operator">=</span> (Class&lt;?&gt;) pt.getActualTypeArguments()[<span class="number">0</span>];</span><br><span class="line">                    <span class="keyword">if</span> (actual.isAnnotationPresent(Table.class)) &#123; <span class="comment">// 集合元素是标注@Table的对象</span></span><br><span class="line">                        <span class="type">List</span>&lt;Map&lt;String, Object&gt;&gt; <span class="variable">list</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">                        <span class="keyword">for</span> (Object item : (Collection&lt;?&gt;) val) list.add(toMap(item));</span><br><span class="line">                        map.put(col.value(), list);</span><br><span class="line">                        <span class="keyword">continue</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 处理嵌套对象：递归转换标注@Table的字段</span></span><br><span class="line">            <span class="keyword">if</span> (f.getType().isAnnotationPresent(Table.class)) &#123;</span><br><span class="line">                map.put(col.value(), toMap(val));</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 普通字段：直接存入Map</span></span><br><span class="line">            map.put(col.value(), val);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> map;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* ==================== 2. Map → 实体对象（支持嵌套/集合） ==================== */</span></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 将Map转为指定类型的实体对象，Map的key对应<span class="doctag">@Table</span>.Col的value值</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> map 待转换的Map</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> clazz 目标实体类（必须标注<span class="doctag">@Table</span>注解）</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> 转换后的实体对象（空Map/未标注注解返回null）</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@SuppressWarnings(&quot;unchecked&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> &lt;T&gt; <span class="type">T</span> <span class="title function_">toBean</span><span class="params">(Map&lt;String, Object&gt; map, Class&lt;T&gt; clazz)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (MapUtil.isEmpty(map)) <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="keyword">if</span> (!clazz.isAnnotationPresent(Table.class)) <span class="keyword">return</span> <span class="literal">null</span>; <span class="comment">// 未标注@Table直接返回null</span></span><br><span class="line"></span><br><span class="line">        <span class="type">T</span> <span class="variable">instance</span> <span class="operator">=</span> ReflectUtil.newInstance(clazz); <span class="comment">// 反射创建对象实例</span></span><br><span class="line">        <span class="type">Field</span>[] <span class="variable">fields</span> <span class="operator">=</span> ReflectUtil.getFields(clazz);</span><br><span class="line">        <span class="keyword">for</span> (Field f : fields) &#123;</span><br><span class="line">            Table.<span class="type">Col</span> <span class="variable">col</span> <span class="operator">=</span> f.getAnnotation(Table.Col.class);</span><br><span class="line">            <span class="keyword">if</span> (ObjUtil.isNull(col)) <span class="keyword">continue</span>; <span class="comment">// 未标注@Table.Col的字段忽略</span></span><br><span class="line">            <span class="type">Object</span> <span class="variable">val</span> <span class="operator">=</span> map.get(col.value());</span><br><span class="line">            <span class="keyword">if</span> (ObjUtil.isNull(val)) <span class="keyword">continue</span>; <span class="comment">// 空值字段忽略</span></span><br><span class="line"></span><br><span class="line">            <span class="comment">// 处理嵌套对象：递归转换为目标字段类型</span></span><br><span class="line">            <span class="keyword">if</span> (f.getType().isAnnotationPresent(Table.class)) &#123;</span><br><span class="line">                ReflectUtil.setFieldValue(instance, f, toBean((Map&lt;String, Object&gt;) val, f.getType()));</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 处理集合类型：递归转换集合元素为目标类型</span></span><br><span class="line">            <span class="keyword">if</span> (Collection.class.isAssignableFrom(f.getType())) &#123;</span><br><span class="line">                <span class="type">Type</span> <span class="variable">generic</span> <span class="operator">=</span> f.getGenericType();</span><br><span class="line">                <span class="keyword">if</span> (generic <span class="keyword">instanceof</span> ParameterizedType) &#123;</span><br><span class="line">                    <span class="type">ParameterizedType</span> <span class="variable">pt</span> <span class="operator">=</span> (ParameterizedType) generic;</span><br><span class="line">                    <span class="type">Class</span>&lt;?&gt; <span class="variable">actual</span> <span class="operator">=</span> (Class&lt;?&gt;) pt.getActualTypeArguments()[<span class="number">0</span>];</span><br><span class="line">                    <span class="keyword">if</span> (actual.isAnnotationPresent(Table.class) &amp;&amp; val <span class="keyword">instanceof</span> List) &#123;</span><br><span class="line">                        <span class="type">List</span>&lt;Map&lt;String, Object&gt;&gt; <span class="variable">list</span> <span class="operator">=</span> (List&lt;Map&lt;String, Object&gt;&gt;) val;</span><br><span class="line">                        <span class="type">Collection</span>&lt;Object&gt; <span class="variable">target</span> <span class="operator">=</span> createCollection(f.getType()); <span class="comment">// 创建对应集合实例</span></span><br><span class="line">                        <span class="keyword">for</span> (Map&lt;String, Object&gt; item : list) target.add(toBean(item, actual));</span><br><span class="line">                        ReflectUtil.setFieldValue(instance, f, target);</span><br><span class="line">                        <span class="keyword">continue</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 普通字段：直接设置值（Hutool自动处理类型转换）</span></span><br><span class="line">            ReflectUtil.setFieldValue(instance, f, val);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> instance;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* ==================== 辅助方法：创建集合实例 ==================== */</span></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 根据字段类型创建对应的Collection实例（默认List/Set实现）</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> fieldType 集合字段类型（List/Set）</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> 对应的Collection实例</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="type">Collection</span>&lt;Object&gt; <span class="title function_">createCollection</span><span class="params">(Class&lt;?&gt; fieldType)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (List.class.isAssignableFrom(fieldType)) <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">if</span> (Set.class.isAssignableFrom(fieldType)) <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">LinkedHashSet</span>&lt;&gt;(); <span class="comment">// 保持插入顺序</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;(); <span class="comment">// 默认返回ArrayList</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="工具类调用示例"><a href="#工具类调用示例" class="headerlink" title="工具类调用示例"></a>工具类调用示例</h2><p>从模型数据中获取 <code>Map</code>，通过 <code>BeanMapMapper</code> 快速转换为目标实体类，适配数据同步场景：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 从模型中获取原始Map数据</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 模型数据Map</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">private</span> <span class="type">Map</span>&lt;String, Object&gt; <span class="title function_">getModelData</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> kmReviewMain.getExtendDataModelInfo().getModelData();</span><br><span class="line">    &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">SyncBusinessException</span>(<span class="string">&quot;MODEL_DATA_ERROR&quot;</span>, <span class="string">&quot;获取模型数据异常&quot;</span>, e);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 将Map数据转换为出差申请单实体类</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 转换后的TripApplyData实例</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">private</span> <span class="type">TripApplyData</span> <span class="title function_">getApply</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="comment">// 核心调用：Map → 实体</span></span><br><span class="line">        <span class="keyword">return</span> BeanMapMapper.toBean(getModelData(), TripApplyData.class);</span><br><span class="line">    &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">SyncBusinessException</span>(<span class="string">&quot;MODEL_DATA_ERROR&quot;</span>, <span class="string">&quot;Map转出差申请单实体异常&quot;</span>, e);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 若需实体转Map，直接调用：</span></span><br><span class="line">    <span class="comment">// TripApplyData applyData = new TripApplyData();</span></span><br><span class="line">    <span class="comment">// Map&lt;String, Object&gt; applyMap = BeanMapMapper.toMap(applyData);</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="方案二：KV-配置式对象转换（基于-Hutool）"><a href="#方案二：KV-配置式对象转换（基于-Hutool）" class="headerlink" title="方案二：KV 配置式对象转换（基于 Hutool）"></a>方案二：KV 配置式对象转换（基于 <code>Hutool</code>）</h1><p>通过 <code>Map</code> 配置字段映射关系，结合 <code>Hutool</code> 的 <code>BeanUtil</code> 实现对象之间的快速转换，适用于字段较少、映射关系简单的场景（如 <code>VO</code> 与数据库实体的转换）。</p><h2 id="转换工具类（SyncBeanConvertUtil）"><a href="#转换工具类（SyncBeanConvertUtil）" class="headerlink" title="转换工具类（SyncBeanConvertUtil）"></a>转换工具类（<code>SyncBeanConvertUtil</code>）</h2><p>封装对象转换逻辑，通过预定义的映射配置（<code>CITY_VO_COPY_OPTIONS</code>）实现 <code>VO</code> 到实体的批量转换：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.landray.kmss.shunan.travel.sync.utils;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> cn.hutool.core.bean.BeanUtil;</span><br><span class="line"><span class="keyword">import</span> cn.hutool.core.collection.CollUtil;</span><br><span class="line"><span class="keyword">import</span> cn.hutool.core.util.ObjUtil;</span><br><span class="line"><span class="keyword">import</span> com.landray.kmss.shunan.travel.model.ShunanTravelCity;</span><br><span class="line"><span class="keyword">import</span> com.landray.kmss.shunan.travel.sync.vo.CityVO;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="keyword">static</span> com.landray.kmss.shunan.travel.mappings.ShunanTravelCityVoMapping.CITY_VO_COPY_OPTIONS;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * VO与数据库实体转换工具类</span></span><br><span class="line"><span class="comment"> * 核心依赖：Hutool的BeanUtil（字段拷贝）、CollUtil（集合判空）</span></span><br><span class="line"><span class="comment"> * 适用场景：简单对象（无复杂嵌套）的快速转换</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">SyncBeanConvertUtil</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 将城市VO列表转换为数据库实体列表</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> cityVO 城市接口返回的VO（含数据列表）</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> 转换后的ShunanTravelCity实体列表（空输入返回空列表）</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">List</span>&lt;ShunanTravelCity&gt; <span class="title function_">cityVoToEntityList</span><span class="params">(CityVO cityVO)</span> &#123;</span><br><span class="line">        <span class="comment">// 空值校验：避免空指针异常</span></span><br><span class="line">        <span class="keyword">if</span> (ObjUtil.isNull(cityVO) || CollUtil.isEmpty(cityVO.getDataList())) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="type">List</span>&lt;ShunanTravelCity&gt; <span class="variable">entityList</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="comment">// 遍历VO列表，逐个转换为实体</span></span><br><span class="line">        <span class="keyword">for</span> (CityVO.QueryCityCommonBean voBean : cityVO.getDataList()) &#123;</span><br><span class="line">            <span class="type">ShunanTravelCity</span> <span class="variable">entity</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ShunanTravelCity</span>();</span><br><span class="line">            <span class="comment">// 核心转换：基于KV映射配置拷贝字段</span></span><br><span class="line">            BeanUtil.copyProperties(voBean, entity, CITY_VO_COPY_OPTIONS);</span><br><span class="line">            entityList.add(entity);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> entityList;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="KV-映射配置类（ShunanTravelCityVoMapping）"><a href="#KV-映射配置类（ShunanTravelCityVoMapping）" class="headerlink" title="KV 映射配置类（ShunanTravelCityVoMapping）"></a>KV 映射配置类（<code>ShunanTravelCityVoMapping</code>）</h2><p>通过 <code>Map</code> 定义 <code>VO</code> 字段与实体字段的映射关系，配合 <code>Hutool</code> 的<code>CopyOptions</code>实现字段别名映射，配置直观、便于维护：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.landray.kmss.shunan.travel.mappings;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> cn.hutool.core.bean.copier.CopyOptions;</span><br><span class="line"><span class="keyword">import</span> java.util.HashMap;</span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 城市VO与数据库实体的KV映射配置类</span></span><br><span class="line"><span class="comment"> * 作用：定义VO字段名 → 实体字段名的映射关系，供BeanUtil拷贝使用</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ShunanTravelCityVoMapping</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * KV映射关系：key=VO字段名，value=实体字段名</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> Map&lt;String, String&gt; CITY_VO_TO_ENTITY_MAPPING;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Hutool拷贝配置：包含KV映射关系，用于BeanUtil.copyProperties</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> CopyOptions CITY_VO_COPY_OPTIONS;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 静态代码块：初始化映射关系和拷贝配置</span></span><br><span class="line">    <span class="keyword">static</span> &#123;</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 逐个配置字段映射关系</span></span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;code&quot;</span>, <span class="string">&quot;fdCode&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;name&quot;</span>, <span class="string">&quot;fdName&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;englishName&quot;</span>, <span class="string">&quot;fdEnglishName&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;countrySimpleCode&quot;</span>, <span class="string">&quot;fdCountrySimpleCode&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;type&quot;</span>, <span class="string">&quot;fdType&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;countryBelongCode&quot;</span>, <span class="string">&quot;fdCountryBelongCode&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;countryBelongNameZh&quot;</span>, <span class="string">&quot;fdCountryBelongNameZh&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;provinceBelongCode&quot;</span>, <span class="string">&quot;fdProvinceBelongCode&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;provinceBelongNameZh&quot;</span>, <span class="string">&quot;fdProvinceBelongNameZh&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;cityInitial&quot;</span>, <span class="string">&quot;fdCityinitial&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;parentCityCode&quot;</span>, <span class="string">&quot;fdParentCityCode&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;cityBelongCode&quot;</span>, <span class="string">&quot;fdCityBelongCode&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;cityBelongNameZh&quot;</span>, <span class="string">&quot;fdCityBelongNameZh&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;isDomestic&quot;</span>, <span class="string">&quot;fdIsDomestic&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;haveAirport&quot;</span>, <span class="string">&quot;fdHaveAirport&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;haveTrainStation&quot;</span>, <span class="string">&quot;fdHaveTrainStation&quot;</span>);</span><br><span class="line">        CITY_VO_TO_ENTITY_MAPPING.put(<span class="string">&quot;nationalAdministrativeCode&quot;</span>, <span class="string">&quot;fdNationalAdministrativeCode&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 初始化拷贝配置：绑定KV映射关系</span></span><br><span class="line">        CITY_VO_COPY_OPTIONS = <span class="keyword">new</span> <span class="title class_">CopyOptions</span>().setFieldMapping(CITY_VO_TO_ENTITY_MAPPING);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 私有构造器：禁止实例化配置类</span></span><br><span class="line">    <span class="type">private</span> <span class="title function_">ShunanTravelCityVoMapping</span><span class="params">()</span> &#123;&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="转换工具调用示例"><a href="#转换工具调用示例" class="headerlink" title="转换工具调用示例"></a>转换工具调用示例</h2><p>在接口数据同步场景中，将接口返回的 <code>VO</code> 快速转换为数据库实体，用于后续持久化操作：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 城市数据同步示例：VO → 实体</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">// 1. 从接口获取返回结果（假设apiResponse为接口响应对象）</span></span><br><span class="line"><span class="type">CityVO</span> <span class="variable">cityVO</span> <span class="operator">=</span> apiResponse.getResult();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2. 调用工具类转换为实体列表</span></span><br><span class="line"><span class="type">List</span>&lt;ShunanTravelCity&gt; <span class="variable">currentPageCities</span> <span class="operator">=</span> SyncBeanConvertUtil.cityVoToEntityList(cityVO);</span><br><span class="line"></span><br></pre></td></tr></table></figure><h1 id="实用工具：Map-结构扁平化工具类（MapUtil）"><a href="#实用工具：Map-结构扁平化工具类（MapUtil）" class="headerlink" title="实用工具：Map 结构扁平化工具类（MapUtil）"></a>实用工具：<code>Map</code> 结构扁平化工具类（<code>MapUtil</code>）</h1><p>扩展 <code>Hutool</code> 的<code>MapUtil</code>，提供嵌套 <code>Map/List</code> 结构的扁平化功能，将多层级键值对转为单层结构，适用于 <code>URL</code> 参数拼接、简单配置输出、日志打印等场景。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.landray.kmss.shunan.travel.util;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> cn.hutool.core.util.ObjUtil;</span><br><span class="line"><span class="keyword">import</span> cn.hutool.core.util.StrUtil;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Hutool MapUtil扩展工具类：提供嵌套Map/List的扁平化功能</span></span><br><span class="line"><span class="comment"> * 核心场景：</span></span><br><span class="line"><span class="comment"> * 1. 嵌套Map转URL查询参数（如：user.name=张三&amp;hobbies[0]=编程）</span></span><br><span class="line"><span class="comment"> * 2. 复杂Map结构日志打印（单层结构更易读）</span></span><br><span class="line"><span class="comment"> * 3. 简单配置文件输出（需单层键值对格式）</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MapUtil</span> <span class="keyword">extends</span> <span class="title class_">cn</span>.hutool.core.map.MapUtil &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 递归扁平化嵌套Map/List结构</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> sourceMap 待扁平化的源Map（支持值为Map、List或普通对象）</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> parentKey 父层级键名（顶层调用传空字符串&quot;&quot;）</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> targetMap 接收结果的目标Map（需提前创建，如new HashMap&lt;&gt;()）</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">void</span> <span class="title function_">flattenMap</span><span class="params">(Map&lt;String, Object&gt; sourceMap, String parentKey, Map&lt;String, String&gt; targetMap)</span> &#123;</span><br><span class="line">        <span class="comment">// 健壮性检查：避免空指针</span></span><br><span class="line">        <span class="keyword">if</span> (isEmpty(sourceMap) || ObjUtil.isNull(targetMap)) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 遍历源Map的每个键值对</span></span><br><span class="line">        <span class="keyword">for</span> (Map.Entry&lt;String, Object&gt; entry : sourceMap.entrySet()) &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">currentKey</span> <span class="operator">=</span> entry.getKey();</span><br><span class="line">            <span class="type">Object</span> <span class="variable">currentValue</span> <span class="operator">=</span> entry.getValue();</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 拼接完整键名：父键名 + 当前键名（顶层无父键名直接用当前键名）</span></span><br><span class="line">            <span class="type">String</span> <span class="variable">fullKey</span> <span class="operator">=</span> StrUtil.isEmpty(parentKey) ? currentKey : parentKey + <span class="string">&quot;.&quot;</span> + currentKey;</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 过滤空值：不加入结果Map</span></span><br><span class="line">            <span class="keyword">if</span> (ObjUtil.isNull(currentValue)) &#123;</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 递归处理嵌套Map（如：&#123;user: &#123;name: 张三&#125;&#125; → user.name=张三）</span></span><br><span class="line">            <span class="keyword">if</span> (currentValue <span class="keyword">instanceof</span> Map) &#123;</span><br><span class="line">                <span class="meta">@SuppressWarnings(&quot;unchecked&quot;)</span></span><br><span class="line">                <span class="type">Map</span>&lt;String, Object&gt; <span class="variable">nestedMap</span> <span class="operator">=</span> (Map&lt;String, Object&gt;) currentValue;</span><br><span class="line">                flattenMap(nestedMap, fullKey, targetMap);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 处理List/数组（如：&#123;hobbies: [编程, 阅读]&#125; → hobbies[0]=编程&amp;hobbies[1]=阅读）</span></span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">if</span> (currentValue <span class="keyword">instanceof</span> List) &#123;</span><br><span class="line">                <span class="type">List</span>&lt;?&gt; <span class="variable">list</span> <span class="operator">=</span> (List&lt;?&gt;) currentValue;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; list.size(); i++) &#123;</span><br><span class="line">                    <span class="type">Object</span> <span class="variable">listItem</span> <span class="operator">=</span> list.get(i);</span><br><span class="line">                    <span class="type">String</span> <span class="variable">listKey</span> <span class="operator">=</span> fullKey + <span class="string">&quot;[&quot;</span> + i + <span class="string">&quot;]&quot;</span>; <span class="comment">// 列表元素键名：键名[索引]</span></span><br><span class="line">                    <span class="comment">// 列表元素为Map时继续递归（如：&#123;passengers: [&#123;name: 张三&#125;]&#125; → passengers[0].name=张三）</span></span><br><span class="line">                    <span class="keyword">if</span> (listItem <span class="keyword">instanceof</span> Map) &#123;</span><br><span class="line">                        <span class="meta">@SuppressWarnings(&quot;unchecked&quot;)</span></span><br><span class="line">                        <span class="type">Map</span>&lt;String, Object&gt; <span class="variable">itemMap</span> <span class="operator">=</span> (Map&lt;String, Object&gt;) listItem;</span><br><span class="line">                        flattenMap(itemMap, listKey, targetMap);</span><br><span class="line">                    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                        <span class="comment">// 普通列表元素：直接转为字符串存入结果</span></span><br><span class="line">                        targetMap.put(listKey, StrUtil.toString(listItem));</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; </span><br><span class="line">            <span class="comment">// 普通字段：直接转为字符串存入结果（兼容所有基本类型）</span></span><br><span class="line">            <span class="keyword">else</span> &#123;</span><br><span class="line">                targetMap.put(fullKey, StrUtil.toString(currentValue));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="扁平化效果示例"><a href="#扁平化效果示例" class="headerlink" title="扁平化效果示例"></a>扁平化效果示例</h1><h2 id="源嵌套-Map："><a href="#源嵌套-Map：" class="headerlink" title="源嵌套 Map："></a>源嵌套 <code>Map</code>：</h2><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;user&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;张三&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;age&quot;</span><span class="punctuation">:</span> <span class="number">30</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;hobbies&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;编程&quot;</span><span class="punctuation">,</span> <span class="string">&quot;阅读&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;address&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;city&quot;</span><span class="punctuation">:</span> <span class="string">&quot;北京&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;detail&quot;</span><span class="punctuation">:</span> <span class="string">&quot;XX街道&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;passengers&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="punctuation">&#123;</span><span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;李四&quot;</span><span class="punctuation">,</span> <span class="attr">&quot;phone&quot;</span><span class="punctuation">:</span> <span class="string">&quot;123456&quot;</span><span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="punctuation">&#123;</span><span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;王五&quot;</span><span class="punctuation">,</span> <span class="attr">&quot;phone&quot;</span><span class="punctuation">:</span> <span class="string">&quot;654321&quot;</span><span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h2 id="扁平化后-Map："><a href="#扁平化后-Map：" class="headerlink" title="扁平化后 Map："></a>扁平化后 <code>Map</code>：</h2><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;user.name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;张三&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;user.age&quot;</span><span class="punctuation">:</span> <span class="string">&quot;30&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;hobbies[0]&quot;</span><span class="punctuation">:</span> <span class="string">&quot;编程&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;hobbies[1]&quot;</span><span class="punctuation">:</span> <span class="string">&quot;阅读&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;address.city&quot;</span><span class="punctuation">:</span> <span class="string">&quot;北京&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;address.detail&quot;</span><span class="punctuation">:</span> <span class="string">&quot;XX街道&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;passengers[0].name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;李四&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;passengers[0].phone&quot;</span><span class="punctuation">:</span> <span class="string">&quot;123456&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;passengers[1].name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;王五&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;passengers[1].phone&quot;</span><span class="punctuation">:</span> <span class="string">&quot;654321&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h2 id="调用示例"><a href="#调用示例" class="headerlink" title="调用示例"></a>调用示例</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 1. 准备源嵌套Map（可通过BeanMapMapper.toMap(实体)获取）</span></span><br><span class="line"><span class="type">Map</span>&lt;String, Object&gt; <span class="variable">sourceMap</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line"><span class="comment">// ... 向sourceMap添加嵌套数据 ...</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 2. 创建目标Map接收结果</span></span><br><span class="line"><span class="type">Map</span>&lt;String, String&gt; <span class="variable">flatMap</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 3. 调用扁平化方法（顶层parentKey传&quot;&quot;）</span></span><br><span class="line">MapUtil.flattenMap(sourceMap, <span class="string">&quot;&quot;</span>, flatMap);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 4. 后续使用（如转为URL参数）</span></span><br><span class="line"><span class="comment">// String urlParams = HttpUtil.toParams(flatMap);</span></span><br></pre></td></tr></table></figure><h1 id="方案对比与选择建议"><a href="#方案对比与选择建议" class="headerlink" title="方案对比与选择建议"></a>方案对比与选择建议</h1><table><thead><tr><th>方案类型</th><th>核心优势</th><th>适用场景</th><th>依赖工具</th></tr></thead><tbody><tr><td>注解式映射</td><td>侵入性低、支持复杂嵌套、配置直观</td><td>字段多、嵌套深的对象（如接口参数）</td><td><code>Hutool</code> 反射工具</td></tr><tr><td><code>KV</code> 配置式映射</td><td>配置集中、无需修改实体类</td><td>简单对象（如 <code>VO</code> 与数据库实体转换）</td><td><code>Hutool BeanUtil</code></td></tr><tr><td><code>Map</code> 扁平化工具</td><td>解决多层结构转单层需求</td><td><code>URL</code> 参数、日志打印、简单配置输出</td><td><code>Hutool</code> 基础工具</td></tr></tbody></table><p><strong>优先选择注解式映射：</strong> 对于大多数业务场景（尤其是接口数据同步、复杂参数转换），注解式映射的灵活性和可读性更优；仅在无需修改实体类（如第三方提供的 <code>VO</code>）或字段极少时，考虑 <code>KV</code> 配置式映射。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;前言&quot;&gt;&lt;a href=&quot;#前言&quot; class=&quot;headerlink&quot; title=&quot;前言&quot;&gt;&lt;/a&gt;前言&lt;/h1&gt;&lt;p&gt;本文提供三种 &lt;code&gt;Java&lt;/code&gt; 数据处理核心方案，涵盖对象与 &lt;code&gt;Map&lt;/code&gt; 的双向映射及复杂 &lt;cod</summary>
      
    
    
    
    <category term="📕小敏の手札" scheme="https://xmblog.chrislin.eu.org/categories/%F0%9F%93%95%E5%B0%8F%E6%95%8F%E3%81%AE%E6%89%8B%E6%9C%AD/"/>
    
    
    <category term="🅔晚风のEKP" scheme="https://xmblog.chrislin.eu.org/tags/%F0%9F%85%94%E6%99%9A%E9%A3%8E%E3%81%AEEKP/"/>
    
  </entry>
  
  <entry>
    <title>js为目标元素添加父/子元素</title>
    <link href="https://xmblog.chrislin.eu.org/posts/20251125071047.html"/>
    <id>https://xmblog.chrislin.eu.org/posts/20251125071047.html</id>
    <published>2025-11-25T07:10:47.000Z</published>
    <updated>2026-11-10T13:02:16.260Z</updated>
    
    <content type="html"><![CDATA[<p>以下为低代码MK开发的一点小知识笔记</p><h1 id="1-使用案例（明细表字段添加跳转链接）"><a href="#1-使用案例（明细表字段添加跳转链接）" class="headerlink" title="1. 使用案例（明细表字段添加跳转链接）"></a>1. 使用案例（明细表字段添加跳转链接）</h1><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * onLoad_3 - 明细表加载完成后触发的回调事件</span></span><br><span class="line"><span class="comment"> * 核心功能：遍历明细表数据，为每个合同字段查询对应的流程链接，为文本元素包裹a标签实现跳转</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">onLoad_3</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="comment">// 仅在&quot;查看&quot;模式下执行（低代码平台视图状态：view=查看，edit=编辑，add=新增）</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="variable constant_">MKXFORM</span>.<span class="property">viewStatus</span> == <span class="string">&#x27;view&#x27;</span>) &#123;</span><br><span class="line">        <span class="comment">// 字段标识前缀：对应明细表中合同字段的基础标识（后续拼接行唯一key）</span></span><br><span class="line">        <span class="keyword">const</span> fieldPrefix = <span class="string">&quot;mk_payment_request_detail.fd_col_contract~&quot;</span>;</span><br><span class="line">        <span class="comment">// 获取明细表数据：MKXFORM.getValue(&quot;明细表字段标识&quot;).values 是低代码平台获取明细表数据的固定方式</span></span><br><span class="line">        <span class="keyword">const</span> tables = <span class="variable constant_">MKXFORM</span>.<span class="title function_">getValue</span>(<span class="string">&quot;mk_payment_request_detail&quot;</span>).<span class="property">values</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 前置校验：确保明细表有数据</span></span><br><span class="line">        <span class="keyword">if</span> (tables &amp;&amp; <span class="title class_">Array</span>.<span class="title function_">isArray</span>(tables) &amp;&amp; tables.<span class="property">length</span> &gt; <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="comment">// 遍历明细表每一行数据</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; tables.<span class="property">length</span>; i++) &#123;</span><br><span class="line">                <span class="comment">// 动态拼接当前行合同字段的唯一标识（tables[i].key 是每行的唯一key，确保字段标识不重复）</span></span><br><span class="line">                <span class="keyword">const</span> field_contract = fieldPrefix + tables[i].<span class="property">key</span>;</span><br><span class="line">                <span class="comment">// 获取当前行的合同数据（格式：[&#123;fdId: &quot;xxx&quot;, fdName: &quot;xxx&quot;&#125;]）</span></span><br><span class="line">                <span class="keyword">const</span> contract = tables[i][<span class="string">&quot;fd_col_contract&quot;</span>];</span><br><span class="line"></span><br><span class="line">                <span class="comment">// 校验合同数据有效性：确保存在且有fdId（fdId为合同台账的唯一标识，用于查询流程链接）</span></span><br><span class="line">                <span class="keyword">if</span> (contract &amp;&amp; <span class="title class_">Array</span>.<span class="title function_">isArray</span>(contract) &amp;&amp; contract.<span class="property">length</span> &gt; <span class="number">0</span> &amp;&amp; contract[<span class="number">0</span>].<span class="property">fdId</span>) &#123;</span><br><span class="line">                    <span class="comment">/**</span></span><br><span class="line"><span class="comment">                     * 调用集成平台第三方接口：【合同台账】根据ID查询流程ID</span></span><br><span class="line"><span class="comment">                     * 接口参数：fdId（合同唯一标识）</span></span><br><span class="line"><span class="comment">                     * 回调函数：处理接口返回结果，生成跳转链接并设置a标签</span></span><br><span class="line"><span class="comment">                     */</span></span><br><span class="line">                    <span class="variable constant_">MKXFORM</span>.<span class="title function_">callTic</span>(&#123;</span><br><span class="line">                        <span class="attr">interfaceCode</span>: <span class="string">&quot;function_6f73n7dgw6vr7xi5&quot;</span>, <span class="comment">// 集成平台注册的接口编码（固定值）</span></span><br><span class="line">                        <span class="attr">param</span>: &#123; <span class="string">&quot;fdId&quot;</span>: contract[<span class="number">0</span>].<span class="property">fdId</span> &#125; <span class="comment">// 接口请求参数：合同fdId</span></span><br><span class="line">                    &#125;, <span class="keyword">function</span> (<span class="params">error, res</span>) &#123;</span><br><span class="line">                        <span class="comment">// 接口调用成功且返回有效流程ID（fdSourceId为流程详情页的核心标识）</span></span><br><span class="line">                        <span class="keyword">if</span> (res &amp;&amp; res.<span class="property">data</span> &amp;&amp; res.<span class="property">data</span>.<span class="property">fdSourceId</span>) &#123;</span><br><span class="line">                            <span class="comment">// 拼接流程详情页跳转链接（低代码平台流程查看页固定URL格式）</span></span><br><span class="line">                            <span class="keyword">const</span> targetUrl = <span class="string">&#x27;https://xxx.xxx/xxx/view/&#x27;</span> + res.<span class="property">data</span>.<span class="property">fdSourceId</span>;</span><br><span class="line">                            <span class="comment">// 调用工具函数：为当前字段的文本元素包裹a标签</span></span><br><span class="line">                            <span class="variable language_">window</span>.<span class="property">MKXFORM</span>.<span class="property">GLOBALJS</span>.<span class="title function_">setA2Target</span>(field_contract, targetUrl);</span><br><span class="line"></span><br><span class="line">                            <span class="comment">// 重试逻辑：解决低代码平台DOM渲染延迟导致的元素未找到问题</span></span><br><span class="line">                            <span class="keyword">let</span> retryCount = <span class="number">0</span>; <span class="comment">// 重试计数器</span></span><br><span class="line">                            <span class="keyword">const</span> maxRetry = <span class="number">5</span>; <span class="comment">// 最大重试次数（避免无限循环）</span></span><br><span class="line">                            <span class="keyword">const</span> timer = <span class="built_in">setInterval</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">                                <span class="comment">// 字段标识转义：处理特殊字符，确保CSS选择器合法</span></span><br><span class="line">                                <span class="keyword">const</span> fieldReplace = <span class="variable language_">window</span>.<span class="property">MKXFORM</span>.<span class="property">GLOBALJS</span>.<span class="title function_">escapeFieldForSelector</span>(field_contract);</span><br><span class="line">                                <span class="comment">// 查询是否已成功创建a标签（通过转义后的类名定位）</span></span><br><span class="line">                                <span class="keyword">const</span> allCus = <span class="variable language_">document</span>.<span class="title function_">querySelectorAll</span>(<span class="string">&#x27;.custom-parent-a-&#x27;</span> + fieldReplace);</span><br><span class="line"></span><br><span class="line">                                <span class="keyword">if</span> (allCus.<span class="property">length</span> &gt; <span class="number">0</span>) &#123;</span><br><span class="line">                                    <span class="comment">// 已找到a标签，停止重试</span></span><br><span class="line">                                    <span class="built_in">clearInterval</span>(timer);</span><br><span class="line">                                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (retryCount &gt;= maxRetry) &#123;</span><br><span class="line">                                    <span class="comment">// 重试次数用尽，停止重试并打印警告</span></span><br><span class="line">                                    <span class="built_in">clearInterval</span>(timer);</span><br><span class="line">                                    <span class="variable language_">console</span>.<span class="title function_">warn</span>(<span class="string">&quot;设置a标签超时，目标元素未找到&quot;</span>, &#123; <span class="attr">field</span>: field_contract &#125;);</span><br><span class="line">                                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                                    <span class="comment">// 未找到，重新执行a标签设置</span></span><br><span class="line">                                    <span class="variable language_">window</span>.<span class="property">MKXFORM</span>.<span class="property">GLOBALJS</span>.<span class="title function_">setA2Target</span>(field_contract, targetUrl);</span><br><span class="line">                                    retryCount++; <span class="comment">// 计数器自增</span></span><br><span class="line">                                &#125;</span><br><span class="line">                            &#125;, <span class="number">1000</span>); <span class="comment">// 重试间隔：1秒（适配DOM渲染延迟）</span></span><br><span class="line"></span><br><span class="line">                        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                            <span class="comment">// 接口调用失败或未返回有效fdSourceId，打印错误日志（便于排查问题）</span></span><br><span class="line">                            <span class="variable language_">console</span>.<span class="title function_">error</span>(<span class="string">&quot;onLoad_3：查询流程ID失败，未获取到有效fdSourceId&quot;</span>, &#123; error, res, <span class="attr">field</span>: field_contract &#125;);</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;);</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    <span class="comment">// 合同数据无效，打印警告日志（非错误，仅告知无需执行后续逻辑）</span></span><br><span class="line">                    <span class="variable language_">console</span>.<span class="title function_">warn</span>(<span class="string">&quot;onLoad_3：未获取到有效项目ID，无需调用接口&quot;</span>, &#123; contract, <span class="attr">field</span>: field_contract &#125;);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="2-关键代码：setA2Target（为元素包裹-a-标签）"><a href="#2-关键代码：setA2Target（为元素包裹-a-标签）" class="headerlink" title="2. 关键代码：setA2Target（为元素包裹 a 标签）"></a>2. 关键代码：<code>setA2Target</code>（为元素包裹 <code>a</code> 标签）</h1><p>为目标字段的文本元素添加<code>&lt;a&gt;</code>标签父元素，实现跳转功能，其他标签（如 <code>div</code>、<code>span</code>）可参考此逻辑修改。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * setA2Target - 为目标字段的文本元素包裹a标签，配置跳转链接</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">string</span>&#125; <span class="variable">field</span> - 字段唯一标识（如：mk_payment_request_detail.fd_col_contract~xxx）</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">string</span>&#125; <span class="variable">url</span> - 跳转链接（流程详情页URL）</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">setA2Target</span>(<span class="params">field, url</span>) &#123;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="comment">// 步骤1：字段标识转义（处理.、~等CSS特殊字符，避免选择器语法错误）</span></span><br><span class="line">        <span class="keyword">const</span> fieldReplace = <span class="variable language_">window</span>.<span class="property">MKXFORM</span>.<span class="property">GLOBALJS</span>.<span class="title function_">escapeFieldForSelector</span>(field);</span><br><span class="line">        <span class="comment">// 步骤2：查询目标元素（低代码平台字段文本元素固定结构：[data-name=&quot;字段标识&quot;] &gt; span.ele-item-text）</span></span><br><span class="line">        <span class="keyword">const</span> targetEl = <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">&quot;[data-name=&#x27;&quot;</span> + field + <span class="string">&quot;&#x27;] span.ele-item-text&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 校验：若未找到目标元素，打印警告并返回（避免后续代码报错）</span></span><br><span class="line">        <span class="keyword">if</span> (!targetEl) &#123;</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">warn</span>(<span class="string">&quot;setA2Target：未找到目标元素&quot;</span>, &#123; field, <span class="attr">targetSelector</span>: <span class="string">&quot;[data-name=&#x27;&quot;</span> + field + <span class="string">&quot;&#x27;] span.ele-item-text&quot;</span> &#125;);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 校验：避免重复创建a标签（通过closest查询当前元素是否已被目标a标签包裹）</span></span><br><span class="line">        <span class="keyword">const</span> existingA = targetEl.<span class="title function_">closest</span>(<span class="string">&#x27;.custom-parent-a-&#x27;</span> + fieldReplace);</span><br><span class="line">        <span class="keyword">if</span> (existingA) &#123;</span><br><span class="line">            existingA.<span class="property">href</span> = url; <span class="comment">// 若已存在，直接更新链接（适配数据刷新场景）</span></span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 步骤3：创建a标签（作为目标元素的父元素）</span></span><br><span class="line">        <span class="keyword">const</span> parentWrap = <span class="variable language_">document</span>.<span class="title function_">createElement</span>(<span class="string">&#x27;a&#x27;</span>);</span><br><span class="line">        <span class="comment">// 给a标签添加类名（含转义后的字段标识，便于后续查询）</span></span><br><span class="line">        parentWrap.<span class="property">className</span> = <span class="string">&#x27;custom-parent-a-&#x27;</span> + fieldReplace;</span><br><span class="line">        <span class="comment">// 设置跳转链接</span></span><br><span class="line">        parentWrap.<span class="title function_">setAttribute</span>(<span class="string">&#x27;href&#x27;</span>, url);</span><br><span class="line">        <span class="comment">// 设置新窗口打开（避免当前页面跳转，提升用户体验）</span></span><br><span class="line">        parentWrap.<span class="title function_">setAttribute</span>(<span class="string">&#x27;target&#x27;</span>, <span class="string">&#x27;_blank&#x27;</span>);</span><br><span class="line">        <span class="comment">// 安全优化：防止新窗口劫持（低代码平台安全规范要求）</span></span><br><span class="line">        parentWrap.<span class="title function_">setAttribute</span>(<span class="string">&#x27;rel&#x27;</span>, <span class="string">&#x27;noopener noreferrer&#x27;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 步骤4：插入a标签并包裹目标元素</span></span><br><span class="line">        <span class="comment">// 1. 将a标签插入到目标元素的父节点中，位于目标元素之前</span></span><br><span class="line">        targetEl.<span class="property">parentNode</span>.<span class="title function_">insertBefore</span>(parentWrap, targetEl);</span><br><span class="line">        <span class="comment">// 2. 将目标元素移动到a标签内部（完成包裹）</span></span><br><span class="line">        parentWrap.<span class="title function_">appendChild</span>(targetEl);</span><br><span class="line"></span><br><span class="line">    &#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">        <span class="comment">// 捕获异常并打印详细日志（便于问题排查）</span></span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">error</span>(<span class="string">&quot;设置a元素失败&quot;</span>, &#123; field, url, <span class="attr">error</span>: e.<span class="property">message</span>, <span class="attr">stack</span>: e.<span class="property">stack</span> &#125;);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="3-关键代码：escapeFieldForSelector（字段标识转义工具）"><a href="#3-关键代码：escapeFieldForSelector（字段标识转义工具）" class="headerlink" title="3. 关键代码：escapeFieldForSelector（字段标识转义工具）"></a>3. 关键代码：<code>escapeFieldForSelector</code>（字段标识转义工具）</h1><p>处理字段标识中的 <code>CSS</code> 特殊字符（如 <code>.</code> <code>、</code> <code>~</code> <code>、</code> <code>$</code> 等），避免生成无效的 <code>CSS</code> 选择器，导致元素查询失败。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * escapeFieldForSelector - 字段标识转义工具函数</span></span><br><span class="line"><span class="comment"> * 核心作用：将含特殊字符的字段标识转为CSS选择器支持的格式，避免语法错误</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">string</span>&#125; <span class="variable">field</span> - 原始字段标识（可能含.、~、$、数字开头等特殊场景）</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@returns</span> &#123;<span class="type">string</span>&#125; 转义后的字段标识（可安全用于CSS选择器）</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">escapeFieldForSelector</span>(<span class="params">field</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (!field) <span class="keyword">return</span> <span class="string">&#x27;&#x27;</span>;</span><br><span class="line">    <span class="keyword">return</span> field</span><br><span class="line">        .<span class="title function_">replace</span>(<span class="regexp">/\./g</span>, <span class="string">&#x27;\\.&#x27;</span>) <span class="comment">// 转义小数点（.在CSS中表示多类名分隔符）</span></span><br><span class="line">        .<span class="title function_">replace</span>(<span class="regexp">/~/g</span>, <span class="string">&#x27;\\~&#x27;</span>) <span class="comment">// 转义波浪号（~在CSS中表示相邻兄弟选择器）</span></span><br><span class="line">        .<span class="title function_">replace</span>(<span class="regexp">/\$/g</span>, <span class="string">&#x27;\\$&#x27;</span>) <span class="comment">// 转义美元符号（$在CSS中是特殊字符）</span></span><br><span class="line">        .<span class="title function_">replace</span>(<span class="regexp">/^(\d)/</span>, <span class="string">&#x27;\\3$1 &#x27;</span>) <span class="comment">// 转义以数字开头的字段（CSS类名不能直接以数字开头，需用\3+数字+空格转义）</span></span><br><span class="line">        .<span class="title function_">replace</span>(<span class="regexp">/__(\d)/</span>, <span class="string">&#x27;__\\3$1 &#x27;</span>); <span class="comment">// 转义双下划线后紧跟数字的场景（如__0.xxx）</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;以下为低代码MK开发的一点小知识笔记&lt;/p&gt;
&lt;h1 id=&quot;1-使用案例（明细表字段添加跳转链接）&quot;&gt;&lt;a href=&quot;#1-使用案例（明细表字段添加跳转链接）&quot; class=&quot;headerlink&quot; title=&quot;1. 使用案例（明细表字段添加跳转链接）&quot;&gt;&lt;/a&gt;1.</summary>
      
    
    
    
    <category term="📕小敏の手札" scheme="https://xmblog.chrislin.eu.org/categories/%F0%9F%93%95%E5%B0%8F%E6%95%8F%E3%81%AE%E6%89%8B%E6%9C%AD/"/>
    
    
    <category term="Ⓜ️晚风のMK" scheme="https://xmblog.chrislin.eu.org/tags/M%EF%B8%8F%E6%99%9A%E9%A3%8E%E3%81%AEMK/"/>
    
  </entry>
  
  <entry>
    <title>Hexo Butterfly 主题：无感刷新 + 侧边音乐插件的优雅配置</title>
    <link href="https://xmblog.chrislin.eu.org/posts/20251120145637.html"/>
    <id>https://xmblog.chrislin.eu.org/posts/20251120145637.html</id>
    <published>2025-11-20T14:56:37.000Z</published>
    <updated>2026-11-10T13:02:16.260Z</updated>
    
    <content type="html"><![CDATA[<h1 id="开启-Pjax-无感刷新：点击链接不跳转页面"><a href="#开启-Pjax-无感刷新：点击链接不跳转页面" class="headerlink" title="开启 Pjax 无感刷新：点击链接不跳转页面"></a>开启 <code>Pjax</code> 无感刷新：点击链接不跳转页面</h1><p>这个配置能让博客内点击链接时 <strong>无刷新切换页面</strong> ，浏览体验更丝滑。</p><p>操作路径：修改 <code>[Blogroot]/_config.butterfly.yml</code> 的以下配置</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Pjax无刷新页面切换（参考文档：https://github.com/MoOx/pjax）</span></span><br><span class="line"><span class="attr">pjax:</span></span><br><span class="line">  <span class="comment"># 是否启用：设为true即可开启全局无感刷新</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 排除不使用Pjax的页面（比如音乐页等，按需添加）</span></span><br><span class="line">  <span class="attr">exclude:</span></span><br><span class="line">  <span class="comment"># - /xxxxxx/</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 自定义CDN加速（可选，让Pjax资源加载更快）</span></span><br><span class="line"><span class="attr">CDN:</span></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line">    <span class="attr">pjax:</span> <span class="string">https://cdn.jsdmirror.com/npm/pjax@0.2.8/pjax.min.js</span></span><br></pre></td></tr></table></figure><h1 id="配置侧边折叠音乐插件：美观不占地"><a href="#配置侧边折叠音乐插件：美观不占地" class="headerlink" title="配置侧边折叠音乐插件：美观不占地"></a>配置侧边折叠音乐插件：美观不占地</h1><p>通过 <code>Aplayer+Meting</code> 实现侧边折叠式音乐播放器（默认只露箭头，<code>hover</code> 展开），兼顾氛围与页面整洁。</p><p><strong>步骤 1：开启 <code>Hexo</code> 的 <code>Aplayer</code> 插件</strong></p><p>操作路径：在 <code>[Blogroot]/_config.yml</code> 末尾添加（无则新增）</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># APlayer（音乐播放器依赖，需先开启）</span></span><br><span class="line"><span class="comment"># 文档：https://github.com/MoePlayer/hexo-tag-aplayer/blob/master/docs/README-zh_cn.md</span></span><br><span class="line"><span class="attr">aplayer:</span></span><br><span class="line">  <span class="attr">meting:</span> <span class="literal">true</span>  <span class="comment"># 启用Meting（对接网易云/QQ音乐等平台）</span></span><br><span class="line">  <span class="attr">asset_inject:</span> <span class="literal">false</span></span><br></pre></td></tr></table></figure><p><strong>步骤 2：在 <code>Butterfly</code> 主题中配置播放器</strong></p><p>操作路径：修改 <code>[Blogroot]/_config.butterfly.yml</code> 的以下配置</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 注入Aplayer相关资源（必须启用）</span></span><br><span class="line"><span class="attr">aplayerInject:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span>    <span class="comment"># 总开关：开</span></span><br><span class="line">  <span class="attr">per_page:</span> <span class="literal">true</span>  <span class="comment"># 所有页面都加载播放器</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 注入自定义样式+播放器容器</span></span><br><span class="line"><span class="attr">inject:</span></span><br><span class="line">  <span class="attr">head:</span></span><br><span class="line">    <span class="comment"># 引入自己写的播放器折叠样式（后面会贴代码）</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;stylesheet&quot;</span> <span class="string">href=&quot;/css/aplayer.css&quot;&gt;</span></span><br><span class="line">  <span class="attr">bottom:</span></span><br><span class="line">    <span class="comment"># 网易云歌单配置：data-id填你的歌单ID，其他参数按需调</span></span><br><span class="line"><span class="comment">#    - &lt;div class=&quot;aplayer no-destroy&quot; data-id=&quot;7510894589&quot; data-server=&quot;netease&quot; data-type=&quot;playlist&quot; data-fixed=&quot;true&quot; data-mini=&quot;true&quot; data-listFolded=&quot;false&quot; data-order=&quot;random&quot; data-preload=&quot;none&quot; data-autoplay=&quot;false&quot; muted&gt;&lt;/div&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;meting-js</span> <span class="string">class=&quot;aplayer</span> <span class="literal">no</span><span class="string">-destroy&quot;</span> <span class="string">server=&quot;netease&quot;</span> <span class="string">type=&quot;playlist&quot;</span> <span class="string">id=&quot;7510894589&quot;</span> <span class="string">fixed=&quot;true&quot;</span> <span class="string">mini=&quot;true&quot;</span> <span class="string">list-folded=&quot;false&quot;</span> <span class="string">list-max-height=&quot;300px&quot;</span> <span class="string">autoplay=&quot;false&quot;</span> <span class="string">theme=&quot;#ff7e79&quot;</span> <span class="string">loop=&quot;all&quot;</span> <span class="string">order=&quot;random&quot;</span> <span class="string">preload=&quot;none&quot;</span> <span class="string">muted=&quot;false&quot;&gt;&lt;/meting-js&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 配置CDN加速音乐播放器资源</span></span><br><span class="line"><span class="attr">CDN:</span></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line">    <span class="attr">aplayer_css:</span> <span class="string">https://cdn.jsdmirror.com/npm/aplayer/dist/APlayer.min.css</span></span><br><span class="line">    <span class="attr">aplayer_js:</span> <span class="string">https://cdn.jsdmirror.com/npm/aplayer/dist/APlayer.min.js</span></span><br><span class="line">    <span class="attr">meting_js:</span> <span class="string">https://cdn.jsdmirror.com/npm/meting@2/dist/Meting.min.js</span></span><br></pre></td></tr></table></figure><p><strong>步骤 3：添加 “侧边折叠” 样式</strong></p><p>操作路径：新建 <code>[Blogroot]/source/css/aplayer.css</code> ，写入以下代码</p><p>（作用：让播放器默认缩在左侧只露箭头，鼠标悬浮时完整展开）</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.aplayer</span><span class="selector-class">.aplayer-fixed</span><span class="selector-class">.aplayer-narrow</span> <span class="selector-class">.aplayer-body</span> &#123;</span><br><span class="line">    <span class="attribute">left</span>: -<span class="number">66px</span> <span class="meta">!important</span>;</span><br><span class="line">    <span class="comment">/* 默认情况下缩进左侧66px，只留一点箭头部分 */</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.aplayer</span><span class="selector-class">.aplayer-fixed</span><span class="selector-class">.aplayer-narrow</span> <span class="selector-class">.aplayer-body</span><span class="selector-pseudo">:hover</span> &#123;</span><br><span class="line">    <span class="attribute">left</span>: <span class="number">0</span> <span class="meta">!important</span>;</span><br><span class="line">    <span class="comment">/* 鼠标悬停是左侧缩进归零，完全显示按钮 */</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h1 id="我的-CDN-配置参考（加速资源加载）"><a href="#我的-CDN-配置参考（加速资源加载）" class="headerlink" title="我的 CDN 配置参考（加速资源加载）"></a>我的 CDN 配置参考（加速资源加载）</h1><p>如果觉我的 <code>CDN</code> 加载速度不错，可以直接复用这个 <code>CDN</code> 配置（修改<code>[Blogroot]/_config.butterfly.yml</code>）</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># CDN设置（内部+第三方资源加速）</span></span><br><span class="line"><span class="attr">CDN:</span></span><br><span class="line">  <span class="attr">internal_provider:</span> <span class="string">local</span></span><br><span class="line">  <span class="attr">third_party_provider:</span> <span class="string">jsdelivr</span></span><br><span class="line">  <span class="attr">version:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line">    <span class="attr">aplayer_css:</span> <span class="string">https://cdn.jsdmirror.com/npm/aplayer/dist/APlayer.min.css</span></span><br><span class="line">    <span class="attr">aplayer_js:</span> <span class="string">https://cdn.jsdmirror.com/npm/aplayer/dist/APlayer.min.js</span></span><br><span class="line">    <span class="attr">meting_js:</span> <span class="string">https://cdn.jsdmirror.com/npm/meting@2/dist/Meting.min.js</span></span><br><span class="line">    <span class="attr">fontawesome:</span> <span class="string">https://cdn.bootcdn.net/ajax/libs/font-awesome/7.0.1/css/all.min.css</span></span><br><span class="line">    <span class="attr">pjax:</span> <span class="string">https://cdn.jsdmirror.com/npm/pjax@0.2.8/pjax.min.js</span></span><br><span class="line">    <span class="attr">waline_css:</span> <span class="string">https://cdn.bootcdn.net/ajax/libs/waline/3.6.0/waline.min.css</span></span><br><span class="line">    <span class="attr">waline_js:</span> <span class="string">https://cdn.bootcdn.net/ajax/libs/waline/3.6.0/waline.min.js</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;开启-Pjax-无感刷新：点击链接不跳转页面&quot;&gt;&lt;a href=&quot;#开启-Pjax-无感刷新：点击链接不跳转页面&quot; class=&quot;headerlink&quot; title=&quot;开启 Pjax 无感刷新：点击链接不跳转页面&quot;&gt;&lt;/a&gt;开启 &lt;code&gt;Pjax&lt;/code&gt;</summary>
      
    
    
    
    <category term="🍭小敏の半糖" scheme="https://xmblog.chrislin.eu.org/categories/%F0%9F%8D%AD%E5%B0%8F%E6%95%8F%E3%81%AE%E5%8D%8A%E7%B3%96/"/>
    
    
    <category term="💠Hexo" scheme="https://xmblog.chrislin.eu.org/tags/%F0%9F%92%A0Hexo/"/>
    
    <category term="🦋Butterfly" scheme="https://xmblog.chrislin.eu.org/tags/%F0%9F%A6%8BButterfly/"/>
    
    <category term="🌌晚风の雾岛 Misty" scheme="https://xmblog.chrislin.eu.org/tags/%F0%9F%8C%8C%E6%99%9A%E9%A3%8E%E3%81%AE%E9%9B%BE%E5%B2%9B-Misty/"/>
    
  </entry>
  
  <entry>
    <title>网站改造为可安装的PWA</title>
    <link href="https://xmblog.chrislin.eu.org/posts/20251031012229.html"/>
    <id>https://xmblog.chrislin.eu.org/posts/20251031012229.html</id>
    <published>2025-10-31T01:22:29.000Z</published>
    <updated>2026-11-10T13:02:16.259Z</updated>
    
    <content type="html"><![CDATA[<h1 id="PWA-简介"><a href="#PWA-简介" class="headerlink" title="PWA 简介"></a>PWA 简介</h1><blockquote><p>渐进式 <code>Web</code> 应用（<code>Progressive Web App</code>，<code>PWA</code>）是一个使用 <code>web</code> 平台技术构建的应用程序，但它提供的用户体验就像一个特定平台的应用程序。它像网站一样，<code>PWA</code>可以通过一个代码库在多个平台和设备上运行。它也像一个特定平台的应用程序一样，可以安装在设备上，可以离线和在后台运行，并且可以与设备和其他已安装的应用程序集成。</p></blockquote><ul><li>支持的浏览器会提示用户将 <code>PWA</code> 安装到设备上。</li><li><code>PWA</code> 可以像特定平台的应用一样安装，并可以自定义安装过程。</li><li>一旦安装，<code>PWA</code> 就会在设备上获得一个应用图标，与特定平台的应用程序一起。</li><li>一旦安装，<code>PWA</code> 可以作为一个独立的应用程序启动，而不是在浏览器中的一个网站。</li></ul><h1 id="从这里开始"><a href="#从这里开始" class="headerlink" title="从这里开始"></a>从这里开始</h1><ol><li>打开<code>_config.butterfly.yml</code> 文件，找到 <code>Inject</code> 部分，在<code>inject.head</code>中添加<code>/manifest.json</code>（文件位于<code>博客根目录/source/</code>） <figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">inject:</span></span><br><span class="line">  <span class="attr">head:</span></span><br><span class="line">  <span class="comment"># - &lt;link rel=&quot;stylesheet&quot; href=&quot;/xxx.css&quot;&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;manifest&quot;</span> <span class="string">href=&quot;/manifest.json&quot;&gt;</span></span><br></pre></td></tr></table></figure></li><li><code>manifest.json</code>内容如下 <figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;小敏の晚风&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;short_name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;小敏の晚风&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;start_url&quot;</span><span class="punctuation">:</span> <span class="string">&quot;/&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;display&quot;</span><span class="punctuation">:</span> <span class="string">&quot;standalone&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;background_color&quot;</span><span class="punctuation">:</span> <span class="string">&quot;#ffffff&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;lang&quot;</span><span class="punctuation">:</span> <span class="string">&quot;zh-cn&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;scope&quot;</span><span class="punctuation">:</span> <span class="string">&quot;/&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;description&quot;</span><span class="punctuation">:</span> <span class="string">&quot;知识分享 技术学习等.&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;icons&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;src&quot;</span><span class="punctuation">:</span> <span class="string">&quot;/img/favcion_xm.svg&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;sizes&quot;</span><span class="punctuation">:</span> <span class="string">&quot;512x512&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;image/svg+xml&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;theme_color&quot;</span><span class="punctuation">:</span> <span class="string">&quot;#0085ff&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;file_handlers&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;share_target&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;screenshots&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure></li></ol>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;PWA-简介&quot;&gt;&lt;a href=&quot;#PWA-简介&quot; class=&quot;headerlink&quot; title=&quot;PWA 简介&quot;&gt;&lt;/a&gt;PWA 简介&lt;/h1&gt;&lt;blockquote&gt;
&lt;p&gt;渐进式 &lt;code&gt;Web&lt;/code&gt; 应用（&lt;code&gt;Progressive</summary>
      
    
    
    
    <category term="🍭小敏の半糖" scheme="https://xmblog.chrislin.eu.org/categories/%F0%9F%8D%AD%E5%B0%8F%E6%95%8F%E3%81%AE%E5%8D%8A%E7%B3%96/"/>
    
    
    <category term="⭐晚风の星匣" scheme="https://xmblog.chrislin.eu.org/tags/%E2%AD%90%E6%99%9A%E9%A3%8E%E3%81%AE%E6%98%9F%E5%8C%A3/"/>
    
  </entry>
  
  <entry>
    <title>Butterfly主题魔改</title>
    <link href="https://xmblog.chrislin.eu.org/posts/20251022083637.html"/>
    <id>https://xmblog.chrislin.eu.org/posts/20251022083637.html</id>
    <published>2025-10-22T08:36:37.000Z</published>
    <updated>2026-11-10T13:02:16.259Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Hexo-基础搭建"><a href="#Hexo-基础搭建" class="headerlink" title="Hexo 基础搭建"></a>Hexo 基础搭建</h1><ul><li>参考 <a href="/posts/20251010083637.html" title="Hello World">Hello World</a> 可快速搭建Hexo框架的博客和发布文章</li></ul><h1 id="应用主题-Butterfly"><a href="#应用主题-Butterfly" class="headerlink" title="应用主题 Butterfly"></a>应用主题 Butterfly</h1><h2 id="yarn-拉取依赖-启用主题"><a href="#yarn-拉取依赖-启用主题" class="headerlink" title="yarn 拉取依赖 启用主题"></a>yarn 拉取依赖 启用主题</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">yarn add hexo-theme-butterfly # 安装 butterfly 主题</span><br><span class="line">yarn add hexo-renderer-pug hexo-renderer-stylus # 安装 pug 以及 stylus 的渲染器</span><br></pre></td></tr></table></figure><ul><li>在根目录下的<code>_config.yml</code>中配置主题</li></ul><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">themes:</span> <span class="string">butterfly</span></span><br></pre></td></tr></table></figure><ul><li>在博客根目录中创建 <a href="#Butterfly%E3%81%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E9%80%9F%E8%AF%BB%E7%BF%BB%E8%AF%91">_config.butterfly.yml</a></li></ul><blockquote><p>这里先说明一下怎么引入创建的<code>css</code>或者<code>js</code>（在博客根目录<code>source</code>中选择性新建<code>_data</code><code>css</code><code>js</code><code>img</code>）<br>打开<code>_config.butterfly.yml</code> 文件，找到 <code>Inject</code> 部分，这里以 <code>custom.css</code> 和 <code>title.js</code> 为例，注意这两个都为本地文件，在线网址也一样，更改 <code>href=</code> 和 <code>src=</code> 里面的内容就行</p></blockquote><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">inject:</span></span><br><span class="line">  <span class="attr">head:</span></span><br><span class="line">  <span class="comment"># - &lt;link rel=&quot;stylesheet&quot; href=&quot;/xxx.css&quot;&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;stylesheet&quot;</span> <span class="string">href=&quot;/css/custom.css&quot;&gt;</span></span><br><span class="line">  <span class="attr">bottom:</span></span><br><span class="line">  <span class="comment"># - &lt;script src=&quot;xxxx&quot;&gt;&lt;/script&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">async</span> <span class="string">src=&quot;/js/title.js&quot;&gt;&lt;/script&gt;</span></span><br></pre></td></tr></table></figure><blockquote><p><code>Hexo</code> 会自动合并主题中的 <code>_config.yml</code> 和 <code>_config.butterfly.yml</code> 里的配置。<br>会优先使用 _<code>_config.butterfly.yml</code> 的配置，其优先度较高。</p></blockquote><ul><li>后续对<code>butterfly</code>主题的美化配置就在<code>_config.butterfly.yml</code>进行修改就可以了~</li></ul><h2 id="背景美化"><a href="#背景美化" class="headerlink" title="背景美化"></a>背景美化</h2><h3 id="背景一图流"><a href="#背景一图流" class="headerlink" title="背景一图流"></a>背景一图流</h3><ol><li><p>设置背景<br> 修改主题配置文件_<code>_config.butterfly.yml</code><br> 编辑 <code>index_img</code>、<code>background</code>、<code>footer_img</code> 选项。<br> 设置网站背景，并将主页顶部图和页脚背景改为透明。(需要将以下示例地址替换为自己的图片地址。可以用一张具体的图片，也可以用随机图 api，随机显示图片)</p> <figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 首页的横幅图片</span></span><br><span class="line"><span class="attr">index_img:</span> <span class="string">transparent</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 归档页的横幅图片</span></span><br><span class="line"><span class="attr">archive_img:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 注意: 是标签页（单个标签），不是标签页面（所有标签）</span></span><br><span class="line"><span class="attr">tag_img:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 标签页的横幅图片，可为每个标签单独设置</span></span><br><span class="line"><span class="comment"># 格式:</span></span><br><span class="line"><span class="comment">#  - 标签名: 图片链接</span></span><br><span class="line"><span class="attr">tag_per_img:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 注意: 是分类页（单个分类），不是分类页面（所有分类）</span></span><br><span class="line"><span class="attr">category_img:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 分类页的横幅图片，可为每个分类单独设置</span></span><br><span class="line"><span class="comment"># 格式:</span></span><br><span class="line"><span class="comment">#  - 分类名: 图片链接</span></span><br><span class="line"><span class="attr">category_per_img:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 页脚的背景图片</span></span><br><span class="line"><span class="attr">footer_img:</span> <span class="string">transparent</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 网站背景</span></span><br><span class="line"><span class="comment"># 可设置为颜色或图片链接</span></span><br><span class="line"><span class="attr">background:</span> <span class="string">https://www.helloimg.com/i/2025/10/27/68ff0e506e4bb.png</span></span><br></pre></td></tr></table></figure></li><li><p>引入相关样式<br>新建一个文件，位于 <code>source/css/modify.styl</code>，并增加以下内容</p> <figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">@import</span> <span class="string">&#x27;nib&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 顶部图</span></span><br><span class="line"><span class="selector-id">#page-header</span></span><br><span class="line">  &amp;, <span class="selector-pseudo">&amp;:before</span></span><br><span class="line">    <span class="attribute">background</span>: transparent <span class="meta">!important</span></span><br><span class="line">  &amp;<span class="selector-class">.post-bg</span>, &amp;<span class="selector-class">.not-home-page</span></span><br><span class="line">    <span class="attribute">height</span>: <span class="number">280px</span> <span class="meta">!important</span></span><br><span class="line">  <span class="selector-id">#post-info</span></span><br><span class="line">    <span class="attribute">bottom</span>: <span class="number">40px</span> <span class="meta">!important</span></span><br><span class="line">  <span class="selector-id">#page-site-info</span></span><br><span class="line">    <span class="attribute">top</span>: <span class="number">140px</span> <span class="meta">!important</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">@media</span> screen <span class="keyword">and</span> (<span class="attribute">max-width</span>: <span class="number">768px</span>)</span><br><span class="line">    &amp;.not-home-page</span><br><span class="line">      <span class="attribute">height</span>: <span class="number">200px</span> !important</span><br><span class="line">    #post-info</span><br><span class="line">      bottom: <span class="number">10px</span> !important</span><br><span class="line">    #page-site-info</span><br><span class="line">      top: <span class="number">100px</span> !important</span><br><span class="line"></span><br><span class="line">.top-img</span><br><span class="line">  <span class="attribute">height</span>: <span class="number">250px</span></span><br><span class="line">  margin: -<span class="number">50px</span> -<span class="number">40px</span> <span class="number">50px</span></span><br><span class="line">  border-top-left-radius: inherit</span><br><span class="line">  border-top-right-radius: inherit</span><br><span class="line">  background-position: center center</span><br><span class="line">  background-size: cover</span><br><span class="line">  transition: all <span class="number">0.3s</span></span><br><span class="line"></span><br><span class="line">  @media screen <span class="keyword">and</span> (<span class="attribute">max-width</span>: <span class="number">768px</span>)</span><br><span class="line">    <span class="attribute">height</span>: <span class="number">230px</span></span><br><span class="line">    margin: -<span class="number">36px</span> -<span class="number">14px</span> <span class="number">36px</span></span><br><span class="line"></span><br><span class="line">  [data-theme=&#x27;dark&#x27;] &amp;</span><br><span class="line">    filter: brightness(<span class="number">0.8</span>)</span><br><span class="line"></span><br><span class="line">// 页脚</span><br><span class="line">#footer:before</span><br><span class="line">  background-color: alpha(#FFF, .<span class="number">5</span>)</span><br><span class="line"></span><br><span class="line">  [data-theme=&#x27;dark&#x27;] &amp;</span><br><span class="line">    background-color: alpha(#<span class="number">000</span>, .<span class="number">5</span>)</span><br><span class="line"></span><br><span class="line">#footer-wrap, #footer-wrap a</span><br><span class="line">  <span class="attribute">color</span>: #<span class="number">111</span></span><br><span class="line">  transition: unset</span><br><span class="line"></span><br><span class="line">  [data-theme=&#x27;dark&#x27;] &amp;</span><br><span class="line">    <span class="attribute">color</span>: var(--light-grey)</span><br></pre></td></tr></table></figure><p>在主题配置文件 <code>_config.butterfly.yml</code> 的 <code>inject.head</code> 引入样式</p> <figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">inject:</span></span><br><span class="line">  <span class="attr">head:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;stylesheet&quot;</span> <span class="string">href=&quot;/css/modify.css&quot;&gt;</span></span><br></pre></td></tr></table></figure><blockquote><p>说明：<code>modify.styl</code> 会被 <code>Hexo</code> 渲染成 <code>modify.css</code> 文件，所以此处应为 <code>modify.css</code></p></blockquote></li><li><p>增加插件脚本<br>因为使用了 <code>cheerio</code> 来解析 <code>HTML</code>，所以需要先安装此依赖</p> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yarn add cheerio</span><br></pre></td></tr></table></figure><blockquote><p>这里强调一下有很多宝子看错路径哦【<code>scripts/modify.js</code>】<br> 新建一个文件，位于 <code>scripts/modify.js</code>，并增加以下内容</p></blockquote> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&quot;use strict&quot;</span>;</span><br><span class="line"><span class="keyword">const</span> cheerio = <span class="built_in">require</span>(<span class="string">&quot;cheerio&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 在页面插入新顶部图</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">cheerio.Root</span>&#125; $ Root</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">insertTopImg</span>(<span class="params">$</span>) &#123;</span><br><span class="line">    <span class="keyword">let</span> header = $(<span class="string">&quot;#page-header&quot;</span>);</span><br><span class="line">    <span class="keyword">if</span> (header.<span class="property">length</span> === <span class="number">0</span>) <span class="keyword">return</span>;</span><br><span class="line">    <span class="keyword">let</span> background = header.<span class="title function_">css</span>(<span class="string">&quot;background-image&quot;</span>);</span><br><span class="line">    <span class="keyword">if</span> (!background) <span class="keyword">return</span>;</span><br><span class="line">    $(<span class="string">&quot;#post, #page, #archive, #tag, #category&quot;</span>).<span class="title function_">prepend</span>(</span><br><span class="line">        <span class="string">`&lt;div class=&quot;top-img&quot; style=&quot;background-image: <span class="subst">$&#123;background&#125;</span>;&quot;&gt;&lt;/div&gt;`</span></span><br><span class="line">    );</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">hexo.<span class="property">extend</span>.<span class="property">filter</span>.<span class="title function_">register</span>(<span class="string">&quot;after_render:html&quot;</span>, <span class="keyword">function</span> (<span class="params">str, data</span>) &#123;</span><br><span class="line">    <span class="keyword">let</span> $ = cheerio.<span class="title function_">load</span>(str, &#123;</span><br><span class="line">        <span class="attr">decodeEntities</span>: <span class="literal">false</span>,</span><br><span class="line">    &#125;);</span><br><span class="line">    <span class="title function_">insertTopImg</span>($);</span><br><span class="line">    <span class="keyword">return</span> $.<span class="title function_">html</span>();</span><br><span class="line">&#125;);</span><br><span class="line"></span><br></pre></td></tr></table></figure></li></ol><h3 id="背景透明设置"><a href="#背景透明设置" class="headerlink" title="背景透明设置"></a>背景透明设置</h3><blockquote><p>参考教程：<a href="https://moonshuo.cn/posts/12667.html#%E8%83%8C%E6%99%AF%E9%80%8F%E6%98%8E%E8%AE%BE%E7%BD%AE%E4%BF%AE%E5%A4%8D">Hexo 中 Buttefly 主题美化进阶续篇（十一） | 偷掉月亮 (moonshuo.cn)</a></p></blockquote><p>根据自己的喜好进行了更改，添加以下代码到 <code>custom.css</code> 文件（或者自己新建一个），然后在主题配置项引入 <code>css</code> 文件</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 背景透明度 */</span></span><br><span class="line"><span class="selector-pseudo">:root</span> &#123;</span><br><span class="line">    <span class="attr">--trans-light</span>: <span class="built_in">rgba</span>(<span class="number">255</span>, <span class="number">255</span>, <span class="number">255</span>, <span class="number">0.8</span>);</span><br><span class="line">    <span class="attr">--trans-dark</span>: <span class="built_in">rgba</span>(<span class="number">25</span>, <span class="number">25</span>, <span class="number">25</span>, <span class="number">0.8</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 首页文章卡片 */</span></span><br><span class="line"><span class="selector-id">#recent-posts</span>&gt;<span class="selector-class">.recent-post-item</span> &#123;</span><br><span class="line">    <span class="attribute">background</span>: <span class="built_in">var</span>(--trans-light);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 首页侧栏卡片 */</span></span><br><span class="line"><span class="selector-id">#aside-content</span> <span class="selector-class">.card-widget</span> &#123;</span><br><span class="line">    <span class="attribute">background</span>: <span class="built_in">var</span>(--trans-light);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 文章页、归档页、普通页面 */</span></span><br><span class="line"><span class="selector-tag">div</span><span class="selector-id">#post</span>,</span><br><span class="line"><span class="selector-tag">div</span><span class="selector-id">#page</span>,</span><br><span class="line"><span class="selector-tag">div</span><span class="selector-id">#archive</span> &#123;</span><br><span class="line">    <span class="attribute">background</span>: <span class="built_in">var</span>(--trans-light);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 导航栏 */</span></span><br><span class="line"><span class="selector-id">#page-header</span><span class="selector-class">.nav-fixed</span> <span class="selector-id">#nav</span> &#123;</span><br><span class="line">    <span class="attribute">background</span>: <span class="built_in">rgba</span>(<span class="number">255</span>, <span class="number">255</span>, <span class="number">255</span>, <span class="number">0.88</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> <span class="selector-id">#page-header</span><span class="selector-class">.nav-fixed</span> <span class="selector-id">#nav</span> &#123;</span><br><span class="line">    <span class="attribute">background</span>: <span class="built_in">rgba</span>(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.7</span>) <span class="meta">!important</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 夜间模式遮罩 */</span></span><br><span class="line"><span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> <span class="selector-id">#recent-posts</span>&gt;<span class="selector-class">.recent-post-item</span>,</span><br><span class="line"><span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> <span class="selector-id">#aside-content</span> <span class="selector-class">.card-widget</span>,</span><br><span class="line"><span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> <span class="selector-tag">div</span><span class="selector-id">#post</span>,</span><br><span class="line"><span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> <span class="selector-tag">div</span><span class="selector-id">#archive</span>,</span><br><span class="line"><span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> <span class="selector-tag">div</span><span class="selector-id">#page</span> &#123;</span><br><span class="line">    <span class="attribute">background</span>: <span class="built_in">var</span>(--trans-dark);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 夜间模式页脚页头遮罩透明 */</span></span><br><span class="line"><span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> <span class="selector-id">#footer</span><span class="selector-pseudo">::before</span> &#123;</span><br><span class="line">    <span class="attribute">background</span>: transparent <span class="meta">!important</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> <span class="selector-id">#page-header</span><span class="selector-pseudo">::before</span> &#123;</span><br><span class="line">    <span class="attribute">background</span>: transparent <span class="meta">!important</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 阅读模式 */</span></span><br><span class="line"><span class="selector-class">.read-mode</span> <span class="selector-id">#aside-content</span> <span class="selector-class">.card-widget</span> &#123;</span><br><span class="line">    <span class="attribute">background</span>: <span class="built_in">rgba</span>(<span class="number">249</span>, <span class="number">245</span>, <span class="number">233</span>, <span class="number">0.9</span>) <span class="meta">!important</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.read-mode</span> <span class="selector-tag">div</span><span class="selector-id">#post</span> &#123;</span><br><span class="line">    <span class="attribute">background</span>: <span class="built_in">rgba</span>(<span class="number">249</span>, <span class="number">245</span>, <span class="number">233</span>, <span class="number">0.9</span>) <span class="meta">!important</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 夜间模式下的阅读模式 */</span></span><br><span class="line"><span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> <span class="selector-class">.read-mode</span> <span class="selector-id">#aside-content</span> <span class="selector-class">.card-widget</span> &#123;</span><br><span class="line">    <span class="attribute">background</span>: <span class="built_in">rgba</span>(<span class="number">25</span>, <span class="number">25</span>, <span class="number">25</span>, <span class="number">0.9</span>) <span class="meta">!important</span>;</span><br><span class="line">    <span class="attribute">color</span>: <span class="number">#ffffff</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-attr">[data-theme=<span class="string">&quot;dark&quot;</span>]</span> <span class="selector-class">.read-mode</span> <span class="selector-tag">div</span><span class="selector-id">#post</span> &#123;</span><br><span class="line">    <span class="attribute">background</span>: <span class="built_in">rgba</span>(<span class="number">25</span>, <span class="number">25</span>, <span class="number">25</span>, <span class="number">0.9</span>) <span class="meta">!important</span>;</span><br><span class="line">    <span class="attribute">color</span>: <span class="number">#ffffff</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="站点动态-title"><a href="#站点动态-title" class="headerlink" title="站点动态 title"></a>站点动态 title</h3><p>站点动态 <code>title</code> 是通过 <code>js</code> 监测是否聚焦于当前页面，从而替换标签显示内容</p><ol><li>在博客根目录下的<code>source</code>中<code>js</code>文件夹中新建<code>title.js</code> <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//动态标题</span></span><br><span class="line"><span class="keyword">var</span> <span class="title class_">OriginTitile</span> = <span class="variable language_">document</span>.<span class="property">title</span>;</span><br><span class="line"><span class="keyword">var</span> titleTime;</span><br><span class="line"><span class="variable language_">document</span>.<span class="title function_">addEventListener</span>(<span class="string">&#x27;visibilitychange&#x27;</span>, <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="variable language_">document</span>.<span class="property">hidden</span>) &#123;</span><br><span class="line">        <span class="comment">//离开当前页面时标签显示内容</span></span><br><span class="line">        <span class="variable language_">document</span>.<span class="property">title</span> = <span class="string">&#x27;w(ﾟДﾟ)w 不要走！再看看嘛！&#x27;</span>;</span><br><span class="line">        <span class="built_in">clearTimeout</span>(titleTime);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment">//返回当前页面时标签显示内容</span></span><br><span class="line">        <span class="variable language_">document</span>.<span class="property">title</span> = <span class="string">&#x27;♪(^∇^*)欢迎回来！&#x27;</span> + <span class="title class_">OriginTitile</span>;</span><br><span class="line">        <span class="comment">//两秒后变回正常标题</span></span><br><span class="line">        titleTime = <span class="built_in">setTimeout</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">            <span class="variable language_">document</span>.<span class="property">title</span> = <span class="title class_">OriginTitile</span>;</span><br><span class="line">        &#125;, <span class="number">2000</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></li><li>在主题配置文件 <code>_config.butterfly.yml</code> 的 <code>inject.bottom</code> 引入样式，此处因为这是个独立的 <code>js</code>，而且体量极小，所以可以添加 <code>async</code> 异步加载标签 <figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">inject:</span></span><br><span class="line">  <span class="attr">bottom:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">async</span> <span class="string">src=&quot;/js/title.js&quot;&gt;&lt;/script&gt;</span></span><br></pre></td></tr></table></figure></li></ol><h3 id="修改标题样式-旋转小风车"><a href="#修改标题样式-旋转小风车" class="headerlink" title="修改标题样式-旋转小风车"></a>修改标题样式-旋转小风车</h3><ol><li>在主题配置文件中，更改相关配置如下，下面对应的为小风车的编号，可以更改为自己的编号</li><li>在博客根目录下的<code>source</code>中<code>css</code>文件夹中新建<code>custom.css</code>文件（若已存在可以考虑追加内容）（也可以按照自己喜好命名）<br>在主题配置文件<code>_config.butterfly.yml</code> 中引入对应的 <code>css</code> 文件，将以下代码复制到新建的 <code>custom.css</code> 中 <figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 文章页H1-H6图标样式效果 */</span></span><br><span class="line"><span class="comment">/* 控制风车转动速度 4s那里可以自己调节快慢 */</span></span><br><span class="line"><span class="selector-tag">h1</span><span class="selector-pseudo">::before</span>,</span><br><span class="line"><span class="selector-tag">h2</span><span class="selector-pseudo">::before</span>,</span><br><span class="line"><span class="selector-tag">h3</span><span class="selector-pseudo">::before</span>,</span><br><span class="line"><span class="selector-tag">h4</span><span class="selector-pseudo">::before</span>,</span><br><span class="line"><span class="selector-tag">h5</span><span class="selector-pseudo">::before</span>,</span><br><span class="line"><span class="selector-tag">h6</span><span class="selector-pseudo">::before</span> &#123;</span><br><span class="line">    -webkit-<span class="attribute">animation</span>: ccc <span class="number">4s</span> linear infinite;</span><br><span class="line">    <span class="attribute">animation</span>: ccc <span class="number">4s</span> linear infinite;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 控制风车转动方向 -1turn 为逆时针转动，1turn 为顺时针转动，相同数字部分记得统一修改 */</span></span><br><span class="line"><span class="keyword">@-webkit-keyframes</span> ccc &#123;</span><br><span class="line">    <span class="number">0%</span> &#123;</span><br><span class="line">        -webkit-<span class="attribute">transform</span>: <span class="built_in">rotate</span>(<span class="number">0deg</span>);</span><br><span class="line">        <span class="attribute">transform</span>: <span class="built_in">rotate</span>(<span class="number">0deg</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="selector-tag">to</span> &#123;</span><br><span class="line">        -webkit-<span class="attribute">transform</span>: <span class="built_in">rotate</span>(-<span class="number">1turn</span>);</span><br><span class="line">        <span class="attribute">transform</span>: <span class="built_in">rotate</span>(-<span class="number">1turn</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">@keyframes</span> ccc &#123;</span><br><span class="line">    <span class="number">0%</span> &#123;</span><br><span class="line">        -webkit-<span class="attribute">transform</span>: <span class="built_in">rotate</span>(<span class="number">0deg</span>);</span><br><span class="line">        <span class="attribute">transform</span>: <span class="built_in">rotate</span>(<span class="number">0deg</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="selector-tag">to</span> &#123;</span><br><span class="line">        -webkit-<span class="attribute">transform</span>: <span class="built_in">rotate</span>(-<span class="number">1turn</span>);</span><br><span class="line">        <span class="attribute">transform</span>: <span class="built_in">rotate</span>(-<span class="number">1turn</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 设置风车颜色 */</span></span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h1</span><span class="selector-pseudo">::before</span> &#123;</span><br><span class="line">    <span class="attribute">color</span>: <span class="number">#ef50a8</span>;</span><br><span class="line">    <span class="attribute">margin-left</span>: -<span class="number">1.55rem</span>;</span><br><span class="line">    <span class="attribute">font-size</span>: <span class="number">1.3rem</span>;</span><br><span class="line">    <span class="attribute">margin-top</span>: -<span class="number">0.23rem</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h2</span><span class="selector-pseudo">::before</span> &#123;</span><br><span class="line">    <span class="attribute">color</span>: <span class="number">#fb7061</span>;</span><br><span class="line">    <span class="attribute">margin-left</span>: -<span class="number">1.35rem</span>;</span><br><span class="line">    <span class="attribute">font-size</span>: <span class="number">1.1rem</span>;</span><br><span class="line">    <span class="attribute">margin-top</span>: -<span class="number">0.12rem</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h3</span><span class="selector-pseudo">::before</span> &#123;</span><br><span class="line">    <span class="attribute">color</span>: <span class="number">#ffbf00</span>;</span><br><span class="line">    <span class="attribute">margin-left</span>: -<span class="number">1.22rem</span>;</span><br><span class="line">    <span class="attribute">font-size</span>: <span class="number">0.95rem</span>;</span><br><span class="line">    <span class="attribute">margin-top</span>: -<span class="number">0.09rem</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h4</span><span class="selector-pseudo">::before</span> &#123;</span><br><span class="line">    <span class="attribute">color</span>: <span class="number">#a9e000</span>;</span><br><span class="line">    <span class="attribute">margin-left</span>: -<span class="number">1.05rem</span>;</span><br><span class="line">    <span class="attribute">font-size</span>: <span class="number">0.8rem</span>;</span><br><span class="line">    <span class="attribute">margin-top</span>: -<span class="number">0.09rem</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h5</span><span class="selector-pseudo">::before</span> &#123;</span><br><span class="line">    <span class="attribute">color</span>: <span class="number">#57c850</span>;</span><br><span class="line">    <span class="attribute">margin-left</span>: -<span class="number">0.9rem</span>;</span><br><span class="line">    <span class="attribute">font-size</span>: <span class="number">0.7rem</span>;</span><br><span class="line">    <span class="attribute">margin-top</span>: <span class="number">0rem</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h6</span><span class="selector-pseudo">::before</span> &#123;</span><br><span class="line">    <span class="attribute">color</span>: <span class="number">#5ec1e0</span>;</span><br><span class="line">    <span class="attribute">margin-left</span>: -<span class="number">0.9rem</span>;</span><br><span class="line">    <span class="attribute">font-size</span>: <span class="number">0.66rem</span>;</span><br><span class="line">    <span class="attribute">margin-top</span>: <span class="number">0rem</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* s设置风车hover动效 6s那里可以自己调节快慢*/</span></span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h1</span><span class="selector-pseudo">:hover</span>,</span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h2</span><span class="selector-pseudo">:hover</span>,</span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h3</span><span class="selector-pseudo">:hover</span>,</span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h4</span><span class="selector-pseudo">:hover</span>,</span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h5</span><span class="selector-pseudo">:hover</span>,</span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h6</span><span class="selector-pseudo">:hover</span> &#123;</span><br><span class="line">    <span class="attribute">color</span>: <span class="built_in">var</span>(--theme-color);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h1</span><span class="selector-pseudo">:hover</span><span class="selector-pseudo">::before</span>,</span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h2</span><span class="selector-pseudo">:hover</span><span class="selector-pseudo">::before</span>,</span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h3</span><span class="selector-pseudo">:hover</span><span class="selector-pseudo">::before</span>,</span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h4</span><span class="selector-pseudo">:hover</span><span class="selector-pseudo">::before</span>,</span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h5</span><span class="selector-pseudo">:hover</span><span class="selector-pseudo">::before</span>,</span><br><span class="line"><span class="selector-id">#content-inner</span><span class="selector-class">.layout</span> <span class="selector-tag">h6</span><span class="selector-pseudo">:hover</span><span class="selector-pseudo">::before</span> &#123;</span><br><span class="line">    <span class="attribute">color</span>: <span class="built_in">var</span>(--theme-color);</span><br><span class="line">    -webkit-<span class="attribute">animation</span>: ccc <span class="number">6s</span> linear infinite;</span><br><span class="line">    <span class="attribute">animation</span>: ccc <span class="number">6s</span> linear infinite;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ol><h1 id="评论系统-Waline"><a href="#评论系统-Waline" class="headerlink" title="评论系统 Waline"></a>评论系统 Waline</h1><h2 id="配置-waline"><a href="#配置-waline" class="headerlink" title="配置 waline"></a>配置 waline</h2><h3 id="启用-配置-Waline"><a href="#启用-配置-Waline" class="headerlink" title="启用&amp;配置 Waline"></a>启用&amp;配置 Waline</h3><ul><li>在 <a href="#Butterfly%E3%81%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E9%80%9F%E8%AF%BB%E7%BF%BB%E8%AF%91">_config.butterfly.yml</a> 中按照如下格式启用 <a href="https://waline.js.org/guide/get-started/">Waline</a> （可直达快速开始文档搭建部署自己的评论系统）</li></ul><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 评论系统</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="attr">comments:</span></span><br><span class="line">  <span class="comment"># 最多启用两个评论系统，第一个为默认</span></span><br><span class="line">  <span class="comment"># 无需则留空</span></span><br><span class="line">  <span class="comment"># 选择：Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/Artalk</span></span><br><span class="line">  <span class="comment"># 双系统格式：Disqus,Waline</span></span><br><span class="line">  <span class="attr">use:</span> <span class="string">Waline</span></span><br><span class="line">  <span class="comment"># 按钮旁是否显示评论系统名称</span></span><br><span class="line">  <span class="attr">text:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 懒加载：评论区进入浏览器视口才加载</span></span><br><span class="line">  <span class="comment"># 设为true则评论计数失效</span></span><br><span class="line">  <span class="attr">lazyload:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 文章头图中是否显示评论数</span></span><br><span class="line">  <span class="attr">count:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 首页是否显示评论数</span></span><br><span class="line">  <span class="attr">card_post_count:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Waline评论系统 - 基于Valine开发的带后端支持的简易评论系统（参考文档：https://waline.js.org/）</span></span><br><span class="line"><span class="attr">waline:</span></span><br><span class="line">  <span class="comment"># 服务器URL</span></span><br><span class="line">  <span class="attr">serverURL:</span> <span class="string">https://xxxxxx.vercel.app</span> <span class="comment">#替换为自己的服务器URL</span></span><br><span class="line">  <span class="comment"># 评论框背景图片</span></span><br><span class="line">  <span class="attr">bg:</span></span><br><span class="line">  <span class="comment"># 是否用Waline访客计数作为页面浏览量</span></span><br><span class="line">  <span class="attr">pageview:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 其他可选配置</span></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line">    <span class="attr">requireMeta:</span> [ <span class="string">nick</span>, <span class="string">mail</span> ] <span class="comment"># 配置了也没啥用，还是能提交</span></span><br><span class="line">    <span class="attr">locale:</span></span><br><span class="line">      <span class="attr">placeholder:</span> <span class="string">小站已开启评论审核，可匿名评论，但评论需要通过审核后才能够出现在评论区哦~</span></span><br><span class="line">    <span class="comment"># 表情包网上也有很多哦</span></span><br><span class="line">    <span class="attr">emoji:</span> [</span><br><span class="line">      <span class="string">&#x27;https://unpkg.com/@waline/emojis@1.2.0/alus&#x27;</span>,</span><br><span class="line">      <span class="string">&#x27;https://unpkg.com/@waline/emojis@1.2.0/weibo&#x27;</span></span><br><span class="line">    ]</span><br><span class="line">    <span class="attr">pageSize:</span> <span class="number">10</span> <span class="comment"># 评论每页显示数量</span></span><br><span class="line">    <span class="attr">highlight:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 让评论区也支持黑夜模式</span></span><br><span class="line">  <span class="attr">dark:</span> <span class="string">&#x27;html[data-user-color-scheme=&quot;dark&quot;]&#x27;</span></span><br></pre></td></tr></table></figure><h2 id="添加gif动图在评论区右侧"><a href="#添加gif动图在评论区右侧" class="headerlink" title="添加gif动图在评论区右侧"></a>添加gif动图在评论区右侧</h2><p>新建一个文件，位于 <code>source/css/waline.styl</code>，并增加以下内容在主题配置文件<code>_config.butterfly.yml</code> 中引入对应的 <code>waline.css</code> 文件</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-id">#wl-edit</span> &#123;</span><br><span class="line">  <span class="attribute">background</span>: <span class="built_in">url</span>(<span class="string">&quot;https://xxxxxxx.gif&quot;</span>) <span class="number">100%</span> <span class="number">100%</span> no-repeat; <span class="comment">// 小图可自行寻找哦</span></span><br><span class="line">  <span class="attribute">background-size</span>: contain <span class="meta">!important</span>;</span><br><span class="line">  <span class="attribute">background-repeat</span>: no-repeat <span class="meta">!important</span>;</span><br><span class="line">  <span class="attribute">background-position</span>: right bottom <span class="meta">!important</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-id">#waline-wrap</span> <span class="selector-tag">textarea</span><span class="selector-pseudo">:focus</span> &#123;</span><br><span class="line">  <span class="attribute">background-position-y</span>: <span class="number">78px</span> <span class="meta">!important</span>;</span><br><span class="line">  <span class="attribute">transition</span>: all <span class="number">0.25s</span> ease-in-out <span class="number">0s</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="walineの服务配置"><a href="#walineの服务配置" class="headerlink" title="walineの服务配置"></a>walineの服务配置</h3><ul><li><code>GitHub</code> 中 修改提交 <code>vercel</code> 会自动构建</li><li>在 <code>package.json</code> 中 添加 <code>axios</code> 和 <code>waline-link-interceptor</code> 依赖</li></ul><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;template&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="string">&quot;0.0.1&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;private&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;dependencies&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;@waline/vercel&quot;</span><span class="punctuation">:</span> <span class="string">&quot;latest&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;axios&quot;</span><span class="punctuation">:</span> <span class="string">&quot;latest&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;waline-link-interceptor&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^0.1.2&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><ul><li><div style="display: flex; align-items: center; gap: 8px;">在 <code>index.cjs</code> 按照如下格式配置（本评论系统通知采用<a href="https://qmsg.zendee.cn" target="_blank" style="display: flex; align-items: center; gap: 4px;"><img style="margin: 0; vertical-align: middle;" height="40px" src="https://qmsg.zendee.cn/img/icon.png" width="40px" alt="Qmsg酱"/>Qmsg酱</a>）</div></li><li>提示：发送消息到<code>QQ</code>中最好不要带链接（<code>msg</code>）和敏感词等，否则会提示消息违规</li></ul><figure class="highlight cjs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title class_">Application</span> = <span class="built_in">require</span>(<span class="string">&#x27;@waline/vercel&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> axios = <span class="built_in">require</span>(<span class="string">&#x27;axios&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> <span class="title class_">LinkInterceptor</span> = <span class="built_in">require</span>(<span class="string">&#x27;waline-link-interceptor&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 自定义环境变量</span></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">MY_EV_VAR</span> = &#123;</span><br><span class="line">  <span class="comment">// QMsg酱的key</span></span><br><span class="line">  <span class="attr">qMsgKey</span>: <span class="string">&quot;xxxxxxx&quot;</span>,</span><br><span class="line">  <span class="comment">// 作者邮箱</span></span><br><span class="line">  <span class="attr">authorEmail</span>: <span class="string">&quot;xxxxxx@qq.com&quot;</span>,</span><br><span class="line">  <span class="comment">// 网站名称</span></span><br><span class="line">  <span class="attr">siteName</span>: <span class="string">&quot;小敏の晚风&quot;</span>,</span><br><span class="line">  <span class="comment">// 网站地址</span></span><br><span class="line">  <span class="attr">siteURL</span>: <span class="string">&quot;https://xmblog.chrislin.eu.org&quot;</span>,</span><br><span class="line">  <span class="comment">// QMsg酱消息发送接口地址</span></span><br><span class="line">  <span class="attr">qMsgApi</span>: <span class="string">&quot;https://qmsg.zendee.cn/send&quot;</span>,</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = <span class="title class_">Application</span>(&#123;</span><br><span class="line">  <span class="comment">// 违禁词</span></span><br><span class="line">  <span class="attr">forbiddenWords</span>: [<span class="string">&#x27;xxx&#x27;</span>, <span class="string">&#x27;yyy&#x27;</span>, <span class="string">&#x27;vvv&#x27;</span>], <span class="comment">// 违禁词部分内容不方便展示</span></span><br><span class="line">  <span class="attr">plugins</span>: [</span><br><span class="line">    <span class="title class_">LinkInterceptor</span>(&#123;</span><br><span class="line">      <span class="attr">whiteList</span>: [<span class="string">&#x27;chrislin.eu.org&#x27;</span>, <span class="string">&#x27;jieniyou.eu.org&#x27;</span>],</span><br><span class="line">      <span class="comment">// blackList: [],</span></span><br><span class="line">      <span class="comment">// interceptorTemplate: `hello __URL__ `,   // 如果下面自定义了跳转地址，那么此处模板不生效</span></span><br><span class="line">      <span class="attr">redirectUrl</span>: <span class="string">&quot;xmblog.chrislin.eu.org/go.html&quot;</span>, <span class="comment">// 填写中间页的具体 html 地址。</span></span><br><span class="line">      <span class="attr">encodeFunc</span>: <span class="function">(<span class="params">url</span>) =&gt;</span>&#123;</span><br><span class="line">        <span class="comment">// 填入一个外链 url 的处理函数</span></span><br><span class="line">        <span class="comment">// 启用 Base64 编码链接</span></span><br><span class="line">      <span class="keyword">return</span> <span class="string">&quot;u=&quot;</span> + <span class="title class_">Buffer</span>.<span class="title function_">from</span>(url).<span class="title function_">toString</span>(<span class="string">&#x27;base64&#x27;</span>) <span class="comment">// 或者 return &quot;u=&quot; + btoa(url)</span></span><br><span class="line">      &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">  ],</span><br><span class="line">  <span class="comment">// 评论发布后执行的操作，参数1：评论，参数2：回复评论的父级评论</span></span><br><span class="line">  <span class="comment">// 使用async的方法，方法体内调用方法一定配合await使用</span></span><br><span class="line">  <span class="keyword">async</span> <span class="title function_">postSave</span>(<span class="params">comment, pComment</span>) &#123;</span><br><span class="line">    <span class="comment">// 如果不是博主本人发的才通知</span></span><br><span class="line">    <span class="keyword">if</span> (comment.<span class="property">mail</span> != <span class="variable constant_">MY_EV_VAR</span>.<span class="property">authorEmail</span>) &#123;</span><br><span class="line">      </span><br><span class="line">      <span class="comment">// 使用axios发送post请求</span></span><br><span class="line">      <span class="keyword">const</span> formData = <span class="keyword">new</span> <span class="title class_">URLSearchParams</span>(); <span class="comment">// 转载数据</span></span><br><span class="line">      <span class="comment">// 将要发送的信息格式化好后装载到POST参数中</span></span><br><span class="line">      <span class="keyword">if</span> (pComment == <span class="literal">undefined</span>) &#123;</span><br><span class="line">        formData.<span class="title function_">append</span>(<span class="string">&#x27;msg&#x27;</span>, <span class="string">`💬 <span class="subst">$&#123;MY_EV_VAR.siteName&#125;</span> 有新评论啦\n<span class="subst">$&#123;comment.nick&#125;</span> 说:\n<span class="subst">$&#123;comment.comment&#125;</span>`</span>);</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        formData.<span class="title function_">append</span>(<span class="string">&#x27;msg&#x27;</span>, <span class="string">`💬 <span class="subst">$&#123;MY_EV_VAR.siteName&#125;</span> 有新评论啦\n<span class="subst">$&#123;comment.nick&#125;</span> 回复 <span class="subst">$&#123;pComment.nick&#125;</span> 的内容:\n<span class="subst">$&#123;pComment.comment&#125;</span>\n说:\n<span class="subst">$&#123;comment.comment&#125;</span>`</span>);</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="comment">// 给QMsg发送请求</span></span><br><span class="line">      <span class="keyword">await</span> axios.<span class="title function_">post</span>(<span class="string">`<span class="subst">$&#123;MY_EV_VAR.qMsgApi&#125;</span>/<span class="subst">$&#123;MY_EV_VAR.qMsgKey&#125;</span>`</span>, formData);</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h1 id="安全跳转页面·插件版"><a href="#安全跳转页面·插件版" class="headerlink" title="安全跳转页面·插件版"></a>安全跳转页面·插件版</h1><blockquote><p>参考<a href="https://blog.liushen.fun/posts/1dfd1f41">LiuShenの安全跳转页面·插件版</a></p></blockquote><ul><li>需要的依赖 <code>cheerio</code> 和 <code>hexo-safego</code></li></ul><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">yarn add cheerio</span><br><span class="line">yarn add hexo-safego</span><br></pre></td></tr></table></figure><ul><li>需要在博客根目录下<code>_config.yml</code>中添加如下代码</li><li>若需要评论系统的链接也被检测需要安全跳转需要在 <code>GitHub</code> 中 修改 <code>index.cjs</code> 添加 <code>plugin</code> 可参考<a href="#waline%E3%81%AE%E6%9C%8D%E5%8A%A1%E9%85%8D%E7%BD%AE">walineの服务配置</a></li></ul><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># hexo-safego安全跳转插件</span></span><br><span class="line"><span class="comment"># see https://blog.liushen.fun/posts/1dfd1f41/</span></span><br><span class="line"><span class="attr">hexo_safego:</span></span><br><span class="line">  <span class="comment"># 基本功能设置</span></span><br><span class="line">  <span class="attr">general:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">true</span>                <span class="comment"># 启用插件</span></span><br><span class="line">    <span class="attr">enable_base64_encode:</span> <span class="literal">true</span>  <span class="comment"># 使用 Base64 编码</span></span><br><span class="line">    <span class="attr">enable_target_blank:</span> <span class="literal">true</span>   <span class="comment"># 打开新窗口</span></span><br><span class="line">  <span class="comment"># 安全设置</span></span><br><span class="line">  <span class="attr">security:</span></span><br><span class="line">    <span class="attr">url_param_name:</span> <span class="string">&#x27;u&#x27;</span>         <span class="comment"># URL 参数名</span></span><br><span class="line">    <span class="attr">html_file_name:</span> <span class="string">&#x27;go.html&#x27;</span>   <span class="comment"># 重定向页面的文件名</span></span><br><span class="line">    <span class="attr">ignore_attrs:</span>               <span class="comment"># 忽略处理的 HTML 属性</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&#x27;data-fancybox&#x27;</span></span><br><span class="line">  <span class="comment"># 容器与页面设置</span></span><br><span class="line">  <span class="attr">scope:</span></span><br><span class="line">    <span class="attr">apply_containers:</span>           <span class="comment"># 应用的容器选择器</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&#x27;#article-container&#x27;</span></span><br><span class="line">    <span class="attr">apply_pages:</span>                <span class="comment"># 应用的页面路径</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;/posts/&quot;</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;/devices/&quot;</span></span><br><span class="line">    <span class="attr">exclude_pages:</span>              <span class="comment"># 排除的页面路径</span></span><br><span class="line">  <span class="comment"># 域名白名单</span></span><br><span class="line">  <span class="attr">whitelist:</span></span><br><span class="line">    <span class="attr">domain_whitelist:</span>           <span class="comment"># 允许的白名单域名</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;chrislin.eu.org&quot;</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;jieniyou.eu.org&quot;</span></span><br><span class="line">  <span class="comment"># 页面外观设置</span></span><br><span class="line">  <span class="attr">appearance:</span></span><br><span class="line">    <span class="attr">avatar:</span> <span class="string">https://www.helloimg.com/i/2025/10/23/68f9f902f1561.png</span>    <span class="comment"># 头像路径</span></span><br><span class="line">    <span class="attr">title:</span> <span class="string">&quot;小敏の晚风&quot;</span>            <span class="comment"># 页面标题</span></span><br><span class="line">    <span class="attr">subtitle:</span> <span class="string">&quot;安全中心&quot;</span>         <span class="comment"># 页面副标题</span></span><br><span class="line">    <span class="attr">darkmode:</span> <span class="literal">true</span>              <span class="comment"># 是否启用深色模式</span></span><br><span class="line">    <span class="attr">countdowntime:</span> <span class="number">-1</span>           <span class="comment"># 倒计时秒数</span></span><br><span class="line">  <span class="comment"># 调试设置</span></span><br><span class="line">  <span class="attr">debug:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">false</span>               <span class="comment"># 启用调试模式</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h1 id="Butterflyの配置文件速读翻译"><a href="#Butterflyの配置文件速读翻译" class="headerlink" title="Butterflyの配置文件速读翻译"></a>Butterflyの配置文件速读翻译</h1><ul><li><code>_config.butterfly.yml</code>：结合 <a href="https://butterfly.js.org/posts/4aa8abbe/#%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E9%80%9F%E8%AE%80">Butterfly 文檔(三) 主題配置 中的配置文件速读</a> 与 <a href="https://www.doubao.com/">豆包</a> 的智能翻译</li></ul><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br><span class="line">458</span><br><span class="line">459</span><br><span class="line">460</span><br><span class="line">461</span><br><span class="line">462</span><br><span class="line">463</span><br><span class="line">464</span><br><span class="line">465</span><br><span class="line">466</span><br><span class="line">467</span><br><span class="line">468</span><br><span class="line">469</span><br><span class="line">470</span><br><span class="line">471</span><br><span class="line">472</span><br><span class="line">473</span><br><span class="line">474</span><br><span class="line">475</span><br><span class="line">476</span><br><span class="line">477</span><br><span class="line">478</span><br><span class="line">479</span><br><span class="line">480</span><br><span class="line">481</span><br><span class="line">482</span><br><span class="line">483</span><br><span class="line">484</span><br><span class="line">485</span><br><span class="line">486</span><br><span class="line">487</span><br><span class="line">488</span><br><span class="line">489</span><br><span class="line">490</span><br><span class="line">491</span><br><span class="line">492</span><br><span class="line">493</span><br><span class="line">494</span><br><span class="line">495</span><br><span class="line">496</span><br><span class="line">497</span><br><span class="line">498</span><br><span class="line">499</span><br><span class="line">500</span><br><span class="line">501</span><br><span class="line">502</span><br><span class="line">503</span><br><span class="line">504</span><br><span class="line">505</span><br><span class="line">506</span><br><span class="line">507</span><br><span class="line">508</span><br><span class="line">509</span><br><span class="line">510</span><br><span class="line">511</span><br><span class="line">512</span><br><span class="line">513</span><br><span class="line">514</span><br><span class="line">515</span><br><span class="line">516</span><br><span class="line">517</span><br><span class="line">518</span><br><span class="line">519</span><br><span class="line">520</span><br><span class="line">521</span><br><span class="line">522</span><br><span class="line">523</span><br><span class="line">524</span><br><span class="line">525</span><br><span class="line">526</span><br><span class="line">527</span><br><span class="line">528</span><br><span class="line">529</span><br><span class="line">530</span><br><span class="line">531</span><br><span class="line">532</span><br><span class="line">533</span><br><span class="line">534</span><br><span class="line">535</span><br><span class="line">536</span><br><span class="line">537</span><br><span class="line">538</span><br><span class="line">539</span><br><span class="line">540</span><br><span class="line">541</span><br><span class="line">542</span><br><span class="line">543</span><br><span class="line">544</span><br><span class="line">545</span><br><span class="line">546</span><br><span class="line">547</span><br><span class="line">548</span><br><span class="line">549</span><br><span class="line">550</span><br><span class="line">551</span><br><span class="line">552</span><br><span class="line">553</span><br><span class="line">554</span><br><span class="line">555</span><br><span class="line">556</span><br><span class="line">557</span><br><span class="line">558</span><br><span class="line">559</span><br><span class="line">560</span><br><span class="line">561</span><br><span class="line">562</span><br><span class="line">563</span><br><span class="line">564</span><br><span class="line">565</span><br><span class="line">566</span><br><span class="line">567</span><br><span class="line">568</span><br><span class="line">569</span><br><span class="line">570</span><br><span class="line">571</span><br><span class="line">572</span><br><span class="line">573</span><br><span class="line">574</span><br><span class="line">575</span><br><span class="line">576</span><br><span class="line">577</span><br><span class="line">578</span><br><span class="line">579</span><br><span class="line">580</span><br><span class="line">581</span><br><span class="line">582</span><br><span class="line">583</span><br><span class="line">584</span><br><span class="line">585</span><br><span class="line">586</span><br><span class="line">587</span><br><span class="line">588</span><br><span class="line">589</span><br><span class="line">590</span><br><span class="line">591</span><br><span class="line">592</span><br><span class="line">593</span><br><span class="line">594</span><br><span class="line">595</span><br><span class="line">596</span><br><span class="line">597</span><br><span class="line">598</span><br><span class="line">599</span><br><span class="line">600</span><br><span class="line">601</span><br><span class="line">602</span><br><span class="line">603</span><br><span class="line">604</span><br><span class="line">605</span><br><span class="line">606</span><br><span class="line">607</span><br><span class="line">608</span><br><span class="line">609</span><br><span class="line">610</span><br><span class="line">611</span><br><span class="line">612</span><br><span class="line">613</span><br><span class="line">614</span><br><span class="line">615</span><br><span class="line">616</span><br><span class="line">617</span><br><span class="line">618</span><br><span class="line">619</span><br><span class="line">620</span><br><span class="line">621</span><br><span class="line">622</span><br><span class="line">623</span><br><span class="line">624</span><br><span class="line">625</span><br><span class="line">626</span><br><span class="line">627</span><br><span class="line">628</span><br><span class="line">629</span><br><span class="line">630</span><br><span class="line">631</span><br><span class="line">632</span><br><span class="line">633</span><br><span class="line">634</span><br><span class="line">635</span><br><span class="line">636</span><br><span class="line">637</span><br><span class="line">638</span><br><span class="line">639</span><br><span class="line">640</span><br><span class="line">641</span><br><span class="line">642</span><br><span class="line">643</span><br><span class="line">644</span><br><span class="line">645</span><br><span class="line">646</span><br><span class="line">647</span><br><span class="line">648</span><br><span class="line">649</span><br><span class="line">650</span><br><span class="line">651</span><br><span class="line">652</span><br><span class="line">653</span><br><span class="line">654</span><br><span class="line">655</span><br><span class="line">656</span><br><span class="line">657</span><br><span class="line">658</span><br><span class="line">659</span><br><span class="line">660</span><br><span class="line">661</span><br><span class="line">662</span><br><span class="line">663</span><br><span class="line">664</span><br><span class="line">665</span><br><span class="line">666</span><br><span class="line">667</span><br><span class="line">668</span><br><span class="line">669</span><br><span class="line">670</span><br><span class="line">671</span><br><span class="line">672</span><br><span class="line">673</span><br><span class="line">674</span><br><span class="line">675</span><br><span class="line">676</span><br><span class="line">677</span><br><span class="line">678</span><br><span class="line">679</span><br><span class="line">680</span><br><span class="line">681</span><br><span class="line">682</span><br><span class="line">683</span><br><span class="line">684</span><br><span class="line">685</span><br><span class="line">686</span><br><span class="line">687</span><br><span class="line">688</span><br><span class="line">689</span><br><span class="line">690</span><br><span class="line">691</span><br><span class="line">692</span><br><span class="line">693</span><br><span class="line">694</span><br><span class="line">695</span><br><span class="line">696</span><br><span class="line">697</span><br><span class="line">698</span><br><span class="line">699</span><br><span class="line">700</span><br><span class="line">701</span><br><span class="line">702</span><br><span class="line">703</span><br><span class="line">704</span><br><span class="line">705</span><br><span class="line">706</span><br><span class="line">707</span><br><span class="line">708</span><br><span class="line">709</span><br><span class="line">710</span><br><span class="line">711</span><br><span class="line">712</span><br><span class="line">713</span><br><span class="line">714</span><br><span class="line">715</span><br><span class="line">716</span><br><span class="line">717</span><br><span class="line">718</span><br><span class="line">719</span><br><span class="line">720</span><br><span class="line">721</span><br><span class="line">722</span><br><span class="line">723</span><br><span class="line">724</span><br><span class="line">725</span><br><span class="line">726</span><br><span class="line">727</span><br><span class="line">728</span><br><span class="line">729</span><br><span class="line">730</span><br><span class="line">731</span><br><span class="line">732</span><br><span class="line">733</span><br><span class="line">734</span><br><span class="line">735</span><br><span class="line">736</span><br><span class="line">737</span><br><span class="line">738</span><br><span class="line">739</span><br><span class="line">740</span><br><span class="line">741</span><br><span class="line">742</span><br><span class="line">743</span><br><span class="line">744</span><br><span class="line">745</span><br><span class="line">746</span><br><span class="line">747</span><br><span class="line">748</span><br><span class="line">749</span><br><span class="line">750</span><br><span class="line">751</span><br><span class="line">752</span><br><span class="line">753</span><br><span class="line">754</span><br><span class="line">755</span><br><span class="line">756</span><br><span class="line">757</span><br><span class="line">758</span><br><span class="line">759</span><br><span class="line">760</span><br><span class="line">761</span><br><span class="line">762</span><br><span class="line">763</span><br><span class="line">764</span><br><span class="line">765</span><br><span class="line">766</span><br><span class="line">767</span><br><span class="line">768</span><br><span class="line">769</span><br><span class="line">770</span><br><span class="line">771</span><br><span class="line">772</span><br><span class="line">773</span><br><span class="line">774</span><br><span class="line">775</span><br><span class="line">776</span><br><span class="line">777</span><br><span class="line">778</span><br><span class="line">779</span><br><span class="line">780</span><br><span class="line">781</span><br><span class="line">782</span><br><span class="line">783</span><br><span class="line">784</span><br><span class="line">785</span><br><span class="line">786</span><br><span class="line">787</span><br><span class="line">788</span><br><span class="line">789</span><br><span class="line">790</span><br><span class="line">791</span><br><span class="line">792</span><br><span class="line">793</span><br><span class="line">794</span><br><span class="line">795</span><br><span class="line">796</span><br><span class="line">797</span><br><span class="line">798</span><br><span class="line">799</span><br><span class="line">800</span><br><span class="line">801</span><br><span class="line">802</span><br><span class="line">803</span><br><span class="line">804</span><br><span class="line">805</span><br><span class="line">806</span><br><span class="line">807</span><br><span class="line">808</span><br><span class="line">809</span><br><span class="line">810</span><br><span class="line">811</span><br><span class="line">812</span><br><span class="line">813</span><br><span class="line">814</span><br><span class="line">815</span><br><span class="line">816</span><br><span class="line">817</span><br><span class="line">818</span><br><span class="line">819</span><br><span class="line">820</span><br><span class="line">821</span><br><span class="line">822</span><br><span class="line">823</span><br><span class="line">824</span><br><span class="line">825</span><br><span class="line">826</span><br><span class="line">827</span><br><span class="line">828</span><br><span class="line">829</span><br><span class="line">830</span><br><span class="line">831</span><br><span class="line">832</span><br><span class="line">833</span><br><span class="line">834</span><br><span class="line">835</span><br><span class="line">836</span><br><span class="line">837</span><br><span class="line">838</span><br><span class="line">839</span><br><span class="line">840</span><br><span class="line">841</span><br><span class="line">842</span><br><span class="line">843</span><br><span class="line">844</span><br><span class="line">845</span><br><span class="line">846</span><br><span class="line">847</span><br><span class="line">848</span><br><span class="line">849</span><br><span class="line">850</span><br><span class="line">851</span><br><span class="line">852</span><br><span class="line">853</span><br><span class="line">854</span><br><span class="line">855</span><br><span class="line">856</span><br><span class="line">857</span><br><span class="line">858</span><br><span class="line">859</span><br><span class="line">860</span><br><span class="line">861</span><br><span class="line">862</span><br><span class="line">863</span><br><span class="line">864</span><br><span class="line">865</span><br><span class="line">866</span><br><span class="line">867</span><br><span class="line">868</span><br><span class="line">869</span><br><span class="line">870</span><br><span class="line">871</span><br><span class="line">872</span><br><span class="line">873</span><br><span class="line">874</span><br><span class="line">875</span><br><span class="line">876</span><br><span class="line">877</span><br><span class="line">878</span><br><span class="line">879</span><br><span class="line">880</span><br><span class="line">881</span><br><span class="line">882</span><br><span class="line">883</span><br><span class="line">884</span><br><span class="line">885</span><br><span class="line">886</span><br><span class="line">887</span><br><span class="line">888</span><br><span class="line">889</span><br><span class="line">890</span><br><span class="line">891</span><br><span class="line">892</span><br><span class="line">893</span><br><span class="line">894</span><br><span class="line">895</span><br><span class="line">896</span><br><span class="line">897</span><br><span class="line">898</span><br><span class="line">899</span><br><span class="line">900</span><br><span class="line">901</span><br><span class="line">902</span><br><span class="line">903</span><br><span class="line">904</span><br><span class="line">905</span><br><span class="line">906</span><br><span class="line">907</span><br><span class="line">908</span><br><span class="line">909</span><br><span class="line">910</span><br><span class="line">911</span><br><span class="line">912</span><br><span class="line">913</span><br><span class="line">914</span><br><span class="line">915</span><br><span class="line">916</span><br><span class="line">917</span><br><span class="line">918</span><br><span class="line">919</span><br><span class="line">920</span><br><span class="line">921</span><br><span class="line">922</span><br><span class="line">923</span><br><span class="line">924</span><br><span class="line">925</span><br><span class="line">926</span><br><span class="line">927</span><br><span class="line">928</span><br><span class="line">929</span><br><span class="line">930</span><br><span class="line">931</span><br><span class="line">932</span><br><span class="line">933</span><br><span class="line">934</span><br><span class="line">935</span><br><span class="line">936</span><br><span class="line">937</span><br><span class="line">938</span><br><span class="line">939</span><br><span class="line">940</span><br><span class="line">941</span><br><span class="line">942</span><br><span class="line">943</span><br><span class="line">944</span><br><span class="line">945</span><br><span class="line">946</span><br><span class="line">947</span><br><span class="line">948</span><br><span class="line">949</span><br><span class="line">950</span><br><span class="line">951</span><br><span class="line">952</span><br><span class="line">953</span><br><span class="line">954</span><br><span class="line">955</span><br><span class="line">956</span><br><span class="line">957</span><br><span class="line">958</span><br><span class="line">959</span><br><span class="line">960</span><br><span class="line">961</span><br><span class="line">962</span><br><span class="line">963</span><br><span class="line">964</span><br><span class="line">965</span><br><span class="line">966</span><br><span class="line">967</span><br><span class="line">968</span><br><span class="line">969</span><br><span class="line">970</span><br><span class="line">971</span><br><span class="line">972</span><br><span class="line">973</span><br><span class="line">974</span><br><span class="line">975</span><br><span class="line">976</span><br><span class="line">977</span><br><span class="line">978</span><br><span class="line">979</span><br><span class="line">980</span><br><span class="line">981</span><br><span class="line">982</span><br><span class="line">983</span><br><span class="line">984</span><br><span class="line">985</span><br><span class="line">986</span><br><span class="line">987</span><br><span class="line">988</span><br><span class="line">989</span><br><span class="line">990</span><br><span class="line">991</span><br><span class="line">992</span><br><span class="line">993</span><br><span class="line">994</span><br><span class="line">995</span><br><span class="line">996</span><br><span class="line">997</span><br><span class="line">998</span><br><span class="line">999</span><br><span class="line">1000</span><br><span class="line">1001</span><br><span class="line">1002</span><br><span class="line">1003</span><br><span class="line">1004</span><br><span class="line">1005</span><br><span class="line">1006</span><br><span class="line">1007</span><br><span class="line">1008</span><br><span class="line">1009</span><br><span class="line">1010</span><br><span class="line">1011</span><br><span class="line">1012</span><br><span class="line">1013</span><br><span class="line">1014</span><br><span class="line">1015</span><br><span class="line">1016</span><br><span class="line">1017</span><br><span class="line">1018</span><br><span class="line">1019</span><br><span class="line">1020</span><br><span class="line">1021</span><br><span class="line">1022</span><br><span class="line">1023</span><br><span class="line">1024</span><br><span class="line">1025</span><br><span class="line">1026</span><br><span class="line">1027</span><br><span class="line">1028</span><br><span class="line">1029</span><br><span class="line">1030</span><br><span class="line">1031</span><br><span class="line">1032</span><br><span class="line">1033</span><br><span class="line">1034</span><br><span class="line">1035</span><br><span class="line">1036</span><br><span class="line">1037</span><br><span class="line">1038</span><br><span class="line">1039</span><br><span class="line">1040</span><br><span class="line">1041</span><br><span class="line">1042</span><br><span class="line">1043</span><br><span class="line">1044</span><br><span class="line">1045</span><br><span class="line">1046</span><br><span class="line">1047</span><br><span class="line">1048</span><br><span class="line">1049</span><br><span class="line">1050</span><br><span class="line">1051</span><br><span class="line">1052</span><br><span class="line">1053</span><br><span class="line">1054</span><br><span class="line">1055</span><br><span class="line">1056</span><br><span class="line">1057</span><br><span class="line">1058</span><br><span class="line">1059</span><br><span class="line">1060</span><br><span class="line">1061</span><br><span class="line">1062</span><br><span class="line">1063</span><br><span class="line">1064</span><br><span class="line">1065</span><br><span class="line">1066</span><br><span class="line">1067</span><br><span class="line">1068</span><br><span class="line">1069</span><br><span class="line">1070</span><br><span class="line">1071</span><br><span class="line">1072</span><br><span class="line">1073</span><br><span class="line">1074</span><br><span class="line">1075</span><br><span class="line">1076</span><br><span class="line">1077</span><br><span class="line">1078</span><br><span class="line">1079</span><br><span class="line">1080</span><br><span class="line">1081</span><br><span class="line">1082</span><br><span class="line">1083</span><br><span class="line">1084</span><br><span class="line">1085</span><br><span class="line">1086</span><br><span class="line">1087</span><br><span class="line">1088</span><br><span class="line">1089</span><br><span class="line">1090</span><br><span class="line">1091</span><br><span class="line">1092</span><br><span class="line">1093</span><br><span class="line">1094</span><br><span class="line">1095</span><br><span class="line">1096</span><br><span class="line">1097</span><br><span class="line">1098</span><br><span class="line">1099</span><br><span class="line">1100</span><br><span class="line">1101</span><br><span class="line">1102</span><br><span class="line">1103</span><br><span class="line">1104</span><br><span class="line">1105</span><br><span class="line">1106</span><br><span class="line">1107</span><br><span class="line">1108</span><br><span class="line">1109</span><br><span class="line">1110</span><br><span class="line">1111</span><br><span class="line">1112</span><br><span class="line">1113</span><br><span class="line">1114</span><br><span class="line">1115</span><br><span class="line">1116</span><br><span class="line">1117</span><br><span class="line">1118</span><br><span class="line">1119</span><br><span class="line">1120</span><br><span class="line">1121</span><br><span class="line">1122</span><br><span class="line">1123</span><br><span class="line">1124</span><br><span class="line">1125</span><br><span class="line">1126</span><br><span class="line">1127</span><br><span class="line">1128</span><br><span class="line">1129</span><br><span class="line">1130</span><br><span class="line">1131</span><br><span class="line">1132</span><br><span class="line">1133</span><br><span class="line">1134</span><br><span class="line">1135</span><br><span class="line">1136</span><br><span class="line">1137</span><br><span class="line">1138</span><br><span class="line">1139</span><br><span class="line">1140</span><br><span class="line">1141</span><br><span class="line">1142</span><br><span class="line">1143</span><br><span class="line">1144</span><br><span class="line">1145</span><br><span class="line">1146</span><br><span class="line">1147</span><br><span class="line">1148</span><br><span class="line">1149</span><br><span class="line">1150</span><br><span class="line">1151</span><br><span class="line">1152</span><br><span class="line">1153</span><br><span class="line">1154</span><br><span class="line">1155</span><br><span class="line">1156</span><br><span class="line">1157</span><br><span class="line">1158</span><br><span class="line">1159</span><br><span class="line">1160</span><br><span class="line">1161</span><br><span class="line">1162</span><br><span class="line">1163</span><br><span class="line">1164</span><br><span class="line">1165</span><br><span class="line">1166</span><br><span class="line">1167</span><br><span class="line">1168</span><br><span class="line">1169</span><br><span class="line">1170</span><br><span class="line">1171</span><br><span class="line">1172</span><br><span class="line">1173</span><br><span class="line">1174</span><br><span class="line">1175</span><br><span class="line">1176</span><br><span class="line">1177</span><br><span class="line">1178</span><br><span class="line">1179</span><br><span class="line">1180</span><br><span class="line">1181</span><br><span class="line">1182</span><br><span class="line">1183</span><br><span class="line">1184</span><br><span class="line">1185</span><br><span class="line">1186</span><br><span class="line">1187</span><br><span class="line">1188</span><br><span class="line">1189</span><br><span class="line">1190</span><br><span class="line">1191</span><br><span class="line">1192</span><br><span class="line">1193</span><br><span class="line">1194</span><br><span class="line">1195</span><br><span class="line">1196</span><br><span class="line">1197</span><br><span class="line">1198</span><br><span class="line">1199</span><br><span class="line">1200</span><br><span class="line">1201</span><br><span class="line">1202</span><br><span class="line">1203</span><br><span class="line">1204</span><br><span class="line">1205</span><br><span class="line">1206</span><br><span class="line">1207</span><br><span class="line">1208</span><br><span class="line">1209</span><br><span class="line">1210</span><br><span class="line">1211</span><br><span class="line">1212</span><br><span class="line">1213</span><br><span class="line">1214</span><br><span class="line">1215</span><br><span class="line">1216</span><br><span class="line">1217</span><br><span class="line">1218</span><br><span class="line">1219</span><br><span class="line">1220</span><br><span class="line">1221</span><br><span class="line">1222</span><br><span class="line">1223</span><br><span class="line">1224</span><br><span class="line">1225</span><br><span class="line">1226</span><br><span class="line">1227</span><br><span class="line">1228</span><br><span class="line">1229</span><br><span class="line">1230</span><br><span class="line">1231</span><br><span class="line">1232</span><br><span class="line">1233</span><br><span class="line">1234</span><br><span class="line">1235</span><br><span class="line">1236</span><br><span class="line">1237</span><br><span class="line">1238</span><br><span class="line">1239</span><br><span class="line">1240</span><br><span class="line">1241</span><br><span class="line">1242</span><br><span class="line">1243</span><br><span class="line">1244</span><br><span class="line">1245</span><br><span class="line">1246</span><br><span class="line">1247</span><br><span class="line">1248</span><br><span class="line">1249</span><br><span class="line">1250</span><br><span class="line">1251</span><br><span class="line">1252</span><br><span class="line">1253</span><br><span class="line">1254</span><br><span class="line">1255</span><br><span class="line">1256</span><br><span class="line">1257</span><br><span class="line">1258</span><br><span class="line">1259</span><br><span class="line">1260</span><br><span class="line">1261</span><br><span class="line">1262</span><br><span class="line">1263</span><br><span class="line">1264</span><br><span class="line">1265</span><br><span class="line">1266</span><br><span class="line">1267</span><br><span class="line">1268</span><br><span class="line">1269</span><br><span class="line">1270</span><br><span class="line">1271</span><br><span class="line">1272</span><br><span class="line">1273</span><br><span class="line">1274</span><br><span class="line">1275</span><br><span class="line">1276</span><br><span class="line">1277</span><br><span class="line">1278</span><br><span class="line">1279</span><br><span class="line">1280</span><br><span class="line">1281</span><br><span class="line">1282</span><br><span class="line">1283</span><br><span class="line">1284</span><br><span class="line">1285</span><br><span class="line">1286</span><br><span class="line">1287</span><br><span class="line">1288</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># Hexo Butterfly 主题配置</span></span><br><span class="line"><span class="comment"># 如有疑问，请参考官方文档</span></span><br><span class="line"><span class="comment"># 中文文档: https://butterfly.js.org/</span></span><br><span class="line"><span class="comment"># 英文文档: https://butterfly.js.org/en/</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 导航设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="attr">nav:</span></span><br><span class="line">  <span class="comment"># 导航栏Logo图片</span></span><br><span class="line">  <span class="attr">logo:</span></span><br><span class="line">  <span class="attr">display_title:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">display_post_title:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 是否固定导航栏</span></span><br><span class="line">  <span class="attr">fixed:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="attr">menu:</span></span><br><span class="line"><span class="comment"># 首页: / || fas fa-home</span></span><br><span class="line"><span class="comment"># 列表||fas fa-list:</span></span><br><span class="line"><span class="comment">#   音乐: /music/ || fas fa-music</span></span><br><span class="line"><span class="comment">#   电影: /movies/ || fas fa-video</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 代码块设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="attr">code_blocks:</span></span><br><span class="line">  <span class="comment"># 代码块主题: darker / pale night / light / ocean / false</span></span><br><span class="line">  <span class="attr">theme:</span> <span class="string">darker</span></span><br><span class="line">  <span class="attr">macStyle:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 代码块高度限制（单位: px）</span></span><br><span class="line">  <span class="attr">height_limit:</span> <span class="literal">false</span></span><br><span class="line">  <span class="attr">word_wrap:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># 工具栏</span></span><br><span class="line">  <span class="attr">copy:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">language:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># true: 收缩代码块 | false: 展开代码块 | none: 展开代码块并隐藏按钮</span></span><br><span class="line">  <span class="attr">shrink:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">fullpage:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 社交媒体链接</span></span><br><span class="line"><span class="comment"># 格式:</span></span><br><span class="line"><span class="comment">#   图标: 链接 || 描述 || 颜色</span></span><br><span class="line"><span class="attr">social:</span></span><br><span class="line"><span class="comment"># fab fa-github: https://github.com/xxxxx || Github || &#x27;#24292e&#x27;</span></span><br><span class="line"><span class="comment"># fas fa-envelope: mailto:xxxxxx@gmail.com || Email || &#x27;#4a7dbe&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 图片设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 网站的favicon图标</span></span><br><span class="line"><span class="attr">favicon:</span> <span class="string">/img/favicon.png</span></span><br><span class="line"></span><br><span class="line"><span class="attr">avatar:</span></span><br><span class="line">  <span class="comment"># 头像图片链接</span></span><br><span class="line">  <span class="attr">img:</span> <span class="string">/img/butterfly-icon.png</span></span><br><span class="line">  <span class="comment"># 是否启用头像效果</span></span><br><span class="line">  <span class="attr">effect:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 禁用所有横幅图片</span></span><br><span class="line"><span class="attr">disable_top_img:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 若页面未设置横幅，则显示默认横幅图片</span></span><br><span class="line"><span class="attr">default_top_img:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 首页的横幅图片</span></span><br><span class="line"><span class="attr">index_img:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 归档页的横幅图片</span></span><br><span class="line"><span class="attr">archive_img:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 注意: 是标签页（单个标签），不是标签页面（所有标签）</span></span><br><span class="line"><span class="attr">tag_img:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 标签页的横幅图片，可为每个标签单独设置</span></span><br><span class="line"><span class="comment"># 格式:</span></span><br><span class="line"><span class="comment">#  - 标签名: 图片链接</span></span><br><span class="line"><span class="attr">tag_per_img:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 注意: 是分类页（单个分类），不是分类页面（所有分类）</span></span><br><span class="line"><span class="attr">category_img:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 分类页的横幅图片，可为每个分类单独设置</span></span><br><span class="line"><span class="comment"># 格式:</span></span><br><span class="line"><span class="comment">#  - 分类名: 图片链接</span></span><br><span class="line"><span class="attr">category_per_img:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 页脚的背景图片</span></span><br><span class="line"><span class="attr">footer_img:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 网站背景</span></span><br><span class="line"><span class="comment"># 可设置为颜色或图片链接</span></span><br><span class="line"><span class="attr">background:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">cover:</span></span><br><span class="line">  <span class="comment"># 是否禁用封面</span></span><br><span class="line">  <span class="attr">index_enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">aside_enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">archives_enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 未设置封面时，显示默认封面</span></span><br><span class="line">  <span class="attr">default_cover:</span></span><br><span class="line">  <span class="comment"># - xxx.jpg</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 替换损坏的图片</span></span><br><span class="line"><span class="attr">error_img:</span></span><br><span class="line">  <span class="comment"># 友链页面的错误图片</span></span><br><span class="line">  <span class="attr">flink:</span> <span class="string">/img/friend_404.gif</span></span><br><span class="line">  <span class="comment"># 文章页面的错误图片</span></span><br><span class="line">  <span class="attr">post_page:</span> <span class="string">/img/404.jpg</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 简单的404页面</span></span><br><span class="line"><span class="attr">error_404:</span></span><br><span class="line">  <span class="comment"># 是否启用404页面</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 404页面的副标题</span></span><br><span class="line">  <span class="attr">subtitle:</span> <span class="string">&#x27;Page Not Found&#x27;</span></span><br><span class="line">  <span class="comment"># 404页面的卡片背景图片</span></span><br><span class="line">  <span class="attr">background:</span> <span class="string">/img/error-page.png</span></span><br><span class="line"></span><br><span class="line"><span class="attr">post_meta:</span></span><br><span class="line">  <span class="comment"># 首页页面</span></span><br><span class="line">  <span class="attr">page:</span></span><br><span class="line">    <span class="comment"># 日期类型: created / updated / both</span></span><br><span class="line">    <span class="attr">date_type:</span> <span class="string">created</span></span><br><span class="line">    <span class="comment"># 日期格式: date / relative</span></span><br><span class="line">    <span class="attr">date_format:</span> <span class="string">date</span></span><br><span class="line">    <span class="attr">categories:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">tags:</span> <span class="literal">false</span></span><br><span class="line">    <span class="comment"># 是否显示文字标签</span></span><br><span class="line">    <span class="attr">label:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 文章页面</span></span><br><span class="line">  <span class="attr">post:</span></span><br><span class="line">    <span class="comment"># 元数据位置: left / center</span></span><br><span class="line">    <span class="attr">position:</span> <span class="string">left</span></span><br><span class="line">    <span class="comment"># 日期类型: created / updated / both</span></span><br><span class="line">    <span class="attr">date_type:</span> <span class="string">both</span></span><br><span class="line">    <span class="comment"># 日期格式: date / relative</span></span><br><span class="line">    <span class="attr">date_format:</span> <span class="string">date</span></span><br><span class="line">    <span class="attr">categories:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">tags:</span> <span class="literal">true</span></span><br><span class="line">    <span class="comment"># 是否显示文字标签</span></span><br><span class="line">    <span class="attr">label:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 首页设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 首页头图的设置</span></span><br><span class="line"><span class="comment"># 默认: 头图全屏，站点信息在中间</span></span><br><span class="line"><span class="comment"># 站点信息的位置，例如: 300px/300em/300rem/10%</span></span><br><span class="line"><span class="attr">index_site_info_top:</span></span><br><span class="line"><span class="comment"># 头图的高度，例如: 300px/300em/300rem</span></span><br><span class="line"><span class="attr">index_top_img_height:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 首页的副标题设置</span></span><br><span class="line"><span class="attr">subtitle:</span></span><br><span class="line">  <span class="comment"># 是否启用副标题</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 打字机效果</span></span><br><span class="line">  <span class="attr">effect:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 自定义typed.js（参考文档：https://github.com/mattboldt/typed.js/#customization）</span></span><br><span class="line">  <span class="attr">typed_option:</span></span><br><span class="line">  <span class="comment"># 来源 - 调用第三方服务API（仅限中文）</span></span><br><span class="line">  <span class="comment"># 会先显示来源，再显示副标题内容</span></span><br><span class="line">  <span class="comment"># 选择: false/1/2/3</span></span><br><span class="line">  <span class="comment"># false - 禁用此功能</span></span><br><span class="line">  <span class="comment"># 1 - hitokoto.cn</span></span><br><span class="line">  <span class="comment"># 2 - https://api.aa1.cn/doc/yiyan.html</span></span><br><span class="line">  <span class="comment"># 3 - jinrishici.com</span></span><br><span class="line">  <span class="attr">source:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 关闭打字机效果后，副标题仅显示sub的第一行内容</span></span><br><span class="line">  <span class="attr">sub:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 首页文章布局</span></span><br><span class="line"><span class="comment"># 1: 左侧封面，右侧信息</span></span><br><span class="line"><span class="comment"># 2: 右侧封面，左侧信息</span></span><br><span class="line"><span class="comment"># 3: 封面与信息左右交替</span></span><br><span class="line"><span class="comment"># 4: 封面在上，信息在下</span></span><br><span class="line"><span class="comment"># 5: 信息覆盖在封面上</span></span><br><span class="line"><span class="comment"># 6: 瀑布流布局 - 封面在上，信息在下</span></span><br><span class="line"><span class="comment"># 7: 瀑布流布局 - 信息覆盖在封面上</span></span><br><span class="line"><span class="attr">index_layout:</span> <span class="number">3</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 在首页显示文章简介</span></span><br><span class="line"><span class="comment"># 1: 显示description字段内容</span></span><br><span class="line"><span class="comment"># 2: 两者（若存在description，显示description；否则显示自动摘要）</span></span><br><span class="line"><span class="comment"># 3: 自动摘要（默认）</span></span><br><span class="line"><span class="comment"># false: 不显示文章简介</span></span><br><span class="line"><span class="attr">index_post_content:</span></span><br><span class="line">  <span class="attr">method:</span> <span class="number">3</span></span><br><span class="line">  <span class="comment"># 若method设为2或3，需配置摘要长度</span></span><br><span class="line">  <span class="attr">length:</span> <span class="number">500</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 文章设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="attr">toc:</span></span><br><span class="line">  <span class="comment"># 文章中是否显示目录</span></span><br><span class="line">  <span class="attr">post:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 页面中是否显示目录</span></span><br><span class="line">  <span class="attr">page:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 是否显示目录编号</span></span><br><span class="line">  <span class="attr">number:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 是否默认展开目录</span></span><br><span class="line">  <span class="attr">expand:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 仅适用于文章</span></span><br><span class="line">  <span class="attr">style_simple:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 是否显示滚动百分比</span></span><br><span class="line">  <span class="attr">scroll_percent:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="attr">post_copyright:</span></span><br><span class="line">  <span class="comment"># 是否启用版权声明</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 是否对文章URL进行解码</span></span><br><span class="line">  <span class="attr">decode:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 作者链接</span></span><br><span class="line">  <span class="attr">author_href:</span></span><br><span class="line">  <span class="comment"># 许可证类型</span></span><br><span class="line">  <span class="attr">license:</span> <span class="string">CC</span> <span class="string">BY-NC-SA</span> <span class="number">4.0</span></span><br><span class="line">  <span class="comment"># 许可证链接</span></span><br><span class="line">  <span class="attr">license_url:</span> <span class="string">https://creativecommons.org/licenses/by-nc-sa/4.0/</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 赞助/打赏</span></span><br><span class="line"><span class="attr">reward:</span></span><br><span class="line">  <span class="comment"># 是否启用打赏</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 打赏提示文本</span></span><br><span class="line">  <span class="attr">text:</span></span><br><span class="line">  <span class="comment"># 收款二维码</span></span><br><span class="line">  <span class="attr">QR_code:</span></span><br><span class="line">  <span class="comment"># - img: /img/wechat.jpg</span></span><br><span class="line">  <span class="comment">#   link:</span></span><br><span class="line">  <span class="comment">#   text: wechat</span></span><br><span class="line">  <span class="comment"># - img: /img/alipay.jpg</span></span><br><span class="line">  <span class="comment">#   link:</span></span><br><span class="line">  <span class="comment">#   text: alipay</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 文章在线编辑</span></span><br><span class="line"><span class="comment"># 在线便捷浏览和编辑博客源代码</span></span><br><span class="line"><span class="attr">post_edit:</span></span><br><span class="line">  <span class="comment"># 是否启用在线编辑</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 链接格式: https://github.com/用户名/仓库名/edit/分支名/子目录名/</span></span><br><span class="line">  <span class="comment"># 示例: https://github.com/jerryc127/butterfly.js.org/edit/main/source/</span></span><br><span class="line">  <span class="attr">url:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 相关文章</span></span><br><span class="line"><span class="attr">related_post:</span></span><br><span class="line">  <span class="comment"># 是否显示相关文章</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 显示的文章数量</span></span><br><span class="line">  <span class="attr">limit:</span> <span class="number">6</span></span><br><span class="line">  <span class="comment"># 选择: created / updated</span></span><br><span class="line">  <span class="attr">date_type:</span> <span class="string">created</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 选择: 1 / 2 / false</span></span><br><span class="line"><span class="comment"># 1: “下一篇文章”链接到旧文章</span></span><br><span class="line"><span class="comment"># 2: “下一篇文章”链接到新文章</span></span><br><span class="line"><span class="comment"># false: 禁用分页</span></span><br><span class="line"><span class="attr">post_pagination:</span> <span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 显示文章过期通知</span></span><br><span class="line"><span class="attr">noticeOutdate:</span></span><br><span class="line">  <span class="comment"># 是否启用过期通知</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 样式: simple / flat</span></span><br><span class="line">  <span class="attr">style:</span> <span class="string">flat</span></span><br><span class="line">  <span class="comment"># 超过多少天显示通知</span></span><br><span class="line">  <span class="attr">limit_day:</span> <span class="number">365</span></span><br><span class="line">  <span class="comment"># 位置: top / bottom</span></span><br><span class="line">  <span class="attr">position:</span> <span class="string">top</span></span><br><span class="line">  <span class="attr">message_prev:</span> <span class="string">It</span> <span class="string">has</span> <span class="string">been</span></span><br><span class="line">  <span class="attr">message_next:</span> <span class="string">days</span> <span class="string">since</span> <span class="string">the</span> <span class="string">last</span> <span class="string">update,</span> <span class="string">the</span> <span class="string">content</span> <span class="string">of</span> <span class="string">the</span> <span class="string">article</span> <span class="string">may</span> <span class="string">be</span> <span class="string">outdated.</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 页脚设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="attr">footer:</span></span><br><span class="line">  <span class="comment"># 页脚导航</span></span><br><span class="line">  <span class="attr">nav:</span></span><br><span class="line">  <span class="attr">owner:</span></span><br><span class="line">    <span class="comment"># 是否启用所有者显示</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">    <span class="comment"># 网站创建年份</span></span><br><span class="line">    <span class="attr">since:</span> <span class="number">2025</span></span><br><span class="line">  <span class="comment"># 主题和框架的版权声明</span></span><br><span class="line">  <span class="attr">copyright:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">    <span class="comment"># 是否显示版本号</span></span><br><span class="line">    <span class="attr">version:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 自定义文本</span></span><br><span class="line">  <span class="attr">custom_text:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 侧边栏设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="attr">aside:</span></span><br><span class="line">  <span class="comment"># 是否启用侧边栏</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 是否默认隐藏侧边栏</span></span><br><span class="line">  <span class="attr">hide:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 是否在右下角显示隐藏侧边栏的按钮</span></span><br><span class="line">  <span class="attr">button:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 移动设备上是否启用侧边栏</span></span><br><span class="line">  <span class="attr">mobile:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 位置: left / right</span></span><br><span class="line">  <span class="attr">position:</span> <span class="string">right</span></span><br><span class="line">  <span class="attr">display:</span></span><br><span class="line">    <span class="comment"># 归档页面是否显示侧边栏</span></span><br><span class="line">    <span class="attr">archive:</span> <span class="literal">true</span></span><br><span class="line">    <span class="comment"># 标签页面是否显示侧边栏</span></span><br><span class="line">    <span class="attr">tag:</span> <span class="literal">true</span></span><br><span class="line">    <span class="comment"># 分类页面是否显示侧边栏</span></span><br><span class="line">    <span class="attr">category:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 作者信息卡片</span></span><br><span class="line">  <span class="attr">card_author:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">    <span class="comment"># 作者描述</span></span><br><span class="line">    <span class="attr">description:</span></span><br><span class="line">    <span class="attr">button:</span></span><br><span class="line">      <span class="comment"># 是否显示按钮</span></span><br><span class="line">      <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">      <span class="comment"># 按钮图标</span></span><br><span class="line">      <span class="attr">icon:</span> <span class="string">fab</span> <span class="string">fa-github</span></span><br><span class="line">      <span class="comment"># 按钮文本</span></span><br><span class="line">      <span class="attr">text:</span> <span class="string">Follow</span> <span class="string">Me</span></span><br><span class="line">      <span class="comment"># 按钮链接</span></span><br><span class="line">      <span class="attr">link:</span> <span class="string">https://github.com/xxxxxx</span></span><br><span class="line">  <span class="comment"># 公告卡片</span></span><br><span class="line">  <span class="attr">card_announcement:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">    <span class="comment"># 公告内容</span></span><br><span class="line">    <span class="attr">content:</span> <span class="string">This</span> <span class="string">is</span> <span class="string">my</span> <span class="string">Blog</span></span><br><span class="line">  <span class="comment"># 最近文章卡片</span></span><br><span class="line">  <span class="attr">card_recent_post:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">    <span class="comment"># 设为0则显示所有近期文章</span></span><br><span class="line">    <span class="attr">limit:</span> <span class="number">5</span></span><br><span class="line">    <span class="comment"># 排序方式: date / updated</span></span><br><span class="line">    <span class="attr">sort:</span> <span class="string">date</span></span><br><span class="line">    <span class="attr">sort_order:</span></span><br><span class="line">  <span class="comment"># 最新评论卡片</span></span><br><span class="line">  <span class="attr">card_newest_comments:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">    <span class="attr">sort_order:</span></span><br><span class="line">    <span class="comment"># 显示评论数量</span></span><br><span class="line">    <span class="attr">limit:</span> <span class="number">6</span></span><br><span class="line">    <span class="comment"># 单位：分钟，数据保存到localStorage</span></span><br><span class="line">    <span class="attr">storage:</span> <span class="number">10</span></span><br><span class="line">    <span class="comment"># 是否显示头像</span></span><br><span class="line">    <span class="attr">avatar:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 分类卡片</span></span><br><span class="line">  <span class="attr">card_categories:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">    <span class="comment"># 设为0则显示所有分类</span></span><br><span class="line">    <span class="attr">limit:</span> <span class="number">8</span></span><br><span class="line">    <span class="comment"># 选择：none / true / false</span></span><br><span class="line">    <span class="attr">expand:</span> <span class="string">none</span></span><br><span class="line">    <span class="attr">sort_order:</span></span><br><span class="line">  <span class="comment"># 标签卡片</span></span><br><span class="line">  <span class="attr">card_tags:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">    <span class="comment"># 设为0则显示所有标签</span></span><br><span class="line">    <span class="attr">limit:</span> <span class="number">40</span></span><br><span class="line">    <span class="comment"># 是否启用标签颜色</span></span><br><span class="line">    <span class="attr">color:</span> <span class="literal">false</span></span><br><span class="line">    <span class="comment"># 标签排序方式: random/name/length</span></span><br><span class="line">    <span class="attr">orderby:</span> <span class="string">random</span></span><br><span class="line">    <span class="comment"># 排序顺序：1为升序，-1为降序</span></span><br><span class="line">    <span class="attr">order:</span> <span class="number">1</span></span><br><span class="line">    <span class="attr">sort_order:</span></span><br><span class="line">  <span class="comment"># 归档卡片</span></span><br><span class="line">  <span class="attr">card_archives:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">    <span class="comment"># 归档类型: monthly / yearly</span></span><br><span class="line">    <span class="attr">type:</span> <span class="string">monthly</span></span><br><span class="line">    <span class="comment"># 日期格式示例：YYYY年MM月</span></span><br><span class="line">    <span class="attr">format:</span> <span class="string">MMMM</span> <span class="string">YYYY</span></span><br><span class="line">    <span class="comment"># 排序顺序：1为升序，-1为降序</span></span><br><span class="line">    <span class="attr">order:</span> <span class="number">-1</span></span><br><span class="line">    <span class="comment"># 设为0则显示所有归档</span></span><br><span class="line">    <span class="attr">limit:</span> <span class="number">8</span></span><br><span class="line">    <span class="attr">sort_order:</span></span><br><span class="line">  <span class="comment"># 系列文章卡片</span></span><br><span class="line">  <span class="attr">card_post_series:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">    <span class="comment"># 标题是否显示系列名称</span></span><br><span class="line">    <span class="attr">series_title:</span> <span class="literal">false</span></span><br><span class="line">    <span class="comment"># 排序依据：title或date</span></span><br><span class="line">    <span class="attr">orderBy:</span> <span class="string">&#x27;date&#x27;</span></span><br><span class="line">    <span class="comment"># 排序顺序：1为升序，-1为降序</span></span><br><span class="line">    <span class="attr">order:</span> <span class="number">-1</span></span><br><span class="line">  <span class="comment"># 网站信息卡片</span></span><br><span class="line">  <span class="attr">card_webinfo:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">    <span class="comment"># 是否显示文章总数</span></span><br><span class="line">    <span class="attr">post_count:</span> <span class="literal">true</span></span><br><span class="line">    <span class="comment"># 是否显示最后更新日期</span></span><br><span class="line">    <span class="attr">last_push_date:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">sort_order:</span></span><br><span class="line">    <span class="comment"># 发布日期与当前日期的时间差</span></span><br><span class="line">    <span class="comment"># 格式：Month/Day/Year Time 或 Year/Month/Day Time</span></span><br><span class="line">    <span class="comment"># 不启用此功能则留空</span></span><br><span class="line">    <span class="attr">runtime_date:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 右下角按钮设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 右下角按钮与底部的距离（默认单位：px）</span></span><br><span class="line"><span class="attr">rightside_bottom:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 简繁中文转换</span></span><br><span class="line"><span class="attr">translate:</span></span><br><span class="line">  <span class="comment"># 是否启用简繁转换</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 按钮默认文本</span></span><br><span class="line">  <span class="attr">default:</span> <span class="string">繁</span></span><br><span class="line">  <span class="comment"># 网站语言（1 - 繁体中文 / 2 - 简体中文）</span></span><br><span class="line">  <span class="attr">defaultEncoding:</span> <span class="number">2</span></span><br><span class="line">  <span class="comment"># 转换延迟时间</span></span><br><span class="line">  <span class="attr">translateDelay:</span> <span class="number">0</span></span><br><span class="line">  <span class="comment"># 简体中文模式下的按钮文本</span></span><br><span class="line">  <span class="attr">msgToTraditionalChinese:</span> <span class="string">&#x27;繁&#x27;</span></span><br><span class="line">  <span class="comment"># 繁体中文模式下的按钮文本</span></span><br><span class="line">  <span class="attr">msgToSimplifiedChinese:</span> <span class="string">&#x27;簡&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 阅读模式</span></span><br><span class="line"><span class="attr">readmode:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 暗黑模式设置</span></span><br><span class="line"><span class="attr">darkmode:</span></span><br><span class="line">  <span class="comment"># 是否启用暗黑模式</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 暗黑/明亮模式切换按钮</span></span><br><span class="line">  <span class="attr">button:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 自动切换暗黑/明亮模式</span></span><br><span class="line">  <span class="comment"># autoChangeMode: 1  跟随系统设置，系统不支持暗黑模式则在18:00-6:00切换为暗黑模式</span></span><br><span class="line">  <span class="comment"># autoChangeMode: 2  固定在18:00-6:00切换为暗黑模式</span></span><br><span class="line">  <span class="comment"># autoChangeMode: false  不自动切换</span></span><br><span class="line">  <span class="attr">autoChangeMode:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 明亮模式时间段（值范围0-24），不设置则默认6-18点</span></span><br><span class="line">  <span class="attr">start:</span></span><br><span class="line">  <span class="attr">end:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 返回顶部按钮中是否显示滚动百分比</span></span><br><span class="line"><span class="attr">rightside_scroll_percent:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 非专业人员请勿修改以下设置</span></span><br><span class="line"><span class="comment"># 选择：readmode,translate,darkmode,hideAside,toc,chat,comment</span></span><br><span class="line"><span class="comment"># 不可重复设置同一值</span></span><br><span class="line"><span class="attr">rightside_item_order:</span></span><br><span class="line">  <span class="comment"># 是否启用右侧按钮排序</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 默认隐藏的按钮：readmode,translate,darkmode,hideAside</span></span><br><span class="line">  <span class="attr">hide:</span></span><br><span class="line">  <span class="comment"># 默认显示的按钮：toc,chat,comment</span></span><br><span class="line">  <span class="attr">show:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 右下角配置按钮的动画效果</span></span><br><span class="line"><span class="attr">rightside_config_animation:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 全局设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="attr">anchor:</span></span><br><span class="line">  <span class="comment"># 滚动时，URL是否根据标题ID更新</span></span><br><span class="line">  <span class="attr">auto_update:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 点击标题是否滚动并更新锚点</span></span><br><span class="line">  <span class="attr">click_to_scroll:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 图片是否显示标题（figcaption）</span></span><br><span class="line"><span class="attr">photofigcaption:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="attr">copy:</span></span><br><span class="line">  <span class="comment"># 是否启用复制功能</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 复制内容后是否添加版权信息</span></span><br><span class="line">  <span class="attr">copyright:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">    <span class="comment"># 超过此字数才添加版权信息</span></span><br><span class="line">    <span class="attr">limit_count:</span> <span class="number">150</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 需安装hexo-wordcount插件</span></span><br><span class="line"><span class="attr">wordcount:</span></span><br><span class="line">  <span class="comment"># 是否启用字数统计</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 文章元信息中是否显示字数统计</span></span><br><span class="line">  <span class="attr">post_wordcount:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 文章元信息中是否显示阅读时间</span></span><br><span class="line">  <span class="attr">min2read:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 侧边栏网站信息中是否显示总字数</span></span><br><span class="line">  <span class="attr">total_wordcount:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 不蒜子站点PV/UV统计</span></span><br><span class="line"><span class="attr">busuanzi:</span></span><br><span class="line">  <span class="comment"># 网站UV统计</span></span><br><span class="line">  <span class="attr">site_uv:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 网站PV统计</span></span><br><span class="line">  <span class="attr">site_pv:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 页面PV统计</span></span><br><span class="line">  <span class="attr">page_pv:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 数学公式设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 关于per_page参数</span></span><br><span class="line"><span class="comment"># 设为true则所有页面加载mathjax/katex脚本</span></span><br><span class="line"><span class="comment"># 设为false则仅在文章front-matter中添加&#x27;mathjax: true&#x27;或&#x27;katex: true&#x27;时加载</span></span><br><span class="line"><span class="attr">math:</span></span><br><span class="line">  <span class="comment"># 选择：mathjax, katex，无需则留空</span></span><br><span class="line">  <span class="attr">use:</span></span><br><span class="line">  <span class="attr">per_page:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 是否隐藏滚动条</span></span><br><span class="line">  <span class="attr">hide_scrollbar:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line">  <span class="attr">mathjax:</span></span><br><span class="line">    <span class="comment"># 是否启用上下文菜单</span></span><br><span class="line">    <span class="attr">enableMenu:</span> <span class="literal">true</span></span><br><span class="line">    <span class="comment"># 选择：all / ams / none，控制公式是否编号及编号方式</span></span><br><span class="line">    <span class="attr">tags:</span> <span class="string">none</span></span><br><span class="line"></span><br><span class="line">  <span class="attr">katex:</span></span><br><span class="line">    <span class="comment"># 是否启用KaTeX公式复制功能</span></span><br><span class="line">    <span class="attr">copy_tex:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 搜索设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="attr">search:</span></span><br><span class="line">  <span class="comment"># 选择：algolia_search / local_search / docsearch，无需则留空</span></span><br><span class="line">  <span class="attr">use:</span></span><br><span class="line">  <span class="comment"># 搜索框提示文本</span></span><br><span class="line">  <span class="attr">placeholder:</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># Algolia搜索</span></span><br><span class="line">  <span class="attr">algolia_search:</span></span><br><span class="line">    <span class="comment"># 每页搜索结果数量</span></span><br><span class="line">    <span class="attr">hitsPerPage:</span> <span class="number">6</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># 本地搜索</span></span><br><span class="line">  <span class="attr">local_search:</span></span><br><span class="line">    <span class="comment"># 页面加载时是否预加载搜索数据</span></span><br><span class="line">    <span class="attr">preload:</span> <span class="literal">false</span></span><br><span class="line">    <span class="comment"># 每篇文章显示的顶部结果数量，设为-1显示所有</span></span><br><span class="line">    <span class="attr">top_n_per_article:</span> <span class="number">1</span></span><br><span class="line">    <span class="comment"># 是否将HTML字符串反转义为可读文本</span></span><br><span class="line">    <span class="attr">unescape:</span> <span class="literal">false</span></span><br><span class="line">    <span class="comment"># 搜索结果是否启用分页</span></span><br><span class="line">    <span class="attr">pagination:</span></span><br><span class="line">      <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">      <span class="comment"># 每页搜索结果数量</span></span><br><span class="line">      <span class="attr">hitsPerPage:</span> <span class="number">8</span></span><br><span class="line">    <span class="attr">CDN:</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># Docsearch（参考文档：https://docsearch.algolia.com/）</span></span><br><span class="line">  <span class="attr">docsearch:</span></span><br><span class="line">    <span class="attr">appId:</span></span><br><span class="line">    <span class="attr">apiKey:</span></span><br><span class="line">    <span class="attr">indexName:</span></span><br><span class="line">    <span class="attr">option:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 分享系统</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="attr">share:</span></span><br><span class="line">  <span class="comment"># 选择：sharejs / addtoany，无需则留空</span></span><br><span class="line">  <span class="attr">use:</span> <span class="string">sharejs</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># Share.js（参考文档：https://github.com/overtrue/share.js）</span></span><br><span class="line">  <span class="attr">sharejs:</span></span><br><span class="line">    <span class="comment"># 启用的分享平台</span></span><br><span class="line">    <span class="attr">sites:</span> <span class="string">facebook,x,wechat,weibo,qq</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># AddToAny（参考文档：https://www.addtoany.com/）</span></span><br><span class="line">  <span class="attr">addtoany:</span></span><br><span class="line">    <span class="comment"># 启用的分享平台</span></span><br><span class="line">    <span class="attr">item:</span> <span class="string">facebook,x,wechat,sina_weibo,facebook_messenger,email,copy_link</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 评论系统</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="attr">comments:</span></span><br><span class="line">  <span class="comment"># 最多启用两个评论系统，第一个为默认</span></span><br><span class="line">  <span class="comment"># 无需则留空</span></span><br><span class="line">  <span class="comment"># 选择：Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/Artalk</span></span><br><span class="line">  <span class="comment"># 双系统格式：Disqus,Waline</span></span><br><span class="line">  <span class="attr">use:</span></span><br><span class="line">  <span class="comment"># 按钮旁是否显示评论系统名称</span></span><br><span class="line">  <span class="attr">text:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 懒加载：评论区进入浏览器视口才加载</span></span><br><span class="line">  <span class="comment"># 设为true则评论计数失效</span></span><br><span class="line">  <span class="attr">lazyload:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 文章头图中是否显示评论数</span></span><br><span class="line">  <span class="attr">count:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 首页是否显示评论数</span></span><br><span class="line">  <span class="attr">card_post_count:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Disqus评论系统（参考文档：https://disqus.com/）</span></span><br><span class="line"><span class="attr">disqus:</span></span><br><span class="line">  <span class="comment"># Disqus的shortname</span></span><br><span class="line">  <span class="attr">shortname:</span></span><br><span class="line">  <span class="comment"># 最新评论组件的API密钥</span></span><br><span class="line">  <span class="attr">apikey:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Disqus替代方案 - 通过Disqus API渲染评论（参考文档：https://github.com/SukkaW/DisqusJS）</span></span><br><span class="line"><span class="attr">disqusjs:</span></span><br><span class="line">  <span class="comment"># Disqus的shortname</span></span><br><span class="line">  <span class="attr">shortname:</span></span><br><span class="line">  <span class="comment"># API密钥</span></span><br><span class="line">  <span class="attr">apikey:</span></span><br><span class="line">  <span class="comment"># 其他可选配置</span></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Livere评论系统（参考文档：https://www.livere.com/）</span></span><br><span class="line"><span class="attr">livere:</span></span><br><span class="line">  <span class="comment"># Livere的用户ID</span></span><br><span class="line">  <span class="attr">uid:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Gitalk评论系统（参考文档：https://github.com/gitalk/gitalk）</span></span><br><span class="line"><span class="attr">gitalk:</span></span><br><span class="line">  <span class="comment"># GitHub应用的客户端ID</span></span><br><span class="line">  <span class="attr">client_id:</span></span><br><span class="line">  <span class="comment"># GitHub应用的客户端密钥</span></span><br><span class="line">  <span class="attr">client_secret:</span></span><br><span class="line">  <span class="comment"># 存储评论的仓库名</span></span><br><span class="line">  <span class="attr">repo:</span></span><br><span class="line">  <span class="comment"># 仓库所有者用户名</span></span><br><span class="line">  <span class="attr">owner:</span></span><br><span class="line">  <span class="comment"># 管理员用户名列表</span></span><br><span class="line">  <span class="attr">admin:</span></span><br><span class="line">  <span class="comment"># 其他可选配置</span></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Valine评论系统（参考文档：https://valine.js.org）</span></span><br><span class="line"><span class="attr">valine:</span></span><br><span class="line">  <span class="comment"># LeanCloud应用的appId</span></span><br><span class="line">  <span class="attr">appId:</span></span><br><span class="line">  <span class="comment"># LeanCloud应用的appKey</span></span><br><span class="line">  <span class="attr">appKey:</span></span><br><span class="line">  <span class="comment"># 评论者头像样式</span></span><br><span class="line">  <span class="attr">avatar:</span> <span class="string">monsterid</span></span><br><span class="line">  <span class="comment"># 此配置适用于国内自定义域名用户，海外版本自动检测（无需手动填写）</span></span><br><span class="line">  <span class="attr">serverURLs:</span></span><br><span class="line">  <span class="comment"># 评论框背景图片</span></span><br><span class="line">  <span class="attr">bg:</span></span><br><span class="line">  <span class="comment"># 是否用Valine访客计数作为页面浏览量</span></span><br><span class="line">  <span class="attr">visitor:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 其他可选配置</span></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Waline评论系统 - 基于Valine开发的带后端支持的简易评论系统（参考文档：https://waline.js.org/）</span></span><br><span class="line"><span class="attr">waline:</span></span><br><span class="line">  <span class="comment"># 服务器URL</span></span><br><span class="line">  <span class="attr">serverURL:</span></span><br><span class="line">  <span class="comment"># 评论框背景图片</span></span><br><span class="line">  <span class="attr">bg:</span></span><br><span class="line">  <span class="comment"># 是否用Waline访客计数作为页面浏览量</span></span><br><span class="line">  <span class="attr">pageview:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 其他可选配置</span></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line">    <span class="attr">locale:</span></span><br><span class="line">      <span class="attr">placeholder:</span> <span class="string">小站已开启评论审核，可匿名评论，但评论需要通过审核后才能够出现在评论区哦~</span></span><br><span class="line">    <span class="attr">emoji:</span> [</span><br><span class="line">             <span class="string">&#x27;https://unpkg.com/@waline/emojis@1.2.0/alus&#x27;</span>,</span><br><span class="line">             <span class="string">&#x27;https://unpkg.com/@waline/emojis@1.2.0/weibo&#x27;</span></span><br><span class="line">    ]</span><br><span class="line">    <span class="attr">pageSize:</span> <span class="number">10</span> <span class="comment"># 评论每页显示数量</span></span><br><span class="line">    <span class="attr">highlight:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">dark:</span> <span class="string">&#x27;html[data-user-color-scheme=&quot;dark&quot;]&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Utterances评论系统（参考文档：https://utteranc.es/）</span></span><br><span class="line"><span class="attr">utterances:</span></span><br><span class="line">  <span class="comment"># 存储评论的GitHub仓库</span></span><br><span class="line">  <span class="attr">repo:</span></span><br><span class="line">  <span class="comment"># 议题映射方式：pathname/url/title/og:title</span></span><br><span class="line">  <span class="attr">issue_term:</span> <span class="string">pathname</span></span><br><span class="line">  <span class="comment"># 主题：github-light/github-dark/github-dark-orange/icy-dark/dark-blue/photon-dark</span></span><br><span class="line">  <span class="attr">light_theme:</span> <span class="string">github-light</span></span><br><span class="line">  <span class="attr">dark_theme:</span> <span class="string">dark-blue</span></span><br><span class="line">  <span class="attr">js:</span></span><br><span class="line">  <span class="comment"># 其他可选配置</span></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Facebook评论插件（参考文档：https://developers.facebook.com/docs/plugins/comments/）</span></span><br><span class="line"><span class="attr">facebook_comments:</span></span><br><span class="line">  <span class="comment"># 应用ID</span></span><br><span class="line">  <span class="attr">app_id:</span></span><br><span class="line">  <span class="comment"># 可选：用户ID</span></span><br><span class="line">  <span class="attr">user_id:</span></span><br><span class="line">  <span class="comment"># 每页显示评论数</span></span><br><span class="line">  <span class="attr">pageSize:</span> <span class="number">10</span></span><br><span class="line">  <span class="comment"># 选择：social / time / reverse_time</span></span><br><span class="line">  <span class="attr">order_by:</span> <span class="string">social</span></span><br><span class="line">  <span class="comment"># 语言</span></span><br><span class="line">  <span class="attr">lang:</span> <span class="string">en_US</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Twikoo评论系统（参考文档：https://github.com/imaegoo/twikoo）</span></span><br><span class="line"><span class="attr">twikoo:</span></span><br><span class="line">  <span class="comment"># 环境ID</span></span><br><span class="line">  <span class="attr">envId:</span></span><br><span class="line">  <span class="comment"># 区域</span></span><br><span class="line">  <span class="attr">region:</span></span><br><span class="line">  <span class="comment"># 是否用Twikoo访客计数作为页面浏览量</span></span><br><span class="line">  <span class="attr">visitor:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 其他可选配置</span></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Giscus评论系统（参考文档：https://giscus.app/）</span></span><br><span class="line"><span class="attr">giscus:</span></span><br><span class="line">  <span class="comment"># 仓库</span></span><br><span class="line">  <span class="attr">repo:</span></span><br><span class="line">  <span class="comment"># 仓库ID</span></span><br><span class="line">  <span class="attr">repo_id:</span></span><br><span class="line">  <span class="comment"># 分类ID</span></span><br><span class="line">  <span class="attr">category_id:</span></span><br><span class="line">  <span class="comment"># 主题</span></span><br><span class="line">  <span class="attr">light_theme:</span> <span class="string">light</span></span><br><span class="line">  <span class="attr">dark_theme:</span> <span class="string">dark</span></span><br><span class="line">  <span class="attr">js:</span></span><br><span class="line">  <span class="comment"># 其他可选配置</span></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Remark42评论系统（参考文档：https://remark42.com/docs/configuration/frontend/）</span></span><br><span class="line"><span class="attr">remark42:</span></span><br><span class="line">  <span class="comment"># 服务器地址</span></span><br><span class="line">  <span class="attr">host:</span></span><br><span class="line">  <span class="comment"># 站点ID</span></span><br><span class="line">  <span class="attr">siteId:</span></span><br><span class="line">  <span class="comment"># 其他可选配置</span></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Artalk评论系统（参考文档：https://artalk.js.org/guide/frontend/config.html）</span></span><br><span class="line"><span class="attr">artalk:</span></span><br><span class="line">  <span class="comment"># 服务器地址</span></span><br><span class="line">  <span class="attr">server:</span></span><br><span class="line">  <span class="comment"># 站点名</span></span><br><span class="line">  <span class="attr">site:</span></span><br><span class="line">  <span class="comment"># 是否用Artalk访客计数作为页面浏览量</span></span><br><span class="line">  <span class="attr">visitor:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 其他可选配置</span></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 聊天服务</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="attr">chat:</span></span><br><span class="line">  <span class="comment"># 选择：chatra/tidio/crisp，无需则留空</span></span><br><span class="line">  <span class="attr">use:</span></span><br><span class="line">  <span class="comment"># 聊天按钮【推荐】</span></span><br><span class="line">  <span class="comment"># 会在网站右下角创建按钮，并隐藏原生按钮</span></span><br><span class="line">  <span class="attr">rightside_button:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 向上滚动时显示原生聊天按钮，向下滚动时隐藏</span></span><br><span class="line">  <span class="attr">button_hide_show:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Chatra聊天服务（参考网站：https://chatra.io/）</span></span><br><span class="line"><span class="attr">chatra:</span></span><br><span class="line">  <span class="comment"># Chatra的服务ID</span></span><br><span class="line">  <span class="attr">id:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Tidio聊天服务（参考网站：https://www.tidio.com/）</span></span><br><span class="line"><span class="attr">tidio:</span></span><br><span class="line">  <span class="comment"># Tidio的公钥</span></span><br><span class="line">  <span class="attr">public_key:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Crisp聊天服务（参考网站：https://crisp.chat/en/）</span></span><br><span class="line"><span class="attr">crisp:</span></span><br><span class="line">  <span class="comment"># Crisp的网站ID</span></span><br><span class="line">  <span class="attr">website_id:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 统计分析</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 百度统计（参考网站：https://tongji.baidu.com/web/welcome/login）</span></span><br><span class="line"><span class="attr">baidu_analytics:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 谷歌分析（参考网站：https://analytics.google.com/analytics/web/）</span></span><br><span class="line"><span class="attr">google_analytics:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Cloudflare分析（参考网站：https://www.cloudflare.com/zh-tw/web-analytics/）</span></span><br><span class="line"><span class="attr">cloudflare_analytics:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Microsoft Clarity（参考网站：https://clarity.microsoft.com/）</span></span><br><span class="line"><span class="attr">microsoft_clarity:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Umami分析（参考网站：https://umami.is/）</span></span><br><span class="line"><span class="attr">umami_analytics:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 自托管部署时，配置Umami实例的主机名</span></span><br><span class="line">  <span class="attr">serverURL:</span></span><br><span class="line">  <span class="comment"># 脚本名称</span></span><br><span class="line">  <span class="attr">script_name:</span> <span class="string">script.js</span></span><br><span class="line">  <span class="comment"># 网站ID</span></span><br><span class="line">  <span class="attr">website_id:</span></span><br><span class="line">  <span class="comment"># 其他可选配置</span></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line">  <span class="attr">UV_PV:</span></span><br><span class="line">    <span class="comment"># 站点UV统计</span></span><br><span class="line">    <span class="attr">site_uv:</span> <span class="literal">false</span></span><br><span class="line">    <span class="comment"># 站点PV统计</span></span><br><span class="line">    <span class="attr">site_pv:</span> <span class="literal">false</span></span><br><span class="line">    <span class="comment"># 页面PV统计</span></span><br><span class="line">    <span class="attr">page_pv:</span> <span class="literal">false</span></span><br><span class="line">    <span class="comment"># Umami Cloud（填API密钥）/自托管Umami（填令牌）</span></span><br><span class="line">    <span class="attr">token:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Google标签管理器（参考网站：https://www.googletagmanager.com/）</span></span><br><span class="line"><span class="attr">google_tag_manager:</span></span><br><span class="line">  <span class="comment"># 标签ID</span></span><br><span class="line">  <span class="attr">tag_id:</span></span><br><span class="line">  <span class="comment"># 可选：域名</span></span><br><span class="line">  <span class="attr">domain:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 广告设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Google Adsense广告</span></span><br><span class="line"><span class="attr">google_adsense:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 是否自动投放广告</span></span><br><span class="line">  <span class="attr">auto_ads:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 广告脚本URL</span></span><br><span class="line">  <span class="attr">js:</span> <span class="string">https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js</span></span><br><span class="line">  <span class="comment"># 客户ID</span></span><br><span class="line">  <span class="attr">client:</span></span><br><span class="line">  <span class="comment"># 是否启用页面级广告</span></span><br><span class="line">  <span class="attr">enable_page_level_ads:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 手动插入广告</span></span><br><span class="line"><span class="comment"># 无需则留空</span></span><br><span class="line"><span class="attr">ad:</span></span><br><span class="line">  <span class="comment"># 在首页每三篇文章后插入广告</span></span><br><span class="line">  <span class="attr">index:</span></span><br><span class="line">  <span class="comment"># 在侧边栏插入广告</span></span><br><span class="line">  <span class="attr">aside:</span></span><br><span class="line">  <span class="comment"># 在文章分页前插入广告</span></span><br><span class="line">  <span class="attr">post:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 站点验证</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="attr">site_verification:</span></span><br><span class="line"><span class="comment"># - name: google-site-verification</span></span><br><span class="line"><span class="comment">#   content: xxxxxx</span></span><br><span class="line"><span class="comment"># - name: baidu-site-verification</span></span><br><span class="line"><span class="comment">#   content: xxxxxxx</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 美化/效果设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 自定义主题颜色</span></span><br><span class="line"><span class="comment"># 注意：颜色值必须用双引号包裹，如&quot;#000&quot;，否则可能导致错误！</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># theme_color:</span></span><br><span class="line"><span class="comment">#   enable: true</span></span><br><span class="line"><span class="comment">#   main: &quot;#49B1F5&quot;</span></span><br><span class="line"><span class="comment">#   paginator: &quot;#00c4b6&quot;</span></span><br><span class="line"><span class="comment">#   button_hover: &quot;#FF7242&quot;</span></span><br><span class="line"><span class="comment">#   text_selection: &quot;#00c4b6&quot;</span></span><br><span class="line"><span class="comment">#   link_color: &quot;#99a9bf&quot;</span></span><br><span class="line"><span class="comment">#   meta_color: &quot;#858585&quot;</span></span><br><span class="line"><span class="comment">#   hr_color: &quot;#A4D8FA&quot;</span></span><br><span class="line"><span class="comment">#   code_foreground: &quot;#F47466&quot;</span></span><br><span class="line"><span class="comment">#   code_background: &quot;rgba(27, 31, 35, .05)&quot;</span></span><br><span class="line"><span class="comment">#   toc_color: &quot;#00c4b6&quot;</span></span><br><span class="line"><span class="comment">#   blockquote_padding_color: &quot;#49b1f5&quot;</span></span><br><span class="line"><span class="comment">#   blockquote_background_color: &quot;#49b1f5&quot;</span></span><br><span class="line"><span class="comment">#   scrollbar_color: &quot;#49b1f5&quot;</span></span><br><span class="line"><span class="comment">#   meta_theme_color_light: &quot;ffffff&quot;</span></span><br><span class="line"><span class="comment">#   meta_theme_color_dark: &quot;#0d0d0d&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 分类页与标签页的界面设置</span></span><br><span class="line"><span class="comment"># 选择：index（与首页UI相同）/ default（与归档页UI相同）</span></span><br><span class="line"><span class="comment"># 留空或设为index</span></span><br><span class="line"><span class="attr">category_ui:</span></span><br><span class="line"><span class="attr">tag_ui:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># UI元素是否启用圆角</span></span><br><span class="line"><span class="attr">rounded_corners_ui:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 是否拉伸文本行，使每行宽度相等（两端对齐）</span></span><br><span class="line"><span class="attr">text_align_justify:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 是否为页眉和页脚添加遮罩</span></span><br><span class="line"><span class="attr">mask:</span></span><br><span class="line">  <span class="attr">header:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">footer:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 加载动画</span></span><br><span class="line"><span class="attr">preloader:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 动画来源</span></span><br><span class="line">  <span class="comment"># 1. 全屏加载动画</span></span><br><span class="line">  <span class="comment"># 2. 进度条动画（pace）</span></span><br><span class="line">  <span class="attr">source:</span> <span class="number">1</span></span><br><span class="line">  <span class="comment"># pace主题（参考：https://codebyzach.github.io/pace/）</span></span><br><span class="line">  <span class="attr">pace_css_url:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 页面过渡动画</span></span><br><span class="line"><span class="attr">enter_transitions:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 默认显示模式 - light（明亮模式，默认）/ dark（暗黑模式）</span></span><br><span class="line"><span class="attr">display_mode:</span> <span class="string">dark</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 文章内容美化配置</span></span><br><span class="line"><span class="attr">beautify:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 指定美化范围（site为全站，post仅文章）</span></span><br><span class="line">  <span class="attr">field:</span> <span class="string">post</span></span><br><span class="line">  <span class="comment"># 指定标题前缀图标，如&#x27;\f0c1&#x27;（Font Awesome图标unicode值）</span></span><br><span class="line">  <span class="attr">title_prefix_icon:</span> <span class="string">&#x27;\f863&#x27;</span></span><br><span class="line">  <span class="comment"># 指定标题前缀图标的颜色，如&#x27;#F47466&#x27;</span></span><br><span class="line">  <span class="attr">title_prefix_icon_color:</span> <span class="string">&quot;#F47466&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 全局字体设置</span></span><br><span class="line"><span class="comment"># 非专业人员请勿修改以下设置</span></span><br><span class="line"><span class="attr">font:</span></span><br><span class="line">  <span class="attr">global_font_size:</span></span><br><span class="line">  <span class="attr">code_font_size:</span></span><br><span class="line">  <span class="attr">font_family:</span></span><br><span class="line">  <span class="attr">code_font_family:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 网站标题与副标题的字体设置</span></span><br><span class="line"><span class="attr">blog_title_font:</span></span><br><span class="line">  <span class="attr">font_link:</span></span><br><span class="line">  <span class="attr">font_family:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 分隔线图标设置</span></span><br><span class="line"><span class="attr">hr_icon:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># Font Awesome图标的unicode值，如&#x27;\3423&#x27;</span></span><br><span class="line">  <span class="attr">icon:</span></span><br><span class="line">  <span class="attr">icon_top:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 打字机特效（参考文档：https://github.com/disjukr/activate-power-mode）</span></span><br><span class="line"><span class="attr">activate_power_mode:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 是否启用彩色效果</span></span><br><span class="line">  <span class="attr">colorful:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 是否启用震动效果</span></span><br><span class="line">  <span class="attr">shake:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 移动设备上是否启用</span></span><br><span class="line">  <span class="attr">mobile:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 背景效果</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># canvas_ribbon丝带背景（参考文档：https://github.com/hustcc/ribbon.js）</span></span><br><span class="line"><span class="attr">canvas_ribbon:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 丝带尺寸</span></span><br><span class="line">  <span class="attr">size:</span> <span class="number">150</span></span><br><span class="line">  <span class="comment"># 丝带透明度（0~1）</span></span><br><span class="line">  <span class="attr">alpha:</span> <span class="number">0.6</span></span><br><span class="line">  <span class="comment"># z-index属性</span></span><br><span class="line">  <span class="attr">zIndex:</span> <span class="number">-1</span></span><br><span class="line">  <span class="comment"># 是否点击切换颜色</span></span><br><span class="line">  <span class="attr">click_to_change:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 移动设备上是否启用</span></span><br><span class="line">  <span class="attr">mobile:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 飘动丝带背景</span></span><br><span class="line"><span class="attr">canvas_fluttering_ribbon:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 移动设备上是否启用</span></span><br><span class="line">  <span class="attr">mobile:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># canvas_nest粒子连线背景（参考文档：https://github.com/hustcc/canvas-nest.js）</span></span><br><span class="line"><span class="attr">canvas_nest:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 线条颜色，默认：&#x27;0,0,0&#x27;；RGB值格式：(R,G,B)，注意用英文逗号分隔</span></span><br><span class="line">  <span class="attr">color:</span> <span class="string">&#x27;0,0,255&#x27;</span></span><br><span class="line">  <span class="comment"># 线条透明度（0~1）</span></span><br><span class="line">  <span class="attr">opacity:</span> <span class="number">0.7</span></span><br><span class="line">  <span class="comment"># 背景的z-index属性</span></span><br><span class="line">  <span class="attr">zIndex:</span> <span class="number">-1</span></span><br><span class="line">  <span class="comment"># 线条数量</span></span><br><span class="line">  <span class="attr">count:</span> <span class="number">99</span></span><br><span class="line">  <span class="comment"># 移动设备上是否启用</span></span><br><span class="line">  <span class="attr">mobile:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 鼠标点击效果：烟花</span></span><br><span class="line"><span class="attr">fireworks:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># z-index属性</span></span><br><span class="line">  <span class="attr">zIndex:</span> <span class="number">9999</span></span><br><span class="line">  <span class="comment"># 移动设备上是否启用</span></span><br><span class="line">  <span class="attr">mobile:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 鼠标点击效果：心形符号</span></span><br><span class="line"><span class="attr">click_heart:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 移动设备上是否启用</span></span><br><span class="line">  <span class="attr">mobile:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 鼠标点击效果：文字</span></span><br><span class="line"><span class="attr">clickShowText:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 显示文字</span></span><br><span class="line">  <span class="attr">text:</span></span><br><span class="line">  <span class="comment"># - I</span></span><br><span class="line">  <span class="comment"># - LOVE</span></span><br><span class="line">  <span class="comment"># - YOU</span></span><br><span class="line">  <span class="comment"># 文字大小</span></span><br><span class="line">  <span class="attr">fontSize:</span> <span class="string">15px</span></span><br><span class="line">  <span class="comment"># 是否随机显示文字</span></span><br><span class="line">  <span class="attr">random:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 移动设备上是否启用</span></span><br><span class="line">  <span class="attr">mobile:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 灯箱设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 选择：fancybox / medium_zoom</span></span><br><span class="line"><span class="comment"># 参考文档：https://github.com/francoischalifour/medium-zoom、https://fancyapps.com/fancybox/</span></span><br><span class="line"><span class="comment"># 无需则留空</span></span><br><span class="line"><span class="attr">lightbox:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 标签插件设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 系列文章</span></span><br><span class="line"><span class="attr">series:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 排序依据：title（按标题）或date（按日期）</span></span><br><span class="line">  <span class="attr">orderBy:</span> <span class="string">&#x27;title&#x27;</span></span><br><span class="line">  <span class="comment"># 排序顺序：1为升序，-1为降序</span></span><br><span class="line">  <span class="attr">order:</span> <span class="number">1</span></span><br><span class="line">  <span class="comment"># 是否显示编号</span></span><br><span class="line">  <span class="attr">number:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># ABCJS - 音乐符号插件（参考文档：https://github.com/paulrosen/abcjs）</span></span><br><span class="line"><span class="attr">abcjs:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 是否每页启用</span></span><br><span class="line">  <span class="attr">per_page:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Mermaid - 流程图插件（参考文档：https://github.com/mermaid-js/mermaid）</span></span><br><span class="line"><span class="attr">mermaid:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 是否通过代码块编写Mermaid图表</span></span><br><span class="line">  <span class="attr">code_write:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 内置主题：default / forest / dark / neutral</span></span><br><span class="line">  <span class="attr">theme:</span></span><br><span class="line">    <span class="attr">light:</span> <span class="string">default</span></span><br><span class="line">    <span class="attr">dark:</span> <span class="string">dark</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># chartjs - 图表插件（参考文档：https://www.chartjs.org/docs/latest/）</span></span><br><span class="line"><span class="attr">chartjs:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 非专业人员请勿修改以下设置</span></span><br><span class="line">  <span class="comment"># 默认配置仅在未指定MD语法时生效</span></span><br><span class="line">  <span class="comment"># 图表全局字体颜色</span></span><br><span class="line">  <span class="attr">fontColor:</span></span><br><span class="line">    <span class="attr">light:</span> <span class="string">&#x27;rgba(0, 0, 0, 0.8)&#x27;</span></span><br><span class="line">    <span class="attr">dark:</span> <span class="string">&#x27;rgba(255, 255, 255, 0.8)&#x27;</span></span><br><span class="line">  <span class="comment"># 图表全局边框颜色</span></span><br><span class="line">  <span class="attr">borderColor:</span></span><br><span class="line">    <span class="attr">light:</span> <span class="string">&#x27;rgba(0, 0, 0, 0.1)&#x27;</span></span><br><span class="line">    <span class="attr">dark:</span> <span class="string">&#x27;rgba(255, 255, 255, 0.2)&#x27;</span></span><br><span class="line">  <span class="comment"># 雷达图与极区图的刻度标签背景色</span></span><br><span class="line">  <span class="attr">scale_ticks_backdropColor:</span></span><br><span class="line">    <span class="attr">light:</span> <span class="string">&#x27;transparent&#x27;</span></span><br><span class="line">    <span class="attr">dark:</span> <span class="string">&#x27;transparent&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Note - Bootstrap提示框插件</span></span><br><span class="line"><span class="attr">note:</span></span><br><span class="line">  <span class="comment"># Note标签样式：</span></span><br><span class="line">  <span class="comment">#  - simple    bs-callout旧版警告样式，默认</span></span><br><span class="line">  <span class="comment">#  - modern    bs-callout新版（v2-v3）警告样式</span></span><br><span class="line">  <span class="comment">#  - flat      带背景的扁平提示框样式，类似Mozilla或StackOverflow</span></span><br><span class="line">  <span class="comment">#  - disabled  禁用Note标签的所有CSS样式</span></span><br><span class="line">  <span class="attr">style:</span> <span class="string">flat</span></span><br><span class="line">  <span class="comment"># 是否显示图标</span></span><br><span class="line">  <span class="attr">icons:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 边框半径</span></span><br><span class="line">  <span class="attr">border_radius:</span> <span class="number">3</span></span><br><span class="line">  <span class="comment"># modern和flat样式的背景色偏移百分比（modern：-12 | 12；flat：-18 | 6）</span></span><br><span class="line">  <span class="comment"># 此偏移也适用于标签变量，可与disabled模式配合使用</span></span><br><span class="line">  <span class="attr">light_bg_offset:</span> <span class="number">0</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"><span class="comment"># 其他设置</span></span><br><span class="line"><span class="comment"># --------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Pjax无刷新页面切换（参考文档：https://github.com/MoOx/pjax）</span></span><br><span class="line"><span class="attr">pjax:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 排除不使用Pjax的页面，如&#x27;/music/&#x27;</span></span><br><span class="line">  <span class="attr">exclude:</span></span><br><span class="line">  <span class="comment"># - /xxxxxx/</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 注入CSS和脚本（用于aplayer/meting音乐播放器）</span></span><br><span class="line"><span class="attr">aplayerInject:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 是否每页启用</span></span><br><span class="line">  <span class="attr">per_page:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Snackbar - 消息提示组件（参考文档：https://github.com/polonel/SnackBar）</span></span><br><span class="line"><span class="comment"># 位置：top-left（左上）/ top-center（中上）/ top-right（右上）/ bottom-left（左下）/ bottom-center（中下）/ bottom-right（右下）</span></span><br><span class="line"><span class="attr">snackbar:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 提示位置</span></span><br><span class="line">  <span class="attr">position:</span> <span class="string">bottom-left</span></span><br><span class="line">  <span class="comment"># 明亮模式与暗黑模式下的提示框背景色</span></span><br><span class="line">  <span class="attr">bg_light:</span> <span class="string">&#x27;#49b1f5&#x27;</span></span><br><span class="line">  <span class="attr">bg_dark:</span> <span class="string">&#x27;#1f1f1f&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Instant.page - 预加载插件（参考文档：https://instant.page/）</span></span><br><span class="line"><span class="attr">instantpage:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Lazyload - 图片懒加载插件（参考文档：https://github.com/verlok/vanilla-lazyload）</span></span><br><span class="line"><span class="attr">lazyload:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 是否用浏览器原生懒加载替代vanilla-lazyload</span></span><br><span class="line">  <span class="attr">native:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 指定懒加载范围（site为全站，post仅文章）</span></span><br><span class="line">  <span class="attr">field:</span> <span class="string">site</span></span><br><span class="line">  <span class="comment"># 占位图</span></span><br><span class="line">  <span class="attr">placeholder:</span></span><br><span class="line">  <span class="comment"># 是否启用模糊效果</span></span><br><span class="line">  <span class="attr">blur:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># PWA - 渐进式Web应用（参考文档：https://github.com/JLHwung/hexo-offline）</span></span><br><span class="line"><span class="comment"># ---------------</span></span><br><span class="line"><span class="attr">pwa:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># manifest文件路径</span></span><br><span class="line">  <span class="attr">manifest:</span></span><br><span class="line">  <span class="comment"># Apple Touch图标路径</span></span><br><span class="line">  <span class="attr">apple_touch_icon:</span></span><br><span class="line">  <span class="comment"># 32×32像素的favicon图标路径</span></span><br><span class="line">  <span class="attr">favicon_32_32:</span></span><br><span class="line">  <span class="comment"># 16×16像素的favicon图标路径</span></span><br><span class="line">  <span class="attr">favicon_16_16:</span></span><br><span class="line">  <span class="comment"># mask图标路径</span></span><br><span class="line">  <span class="attr">mask_icon:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Open Graph元标签（参考文档：https://hexo.io/docs/helpers#open-graph）</span></span><br><span class="line"><span class="attr">Open_Graph_meta:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 其他可选配置</span></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line">  <span class="comment"># twitter_card:</span></span><br><span class="line">  <span class="comment"># twitter_image:</span></span><br><span class="line">  <span class="comment"># twitter_id:</span></span><br><span class="line">  <span class="comment"># twitter_site:</span></span><br><span class="line">  <span class="comment"># google_plus:</span></span><br><span class="line">  <span class="comment"># fb_admins:</span></span><br><span class="line">  <span class="comment"># fb_app_id:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 结构化数据（参考文档：https://developers.google.com/search/docs/guides/intro-structured-data）</span></span><br><span class="line"><span class="attr">structured_data:</span></span><br><span class="line">  <span class="comment"># 是否启用</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 网站的备用名称，用于结构化数据</span></span><br><span class="line">  <span class="comment"># 格式：[&#x27;名称1&#x27;, &#x27;名称2&#x27;]</span></span><br><span class="line">  <span class="attr">alternate_name:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 自动添加CSS浏览器前缀以确保兼容性</span></span><br><span class="line"><span class="attr">css_prefix:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 代码注入</span></span><br><span class="line"><span class="comment"># 在head标签底部（&lt;/head&gt;前）和body标签底部（&lt;/body&gt;前）插入代码</span></span><br><span class="line"><span class="attr">inject:</span></span><br><span class="line">  <span class="attr">head:</span></span><br><span class="line">  <span class="comment"># - &lt;link rel=&quot;stylesheet&quot; href=&quot;/xxx.css&quot;&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;stylesheet&quot;</span> <span class="string">href=&quot;/css/custom.css&quot;&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;stylesheet&quot;</span> <span class="string">href=&quot;/css/modify.css&quot;&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;link</span> <span class="string">rel=&quot;stylesheet&quot;</span> <span class="string">href=&quot;/css/waline.css&quot;&gt;</span></span><br><span class="line">  <span class="attr">bottom:</span></span><br><span class="line">  <span class="comment"># - &lt;script src=&quot;xxxx&quot;&gt;&lt;/script&gt;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&lt;script</span> <span class="string">async</span> <span class="string">src=&quot;/js/title.js&quot;&gt;&lt;/script&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># CDN设置</span></span><br><span class="line"><span class="comment"># 非专业人员请勿修改以下设置</span></span><br><span class="line"><span class="attr">CDN:</span></span><br><span class="line">  <span class="comment"># 内部脚本与第三方脚本的CDN提供商</span></span><br><span class="line">  <span class="comment"># 两者可选：local（本地）/ jsdelivr / unpkg / cdnjs / custom（自定义）</span></span><br><span class="line">  <span class="comment"># 注意：开发版仅支持内部脚本使用&#x27;local&#x27;</span></span><br><span class="line">  <span class="comment"># 注意：第三方脚本设为&#x27;local&#x27;时，需安装hexo-butterfly-extjs插件</span></span><br><span class="line">  <span class="attr">internal_provider:</span> <span class="string">local</span></span><br><span class="line">  <span class="attr">third_party_provider:</span> <span class="string">jsdelivr</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># 是否在URL中添加版本号，true或false</span></span><br><span class="line">  <span class="attr">version:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># 自定义格式</span></span><br><span class="line">  <span class="comment"># 示例：https://cdn.staticfile.org/$&#123;cdnjs_name&#125;/$&#123;version&#125;/$&#123;min_cdnjs_file&#125;</span></span><br><span class="line">  <span class="attr">custom_format:</span></span><br><span class="line"></span><br><span class="line">  <span class="attr">option:</span></span><br><span class="line">  <span class="comment"># abcjs_basic_js:</span></span><br><span class="line">  <span class="comment"># activate_power_mode:</span></span><br><span class="line">  <span class="comment"># algolia_js:</span></span><br><span class="line">  <span class="comment"># algolia_search:</span></span><br><span class="line">  <span class="comment"># aplayer_css:</span></span><br><span class="line">  <span class="comment"># aplayer_js:</span></span><br><span class="line">  <span class="comment"># artalk_css:</span></span><br><span class="line">  <span class="comment"># artalk_js:</span></span><br><span class="line">  <span class="comment"># blueimp_md5:</span></span><br><span class="line">  <span class="comment"># busuanzi:</span></span><br><span class="line">  <span class="comment"># canvas_fluttering_ribbon:</span></span><br><span class="line">  <span class="comment"># canvas_nest:</span></span><br><span class="line">  <span class="comment"># canvas_ribbon:</span></span><br><span class="line">  <span class="comment"># chartjs:</span></span><br><span class="line">  <span class="comment"># click_heart:</span></span><br><span class="line">  <span class="comment"># clickShowText:</span></span><br><span class="line">  <span class="comment"># disqusjs:</span></span><br><span class="line">  <span class="comment"># disqusjs_css:</span></span><br><span class="line">  <span class="comment"># docsearch_css:</span></span><br><span class="line">  <span class="comment"># docsearch_js:</span></span><br><span class="line">  <span class="comment"># egjs_infinitegrid:</span></span><br><span class="line">  <span class="comment"># fancybox:</span></span><br><span class="line">  <span class="comment"># fancybox_css:</span></span><br><span class="line">  <span class="comment"># fireworks:</span></span><br><span class="line">  <span class="comment"># fontawesome:</span></span><br><span class="line">  <span class="comment"># gitalk:</span></span><br><span class="line">  <span class="comment"># gitalk_css:</span></span><br><span class="line">  <span class="comment"># giscus:</span></span><br><span class="line">  <span class="comment"># instantpage:</span></span><br><span class="line">  <span class="comment"># katex:</span></span><br><span class="line">  <span class="comment"># katex_copytex:</span></span><br><span class="line">  <span class="comment"># lazyload:</span></span><br><span class="line">  <span class="comment"># local_search:</span></span><br><span class="line">  <span class="comment"># main:</span></span><br><span class="line">  <span class="comment"># main_css:</span></span><br><span class="line">  <span class="comment"># mathjax:</span></span><br><span class="line">  <span class="comment"># medium_zoom:</span></span><br><span class="line">  <span class="comment"># mermaid:</span></span><br><span class="line">  <span class="comment"># meting_js:</span></span><br><span class="line">  <span class="comment"># prismjs_autoloader:</span></span><br><span class="line">  <span class="comment"># prismjs_js:</span></span><br><span class="line">  <span class="comment"># prismjs_lineNumber_js:</span></span><br><span class="line">  <span class="comment"># pjax:</span></span><br><span class="line">  <span class="comment"># sharejs:</span></span><br><span class="line">  <span class="comment"># sharejs_css:</span></span><br><span class="line">  <span class="comment"># snackbar:</span></span><br><span class="line">  <span class="comment"># snackbar_css:</span></span><br><span class="line">  <span class="comment"># translate:</span></span><br><span class="line">  <span class="comment"># twikoo:</span></span><br><span class="line">  <span class="comment"># typed:</span></span><br><span class="line">  <span class="comment"># utils:</span></span><br><span class="line">  <span class="comment"># valine:</span></span><br><span class="line">  <span class="comment"># waline_css:</span></span><br><span class="line">  <span class="comment"># waline_js:</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Hexo-基础搭建&quot;&gt;&lt;a href=&quot;#Hexo-基础搭建&quot; class=&quot;headerlink&quot; title=&quot;Hexo 基础搭建&quot;&gt;&lt;/a&gt;Hexo 基础搭建&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;参考 &lt;a href=&quot;/posts/20251010083637.ht</summary>
      
    
    
    
    <category term="🍭小敏の半糖" scheme="https://xmblog.chrislin.eu.org/categories/%F0%9F%8D%AD%E5%B0%8F%E6%95%8F%E3%81%AE%E5%8D%8A%E7%B3%96/"/>
    
    
    <category term="💠Hexo" scheme="https://xmblog.chrislin.eu.org/tags/%F0%9F%92%A0Hexo/"/>
    
    <category term="🦋Butterfly" scheme="https://xmblog.chrislin.eu.org/tags/%F0%9F%A6%8BButterfly/"/>
    
    <category term="🌌晚风の雾岛 Misty" scheme="https://xmblog.chrislin.eu.org/tags/%F0%9F%8C%8C%E6%99%9A%E9%A3%8E%E3%81%AE%E9%9B%BE%E5%B2%9B-Misty/"/>
    
  </entry>
  
  <entry>
    <title>Hello World</title>
    <link href="https://xmblog.chrislin.eu.org/posts/20251010083637.html"/>
    <id>https://xmblog.chrislin.eu.org/posts/20251010083637.html</id>
    <published>2025-10-10T08:36:37.000Z</published>
    <updated>2026-11-10T13:02:16.261Z</updated>
    
    <content type="html"><![CDATA[<p>Welcome to <a href="https://hexo.io/">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues">GitHub</a>.</p><h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new <span class="string">&quot;My New Post&quot;</span></span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/writing.html">Writing</a></p><h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/server.html">Server</a></p><h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/generating.html">Generating</a></p><h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/one-command-deployment.html">Deployment</a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;Welcome to &lt;a href=&quot;https://hexo.io/&quot;&gt;Hexo&lt;/a&gt;! This is your very first post. Check &lt;a href=&quot;https://hexo.io/docs/&quot;&gt;documentation&lt;/a&gt; for</summary>
      
    
    
    
    <category term="🍭小敏の半糖" scheme="https://xmblog.chrislin.eu.org/categories/%F0%9F%8D%AD%E5%B0%8F%E6%95%8F%E3%81%AE%E5%8D%8A%E7%B3%96/"/>
    
    
  </entry>
  
</feed>
