<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Hxsyzl blog</title><description>记录一点小东西</description><link>https://www.497995.xyz/</link><language>zh_CN</language><item><title>加群向导&amp;其他问题</title><link>https://www.497995.xyz/posts/chat/</link><guid isPermaLink="true">https://www.497995.xyz/posts/chat/</guid><description>如何联系或许是一只龙，以及加入群聊和常见问题解答。</description><pubDate>Wed, 23 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;加入群聊&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;QQ 群号&lt;/strong&gt;：&lt;code&gt;118098857&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;点击链接加入群聊【LG kernel release channel】&lt;/strong&gt;：&lt;a href=&quot;https://qm.qq.com/q/Yp6hbIQ0WO&quot;&gt;https://qm.qq.com/q/Yp6hbIQ0WO&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;常见问题&lt;/h2&gt;
&lt;h3&gt;EdgeOne CDN 相关&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q: 内测时间截至到哪？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A: “方法 1” 的截止日期为 2025 年 7 月 25 日 23:59:59 (UTC+8)。“方法 2” 和 “方法 3” 将在 7 月 15 日之后继续。我们目前处于有限测试阶段。详情请参阅：&lt;a href=&quot;https://edgeone.ai/zh/redemption&quot;&gt;EdgeOne 兑换活动规则&lt;/a&gt;第五条。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q: 国内外兑换码通用吗？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A: 通用。但如果您需要同时使用国内和国际站，则需要两个独立的兑换码。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q: 国内外站有什么区别？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A: 国际站如果需要使用中国大陆节点，必须进行实名认证，但不支持使用中国大陆身份证。国内站则无此限制。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q: 国际站绑卡有什么要求？是否必须为外币卡？授权费多少？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A: 支持银联卡。CVC 安全码请填写卡号背面的后三位数字。会有一笔 1 美元的授权费用，该费用在验证后会退还。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q: 回源到 Cloudflare 站点后报错 “423 Locked” 怎么办？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A: 将回源 HOST 设置为您的源站地址。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q: 如何套上家里的服务器（“家里云”）？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A: “家里云” 需使用 IPv6 和 DDNS。在 EdgeOne 中，将回源地址设置为您的 v6 域名及相应端口即可。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q: 免费套餐限速吗？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A: 单线程下载速度限制为 512KB/s。在多线程环境下，我个人的测试速度最高可达 72MB/s。&lt;/p&gt;
&lt;h3&gt;内网穿透相关&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q: 我怎么判断自己的网络环境是不是 NAT1？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A: 可以安装 Lucky 等工具，尝试通过 STUN 服务进行打洞测试。如果成功，则通常意味着您的网络类型为 NAT1。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q: 如何尽力将我的网络优化成 NAT1？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A: 推荐配置：将光猫设置为桥接模式，使用路由器进行 PPPoE 拨号，并开启 UPnP 功能。如果需要，也可以设置 DMZ，将其指向您希望获得 NAT1 体验的设备 IP 地址。&lt;/p&gt;
</content:encoded></item><item><title>博客侧边栏美化：集成一个智能天气卡片</title><link>https://www.497995.xyz/posts/add-weather-widget/</link><guid isPermaLink="true">https://www.497995.xyz/posts/add-weather-widget/</guid><description>通过一个 Svelte 组件，为您的博客侧边栏添加一个美观且功能强大的天气卡片。它能自动根据访客IP定位，并提供精确定位选项，还能根据天气情况显示不同图标。</description><pubDate>Mon, 18 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;前言&lt;/strong&gt; 📝&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;一个个性化的博客，除了内容优质，一些有趣的小部件也能极大地提升访客体验。&lt;/li&gt;
&lt;li&gt;天气卡片就是一个常见但非常实用的小功能，它能让访客在浏览您的博客时，顺便了解当地的天气情况，增加页面的互动性和趣味性。&lt;/li&gt;
&lt;li&gt;本教程将展示如何为博客添加一个智能天气卡片。它不仅会自动根据访客的 IP 地址显示天气，还提供了一个“精确定位”按钮，让用户可以获取更准确的天气信息。我们还会用漂亮的图标和渐变色来美化它。&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;方案概述&lt;/strong&gt; 🗺️
我们的天气卡片是一个独立的 Svelte 组件，它负责处理所有与天气相关的功能：&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;IP 定位&lt;/strong&gt; 📍：组件加载时，会首先通过 &lt;code&gt;ipapi.co&lt;/code&gt; 服务获取访客的大致位置（城市）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;天气查询&lt;/strong&gt; 🌦️：根据获取到的经纬度，调用 &lt;code&gt;Open-Meteo&lt;/code&gt; 的免费 API 来获取实时天气数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;精确定位（可选）&lt;/strong&gt; 🛰️：用户可以点击一个按钮，授权浏览器使用更高精度的地理位置（如 GPS），并通过 &lt;code&gt;Nominatim&lt;/code&gt; 服务将经纬度反向解析成城市名称，从而获得更准确的天气。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UI 展示&lt;/strong&gt; ✨：使用 Svelte 来动态展示天气信息，包括温度、风速，并根据天气代码显示不同的 Emoji 图标，同时卡片拥有现代化的渐变背景和布局。&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;实现步骤&lt;/strong&gt; ⚙️&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;整个实现过程都封装在一个 Svelte 组件中，非常便于集成。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建 Svelte 组件&lt;/strong&gt;
我们在 &lt;code&gt;src/components/widget/&lt;/code&gt; 目录下创建了 &lt;code&gt;Weather.svelte&lt;/code&gt; 文件。这是所有逻辑的核心。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;编写组件代码&lt;/strong&gt;
组件的 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 部分包含了所有功能逻辑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;onMount&lt;/code&gt;：组件挂载后，立即开始 IP 定位和天气查询流程。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fetchWeather&lt;/code&gt;：一个专门的函数，负责根据经纬度调用天气 API。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getCityFromCoords&lt;/code&gt;：当使用精确定位时，这个函数负责将经纬度转换成城市名。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;usePreciseLocation&lt;/code&gt;：处理“精确定位”按钮的点击事件，调用浏览器 Geolocation API。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getWeatherIcon&lt;/code&gt;：一个辅助函数，根据 Open-Meteo 返回的天气代码（weathercode）匹配一个合适的 Emoji 图标，让界面更生动。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;集成到侧边栏&lt;/strong&gt;
最后，我们只需要在侧边栏组件 &lt;code&gt;src/components/widget/SideBar.astro&lt;/code&gt; 中引入并使用这个新的天气组件即可。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
import Weather from &quot;./Weather.svelte&quot;;
---
&amp;lt;Weather client:load /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;client:load&lt;/code&gt; 指令告诉 Astro，这个组件需要在客户端加载和渲染，因为它的功能依赖于浏览器环境（如 &lt;code&gt;fetch&lt;/code&gt; 和 &lt;code&gt;navigator.geolocation&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;结束&lt;/strong&gt; 🎉
通过这个小小的天气卡片，我们的博客侧边栏变得更加生动和实用。这个功能不仅展示了 Svelte 在构建交互式组件方面的强大能力，也体现了通过组合多个第三方 API 来实现复杂功能的灵活性。
希望这个小教程能给你的博客带来一点新的色彩。如果你有任何问题或改进建议，欢迎随时提出！&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;附录：最终配置文件&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;天气卡片组件: &lt;code&gt;src/components/widget/Weather.svelte&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script lang=&quot;ts&quot;&amp;gt;
  import { onMount } from &apos;svelte&apos;;

  let weather: any = null;
  let city: string = &apos;&apos;;
  let error: string = &apos;&apos;;
  let loading: boolean = true;

  // Weather code to SVG icon mapping
  function getWeatherIcon(code: number): string {
    if (code === 0) return &apos;☀️&apos;; // Clear sky
    if (code &amp;gt;= 1 &amp;amp;&amp;amp; code &amp;lt;= 3) return &apos;☁️&apos;; // Mainly clear, partly cloudy, overcast
    if (code &amp;gt;= 45 &amp;amp;&amp;amp; code &amp;lt;= 48) return &apos;🌫️&apos;; // Fog
    if (code &amp;gt;= 51 &amp;amp;&amp;amp; code &amp;lt;= 65) return &apos;🌧️&apos;; // Drizzle, Rain
    if (code &amp;gt;= 80 &amp;amp;&amp;amp; code &amp;lt;= 82) return &apos;🌦️&apos;; // Rain showers
    if (code &amp;gt;= 95 &amp;amp;&amp;amp; code &amp;lt;= 99) return &apos;⛈️&apos;; // Thunderstorm
    return &apos;-&apos;;
  }

  async function fetchWeather(latitude: number, longitude: number) {
    const weatherResponse = await fetch(`https://api.open-meteo.com/v1/forecast?latitude=${latitude}&amp;amp;longitude=${longitude}&amp;amp;current_weather=true`);
    if (!weatherResponse.ok) {
      throw new Error(&apos;获取天气信息失败&apos;);
    }
    const weatherData = await weatherResponse.json();
    weather = weatherData.current_weather;
  }

  async function getCityFromCoords(latitude: number, longitude: number) {
    try {
      const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&amp;amp;lat=${latitude}&amp;amp;lon=${longitude}&amp;amp;accept-language=zh-CN`);
      if (!response.ok) return &apos;当前位置&apos;;
      const data = await response.json();
      return data.address.city || data.address.town || data.address.village || &apos;当前位置&apos;;
    } catch (e) {
      console.error(&quot;Reverse geocoding failed&quot;, e);
      return &apos;当前位置&apos;;
    }
  }

  async function usePreciseLocation() {
    loading = true;
    error = &apos;&apos;;
    if (!navigator.geolocation) {
      error = &apos;您的浏览器不支持精确定位。&apos;;
      loading = false;
      return;
    }
    navigator.geolocation.getCurrentPosition(
      async (position) =&amp;gt; {
        const { latitude, longitude } = position.coords;
        city = await getCityFromCoords(latitude, longitude);
        await fetchWeather(latitude, longitude);
        loading = false;
      },
      (err) =&amp;gt; {
        error = err.code === err.PERMISSION_DENIED ? &apos;您已拒绝位置权限，无法使用精确定位。&apos; : &apos;无法获取精确定位。&apos;;
        loading = false;
      }
    );
  }

  onMount(async () =&amp;gt; {
    try {
      const ipResponse = await fetch(&apos;https://ipapi.co/json/&apos;);
      if (!ipResponse.ok) throw new Error(&apos;获取IP信息失败&apos;);
      const ipData = await ipResponse.json();
      city = ipData.city || &apos;未知位置&apos;;
      const { latitude, longitude } = ipData;
      if (!latitude || !longitude) throw new Error(&apos;无法通过IP确定位置&apos;);
      await fetchWeather(latitude, longitude);
    } catch (e: any) {
      error = e.message;
      console.error(e);
    } finally {
      loading = false;
    }
  });
&amp;lt;/script&amp;gt;

&amp;lt;div class=&quot;weather-widget p-4 rounded-lg shadow-md bg-gradient-to-br from-blue-200 to-cyan-200 dark:from-gray-700 dark:to-gray-800 text-gray-800 dark:text-gray-200&quot;&amp;gt;
  &amp;lt;div class=&quot;flex justify-between items-center mb-3&quot;&amp;gt;
    &amp;lt;h2 class=&quot;text-lg font-bold&quot;&amp;gt;{city} 天气&amp;lt;/h2&amp;gt;
    &amp;lt;button on:click={usePreciseLocation} class=&quot;text-sm text-blue-600 dark:text-blue-400 hover:underline focus:outline-none&quot;&amp;gt;
      精确定位
    &amp;lt;/button&amp;gt;
  &amp;lt;/div&amp;gt;
  {#if loading}
    &amp;lt;div class=&quot;flex items-center justify-center h-24&quot;&amp;gt;
      &amp;lt;p&amp;gt;正在加载天气...&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  {:else if weather &amp;amp;&amp;amp; !error}
    &amp;lt;div class=&quot;flex items-center justify-around text-center&quot;&amp;gt;
      &amp;lt;div class=&quot;text-5xl&quot;&amp;gt;
        {getWeatherIcon(weather.weathercode)}
      &amp;lt;/div&amp;gt;
      &amp;lt;div class=&quot;pl-4&quot;&amp;gt;
        &amp;lt;div class=&quot;text-2xl font-bold&quot;&amp;gt;{weather.temperature}°C&amp;lt;/div&amp;gt;
        &amp;lt;div class=&quot;text-sm mt-1&quot;&amp;gt;
          &amp;lt;span title=&quot;风速&quot;&amp;gt;🌬️&amp;lt;/span&amp;gt; {weather.windspeed} km/h
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  {:else if error}
    &amp;lt;div class=&quot;flex items-center justify-center h-24&quot;&amp;gt;
      &amp;lt;p class=&quot;text-red-500&quot;&amp;gt;{error}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  {/if}
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>解放生产力：通过 GitHub Action 与 Cloudflare Worker 实现博客文章自动提交至必应</title><link>https://www.497995.xyz/posts/auto-bing-submit/</link><guid isPermaLink="true">https://www.497995.xyz/posts/auto-bing-submit/</guid><description>配置 GitHub Actions 和 Cloudflare Workers，实现当您推送新文章到仓库时，自动将链接提交到必应站长工具，彻底告别手动提交的烦恼。</description><pubDate>Tue, 12 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;前言&lt;/strong&gt; 📝&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;对于我们这些博主来说，写完一篇文章后，最重要的事情之一就是让搜索引擎尽快收录它。&lt;/li&gt;
&lt;li&gt;每次都手动去必应站长平台提交新文章的 URL，不仅繁琐，而且容易忘记，久而久之就成了个麻烦事 😩。&lt;/li&gt;
&lt;li&gt;本教程将带你设置一个“无服务器”的全自动化流程：当你用 &lt;code&gt;git push&lt;/code&gt; 推送新文章到 GitHub 仓库时，它会自动将文章链接提交给必应。一次配置，永久省心 ✅。&lt;/li&gt;
&lt;li&gt;本教程需要你有一个域名托管在 Cloudflare，并且对 GitHub Actions 有最基本的了解。&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;方案概述&lt;/strong&gt; 🗺️
整个自动化流程分为两个核心部分：&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare Worker&lt;/strong&gt; ☁️：一个轻量级的无服务器脚本，它接收一个文件名列表，然后负责调用必应的 API 来提交最终的 URL。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Action&lt;/strong&gt; 🚀：一个在你的仓库中运行的工作流，它会在你每次推送代码时被触发，找出新添加的文章，然后通知上面的 Cloudflare Worker 来干活。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;听起来很简单，对吧我们这就开始。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第一部分：配置 Cloudflare Worker&lt;/strong&gt; ⚙️&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我们的 Worker 是一个独立的 TypeScript 项目，专门用来处理来自 GitHub 的请求。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建 Worker 目录&lt;/strong&gt;
首先，在你的项目根目录创建一个新文件夹，比如 &lt;code&gt;bing-submit-worker&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;编写 Worker 代码 (&lt;code&gt;index.ts&lt;/code&gt;)&lt;/strong&gt;
这是 Worker 的核心逻辑。它会监听 POST 请求，解析请求中包含的文件名，拼接成完整的 URL，然后发送给必应。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;配置 Worker (&lt;code&gt;wrangler.toml&lt;/code&gt;)&lt;/strong&gt;
这个文件告诉 Cloudflare 如何部署你的 Worker。我们在这里明确了它的名称、入口文件以及最重要的——构建方式和模块格式，以避免一些常见的部署错误。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;项目依赖 (&lt;code&gt;package.json&lt;/code&gt; 和 &lt;code&gt;tsconfig.json&lt;/code&gt;)&lt;/strong&gt;
这两个文件用于管理项目依赖和 TypeScript 编译选项，确保我们的代码能在本地被正确识别，并且能成功构建。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第二部分：配置 GitHub Action&lt;/strong&gt; 🔗&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这是连接代码仓库和 Cloudflare Worker 的桥梁。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建工作流文件&lt;/strong&gt;
在你的仓库中，创建 &lt;code&gt;.github/workflows/bing-submit.yml&lt;/code&gt; 文件。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;编写工作流脚本&lt;/strong&gt;
这个脚本会在每次向 &lt;code&gt;src/content/posts/&lt;/code&gt; 目录推送新 &lt;code&gt;.md&lt;/code&gt; 文件时触发。它使用 &lt;code&gt;git diff --name-only --diff-filter=A&lt;/code&gt; 命令来精确地找出那些&lt;strong&gt;新添加&lt;/strong&gt;的文件，忽略对旧文件的修改。然后，它通过 &lt;code&gt;curl&lt;/code&gt; 命令，将这些新文件名发送给我们刚刚部署的 Cloudflare Worker。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;环境变量配置&lt;/strong&gt; 🔑
为了让整个流程正常工作，我们需要配置两个关键的“秘密”变量。这可以确保我们的 API 密钥等敏感信息不会被硬编码在代码里。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;BING_API_KEY&lt;/code&gt; (用于 Cloudflare Worker)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：这是你的必应站长工具 API 密钥，Worker 需要用它来获得向必应提交 URL 的授权。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;获取方式&lt;/strong&gt;：登录&lt;a href=&quot;https://www.bing.com/webmasters/apikey&quot;&gt;必应网站管理员工具&lt;/a&gt;，生成并复制你的 API 密钥。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置方法&lt;/strong&gt;：在你的终端里，进入 &lt;code&gt;bing-submit-worker&lt;/code&gt; 目录，然后运行以下命令。它会提示你输入密钥，粘贴进去回车即可。&lt;pre&gt;&lt;code&gt;npx wrangler secret put BING_API_KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;BING_SUBMIT_WORKER_URL&lt;/code&gt; (用于 GitHub Action)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：这是你部署成功后的 Cloudflare Worker 的访问 URL。GitHub Action 需要知道这个地址，才能把新文件名发送给它。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;获取方式&lt;/strong&gt;：当你成功运行 &lt;code&gt;npx wrangler deploy&lt;/code&gt; 后，终端会输出你的 Worker URL，通常格式是 &lt;code&gt;https://bing-submit-worker.your-account.workers.dev&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置方法&lt;/strong&gt;：
&lt;ol&gt;
&lt;li&gt;打开你的 GitHub 仓库页面，进入 &lt;code&gt;Settings&lt;/code&gt; &amp;gt; &lt;code&gt;Secrets and variables&lt;/code&gt; &amp;gt; &lt;code&gt;Actions&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;点击 &lt;code&gt;New repository secret&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Name&lt;/strong&gt;: &lt;code&gt;BING_SUBMIT_WORKER_URL&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Secret&lt;/strong&gt;: 粘贴你获取到的 Worker URL。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;结束&lt;/strong&gt; 🎉
希望这篇教程能帮助你搭建起自己的自动化 SEO 流程，把时间花在更有创造力的事情上，而不是重复性的手动提交。配置完成后，你就可以完全忘记“提交 URL”这件事了，因为系统会为你处理好一切。
如果你觉得这个方案不错，也可以根据这个思路，扩展到其他需要自动化的场景中去。祝大家折腾愉快！😋&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;&lt;strong&gt;附录：最终配置文件&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;本次修改涉及的核心文件的最终代码。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Cloudflare Worker: &lt;code&gt;bing-submit-worker/index.ts&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export interface Env {
	BING_API_KEY: string;
}

export default {
	async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise&amp;lt;Response&amp;gt; {
		if (request.method !== &apos;POST&apos;) {
			return new Response(&apos;Expected POST request&apos;, { status: 405 });
		}

		const { files } = await request.json&amp;lt;{ files: string[] }&amp;gt;();

		if (!files || !Array.isArray(files)) {
			return new Response(&apos;Missing &quot;files&quot; in request body&apos;, { status: 400 });
		}

		const siteUrl = &apos;https://www.497995.xyz&apos;;
		const urls = files.map(file =&amp;gt; `${siteUrl}/posts/${file.replace(/\.md$/, &apos;&apos;)}/`);

		try {
			const response = await fetch(`https://ssl.bing.com/webmaster/api.svc/json/SubmitUrlbatch?apikey=${env.BING_API_KEY}`, {
				method: &apos;POST&apos;,
				headers: {
					&apos;Content-Type&apos;: &apos;application/json; charset=utf-8&apos;,
				},
				body: JSON.stringify({
					siteUrl,
					urlList: urls,
				}),
			});

			const responseData = await response.json();

			if (response.ok) {
				console.log(&apos;Successfully submitted URLs to Bing:&apos;, responseData);
				return new Response(JSON.stringify({ success: true, submittedUrls: urls, bingResponse: responseData }), {
					headers: { &apos;Content-Type&apos;: &apos;application/json&apos; },
				});
			} else {
				console.error(&apos;Error submitting URLs to Bing:&apos;, responseData);
				return new Response(JSON.stringify({ success: false, error: responseData }), {
					status: response.status,
					headers: { &apos;Content-Type&apos;: &apos;application/json&apos; },
				});
			}
		} catch (error) {
			console.error(&apos;Failed to submit URLs to Bing:&apos;, error);
			return new Response(JSON.stringify({ success: false, error: (error as Error).message }), {
				status: 500,
				headers: { &apos;Content-Type&apos;: &apos;application/json&apos; },
			});
		}
	},
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;2. Cloudflare Worker 配置: &lt;code&gt;bing-submit-worker/wrangler.toml&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name = &quot;bing-submit-worker&quot;
main = &quot;index.ts&quot;
compatibility_date = &quot;2024-04-05&quot;

[build]
command = &quot;pnpm exec tsc&quot;

[build.upload]
format = &quot;modules&quot;

[vars]
# You need to create a secret for your Bing API key:
# wrangler secret put BING_API_KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;3. GitHub Action 工作流: &lt;code&gt;.github/workflows/bing-submit.yml&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: Submit New Posts to Bing

on:
  push:
    branches:
      - main # Or your default branch
    paths:
      - &apos;src/content/posts/**.md&apos;

jobs:
  submit-to-bing:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 2 # Fetches the last 2 commits to compare HEAD with the previous commit

      - name: Get new files
        id: get_new_files
        run: |
          # Handle the case where before commit might be all zeroes (initial commit)
          if [ &quot;${{ github.event.before }}&quot; = &quot;0000000000000000000000000000000000000000&quot; ]; then
            # For initial commit, get all markdown files in posts directory
            NEW_FILES=$(find src/content/posts -name &quot;*.md&quot; -type f | sed &apos;s#src/content/posts/##&apos; | jq -R . | jq -s .)
          else
            # Get the list of added files in the push
            NEW_FILES=$(git diff --name-only --diff-filter=A ${{ github.event.before }} ${{ github.event.after }} | grep &apos;^src/content/posts/.*\.md$&apos; | sed &apos;s#src/content/posts/##&apos; | jq -R . | jq -s .)
          fi
          
          echo &quot;New files detected: $NEW_FILES&quot;
          echo &quot;files=$NEW_FILES&quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT
          
          # Save to file for debugging
          echo &quot;$NEW_FILES&quot; &amp;gt; new_files.json

      - name: Show files to be submitted
        run: |
          echo &quot;Files that will be submitted:&quot;
          cat new_files.json
          
      - name: Trigger Bing Submission Worker
        if: steps.get_new_files.outputs.files != &apos;[]&apos; &amp;amp;&amp;amp; steps.get_new_files.outputs.files != &apos;&apos; &amp;amp;&amp;amp; steps.get_new_files.outputs.files != &apos;null&apos;
        run: |
          echo &quot;Sending files to Bing Submission Worker: ${{ steps.get_new_files.outputs.files }}&quot;
          curl -X POST &quot;${{ secrets.BING_SUBMIT_WORKER_URL }}&quot; \
          -H &quot;Content-Type: application/json&quot; \
          -d &quot;{\&quot;files\&quot;: ${{ steps.get_new_files.outputs.files }} }&quot;&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>给博客添加一个私有化的 AI 对话功能</title><link>https://www.497995.xyz/posts/self-hosted-ai-chat/</link><guid isPermaLink="true">https://www.497995.xyz/posts/self-hosted-ai-chat/</guid><description>不想用第三方聊天插件？本文将教你如何使用 Cloudflare Worker 和 Svelte，为你的网站快速集成一个完全由你掌控、支持任何 OpenAI 兼容 API 的 AI 对话机器人！</description><pubDate>Sun, 10 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;最近我一直在琢磨，怎么能让我的博客更有趣一点。除了写文章，还能不能提供一些更具互动性的功能？很自然地，我想到了现在大火的 AI 对话。&lt;/p&gt;
&lt;p&gt;市面上有很多现成的第三方聊天插件，但它们或多或少都有一些问题：要么是界面样式丑陋且难以定制，要么是需要将访客数据交给第三方，再或者就是价格不菲。作为一个喜欢折腾的开发者，我更倾向于一个能完全由自己掌控的解决方案。&lt;/p&gt;
&lt;p&gt;于是，我花了点时间，为我的博客打造了一个私有化的 AI 对话功能。它主要由两部分组成：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;一个部署在 &lt;strong&gt;Cloudflare Workers&lt;/strong&gt; 上的通用 AI 代理。&lt;/li&gt;
&lt;li&gt;一个用 &lt;strong&gt;Svelte&lt;/strong&gt; 编写的、功能丰富的聊天前端组件。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这个组合的好处是显而易见的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;隐私和控制&lt;/strong&gt;：API Key 和聊天记录完全由用户浏览器端掌控，不经过我的服务器。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高度灵活&lt;/strong&gt;：它支持任何与 OpenAI API 格式兼容的 AI 服务，无论是 OpenAI 官方、Azure、Google Gemini，还是自建的本地模型，只要 API 接口兼容，就能无缝切换。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;界面美观&lt;/strong&gt;：前端组件完全自定义，可以深度融入博客的整体风格。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;接下来，我将详细介绍如何将这个功能集成到你自己的网站中。&lt;/p&gt;
&lt;h2&gt;后端：一个解决 CORS 的通用 AI 代理&lt;/h2&gt;
&lt;p&gt;如果你尝试过直接在前端（浏览器）调用 AI 服务的 API，你大概率会遇到一个经典问题：&lt;strong&gt;CORS (跨域资源共享) 错误&lt;/strong&gt;。出于安全考虑，浏览器会阻止你的网站向一个不同的域名（比如 &lt;code&gt;api.openai.com&lt;/code&gt;）发送请求。&lt;/p&gt;
&lt;p&gt;为了解决这个问题，我编写了一个非常简单的 Cloudflare Worker，它的作用就像一个中间人或代理，前端将请求发送给这个 Worker，Worker 再把请求转发给真正的 AI API。因为 Worker 运行在云端服务器上，所以它不受浏览器同源策略的限制。&lt;/p&gt;
&lt;p&gt;这个 Worker 的设计非常纯粹和无状态（stateless），它本身不存储任何 API Key 或配置。所有的配置都由前端在每次请求时动态提供。&lt;/p&gt;
&lt;h3&gt;如何使用这个 Worker？&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;部署&lt;/strong&gt;：将 &lt;code&gt;ai-worker/index.ts&lt;/code&gt; 的代码部署到你自己的 Cloudflare Workers 服务上，你会得到一个唯一的 Worker URL，例如 &lt;code&gt;https://my-ai-proxy.workers.dev&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;配置请求头&lt;/strong&gt;：当你的前端应用调用这个 Worker 时，必须在请求头（Headers）中包含两个关键信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Authorization&lt;/code&gt;: 你的 AI 服务提供商的 API Key。格式为 &lt;code&gt;Bearer &amp;lt;YOUR_API_KEY&amp;gt;&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X-API-URL&lt;/code&gt;: 你想要调用的目标 AI API 的完整地址。例如 &lt;code&gt;https://api.openai.com/v1/chat/completions&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这个 Worker 会原封不动地将你的请求体（包含模型名称、消息历史等）和 &lt;code&gt;Authorization&lt;/code&gt; 头转发给 &lt;code&gt;X-API-URL&lt;/code&gt; 指定的地址，并将收到的响应以流式（Streaming）的方式传回给前端。&lt;/p&gt;
&lt;h2&gt;前端：功能强大的 Svelte 聊天组件&lt;/h2&gt;
&lt;p&gt;前端部分是一个独立的 Svelte 组件 (&lt;code&gt;src/components/Chat.svelte&lt;/code&gt;)，它负责渲染整个聊天界面和处理用户交互。&lt;/p&gt;
&lt;p&gt;&amp;lt;!-- 这里可以放一张最终效果图 --&amp;gt;&lt;/p&gt;
&lt;p&gt;它包含了很多实用的功能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;配置面板&lt;/strong&gt;：一个可展开的调试/配置面板，用于设置 Worker 地址和 AI 参数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;本地存储&lt;/strong&gt;：所有配置都会自动保存在浏览器的 &lt;code&gt;localStorage&lt;/code&gt; 中，用户只需配置一次。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Markdown &amp;amp; 代码高亮&lt;/strong&gt;：AI 的回复会被解析为 Markdown，代码块也能正确高亮。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;图片粘贴&lt;/strong&gt;：支持直接从剪贴板粘贴图片并发送给支持多模态输入的模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;流式响应&lt;/strong&gt;：逐字显示 AI 的回复，带来流畅的打字机效果。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;如何使用这个组件？&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建页面&lt;/strong&gt;：首先，你需要一个页面来承载这个聊天组件。在 Astro 项目中，可以创建一个 &lt;code&gt;src/pages/chat.astro&lt;/code&gt; 文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
import Layout from &apos;@/layouts/Layout.astro&apos;;
import Chat from &apos;@/components/Chat.svelte&apos;;
---
&amp;lt;Layout seo={{ title: &apos;AI Chat&apos; }}&amp;gt;
  &amp;lt;div class=&quot;chat-container-wrapper&quot;&amp;gt;
    &amp;lt;Chat client:load /&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/Layout&amp;gt;
&amp;lt;style is:global&amp;gt;
  /* 确保聊天界面占满整个屏幕 */
  html, body, #__astro, .main-content {
    height: 100%;
    padding: 0 !important;
    max-width: 100% !important;
  }
  .chat-container-wrapper {
    height: 100%;
    overflow: hidden;
  }
&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;安装依赖&lt;/strong&gt;：这个组件依赖 &lt;code&gt;marked&lt;/code&gt; 和 &lt;code&gt;dompurify&lt;/code&gt; 来处理和净化 AI 的 Markdown 回复。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pnpm install marked dompurify
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;配置和使用&lt;/strong&gt;：当用户第一次访问聊天页面时，界面会提示他们进行配置。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;点击右上角的 &lt;strong&gt;“显示调试”&lt;/strong&gt; 按钮，展开配置面板。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Worker URL&lt;/strong&gt;：填入上一步你部署好的 Cloudflare Worker 的地址。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API Key&lt;/strong&gt;：填入你的 AI 服务提供商的 API Key。这个 Key 只会存在你的浏览器本地，非常安全。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API Endpoint&lt;/strong&gt;：填入目标 API 地址。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Model&lt;/strong&gt;：指定要使用的模型名称，例如 &lt;code&gt;gpt-4o&lt;/code&gt; 或 &lt;code&gt;glm-4.5&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;System Prompt&lt;/strong&gt;：可选，可以设置一个系统提示来定义 AI 的角色和行为。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;完成配置后，就可以开始对话了。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;通过“Cloudflare Worker 代理 + Svelte 前端组件”这个组合，我成功地为网站添加了一个功能完善、高度可控且注重隐私的 AI 对话功能。它不仅解决了跨域调用的技术难题，还提供了远超第三方插件的灵活性和定制性。&lt;/p&gt;
&lt;h2&gt;文件内容&lt;/h2&gt;
&lt;p&gt;直接给你抄作业😡😋&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src/pages/chat.astro
---
import Layout from &apos;@/layouts/Layout.astro&apos;;
import Chat from &apos;@/components/Chat.svelte&apos;;

const seo = {
  title: &apos;AI Chat&apos;,
  description: &apos;An interactive chat interface powered by AI.&apos;,
};
---

&amp;lt;Layout {seo}&amp;gt;
  &amp;lt;div class=&quot;page-wrapper&quot;&amp;gt;
    &amp;lt;header class=&quot;page-header&quot;&amp;gt;
      &amp;lt;a href=&quot;https://www.497995.xyz&quot; class=&quot;home-link&quot;&amp;gt;
        &amp;amp;larr; 返回主页
      &amp;lt;/a&amp;gt;
    &amp;lt;/header&amp;gt;
    &amp;lt;div class=&quot;chat-container-wrapper&quot;&amp;gt;
      &amp;lt;Chat client:load /&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/Layout&amp;gt;
&amp;lt;style is:global&amp;gt;
  /* Ensure body and container are full height */
  html, body, #__astro {
    height: 100%;
  }
  /* Override layout padding for this page */
  .main-content {
    padding: 0 !important;
    max-width: 100% !important;
    height: 100%;
  }
  .page-wrapper {
    position: relative; /* Needed for the ::before pseudo-element */
    z-index: 0;
    display: flex;
    flex-direction: column;
    height: 100%;
    background-color: transparent;
  }
  .page-wrapper::before {
    content: &apos;&apos;;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-image: url(&apos;https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/197/197-bigskin-6.jpg&apos;);
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    opacity: 0;
    pointer-events: none;
    z-index: -1;
    transition: opacity 0.5s ease-in-out;
  }
  .page-wrapper.bg-loaded::before {
    opacity: 0.15;
  }
  .page-header {
    padding: 0.75rem 1.5rem;
    /* Make header transparent to see the background */
    background-color: rgba(255, 255, 255, 0.7);
    backdrop-filter: saturate(180%) blur(10px);
    -webkit-backdrop-filter: saturate(180%) blur(10px);
    border-bottom: 1px solid rgba(229, 231, 235, 0.5);
    flex-shrink: 0;
    position: relative; /* Ensure header is above the ::before pseudo-element */
    z-index: 1;
  }
  .home-link {
    text-decoration: none;
    color: #374151;
    font-weight: 500;
  }
  .home-link:hover {
    color: #3b82f6;
  }
  .chat-container-wrapper {
    flex-grow: 1;
    overflow: hidden;
    position: relative; /* Ensure chat content is above the ::before pseudo-element */
    z-index: 1;
  }
&amp;lt;/style&amp;gt;

&amp;lt;script&amp;gt;
  document.addEventListener(&apos;astro:page-load&apos;, () =&amp;gt; {
    const bgUrl = &apos;https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/197/197-bigskin-6.jpg&apos;;
    const pageWrapper = document.querySelector(&apos;.page-wrapper&apos;) as HTMLElement;

    if (pageWrapper) {
      const img = new Image();
      img.onload = () =&amp;gt; {
        pageWrapper.classList.add(&apos;bg-loaded&apos;);
      };
      img.src = bgUrl;
    }
  });
&amp;lt;/script&amp;gt;
```


（bgUrl替换成自己的背景）
index.js
````astro
export default {
  async fetch(request) {
    // Handle CORS preflight requests sent by browsers.
    if (request.method === &apos;OPTIONS&apos;) {
      return handleOptions(request);
    }

    if (request.method !== &apos;POST&apos;) {
      return new Response(JSON.stringify({ error: &apos;Method Not Allowed&apos; }), {
        status: 405,
        headers: corsHeaders(),
      });
    }

    // 1. Extract required headers from the client&apos;s request.
    const apiKey = request.headers.get(&apos;Authorization&apos;);
    const apiUrl = request.headers.get(&apos;X-API-URL&apos;);

    // 2. Validate that the required headers are present.
    if (!apiKey) {
      return new Response(JSON.stringify({ error: &apos;Request missing Authorization header&apos; }), {
        status: 400,
        headers: corsHeaders({ &apos;Content-Type&apos;: &apos;application/json&apos; }),
      });
    }

    if (!apiUrl) {
      return new Response(JSON.stringify({ error: &apos;Request missing X-API-URL header&apos; }), {
        status: 400,
        headers: corsHeaders({ &apos;Content-Type&apos;: &apos;application/json&apos; }),
      });
    }

    // 3. Forward the request to the target AI service.
    // The request body from the client is passed through directly.
    const proxyRequest = new Request(apiUrl, {
      method: &apos;POST&apos;,
      headers: {
        &apos;Content-Type&apos;: &apos;application/json&apos;,
        &apos;Authorization&apos;: apiKey,
      },
      body: request.body,
      // @ts-ignore
      duplex: &apos;half&apos;, // Necessary for streaming request bodies.
    });

    try {
      const response = await fetch(proxyRequest);

      // 4. Stream the response back to the client.
      // This handles both successful streaming responses and error responses from the target API.
      const { readable, writable } = new TransformStream();
      response.body?.pipeTo(writable);

      const responseHeaders = corsHeaders({
        &apos;Content-Type&apos;: response.headers.get(&apos;Content-Type&apos;) || &apos;text/event-stream&apos;,
        &apos;Cache-Control&apos;: &apos;no-cache&apos;,
        &apos;Connection&apos;: &apos;keep-alive&apos;,
      });

      return new Response(readable, {
        status: response.status,
        statusText: response.statusText,
        headers: responseHeaders,
      });

    } catch (error) {
      console.error(&apos;Failed to connect to the target API:&apos;, error);
      return new Response(JSON.stringify({ error: &apos;Failed to connect to the target API.&apos; }), {
        status: 502, // Bad Gateway
        headers: corsHeaders({ &apos;Content-Type&apos;: &apos;application/json&apos; }),
      });
    }
  },
};

// Utility to generate common CORS headers for responses.
const corsHeaders = (additionalHeaders = {}) =&amp;gt; {
  return new Headers({
    &apos;Access-Control-Allow-Origin&apos;: &apos;*&apos;, // Allow any origin to call this proxy
    &apos;Access-Control-Allow-Methods&apos;: &apos;POST, OPTIONS&apos;,
    &apos;Access-Control-Allow-Headers&apos;: &apos;Content-Type, Authorization, X-API-URL&apos;,
    ...additionalHeaders,
  });
};

// Handles CORS preflight (OPTIONS) requests.
function handleOptions(request) {
  const requestHeaders = request.headers;
  if (
    requestHeaders.get(&apos;Origin&apos;) !== null &amp;amp;&amp;amp;
    requestHeaders.get(&apos;Access-Control-Request-Method&apos;) !== null &amp;amp;&amp;amp;
    requestHeaders.get(&apos;Access-Control-Request-Headers&apos;) !== null
  ) {
    // Standard CORS preflight response.
    return new Response(null, {
      headers: {
        &apos;Access-Control-Allow-Origin&apos;: &apos;*&apos;,
        &apos;Access-Control-Allow-Methods&apos;: &apos;POST, OPTIONS&apos;,
        &apos;Access-Control-Allow-Headers&apos;: &apos;Content-Type, Authorization, X-API-URL&apos;,
        &apos;Access-Control-Max-Age&apos;: &apos;86400&apos;, // Cache preflight response for 24 hours
      },
    });
  } else {
    // Standard OPTIONS response.
    return new Response(null, {
      headers: {
        Allow: &apos;POST, OPTIONS&apos;,
      },
    });
  }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>个人博客的技术性 SEO 实践：标题、描述与 HTML 语义优化</title><link>https://www.497995.xyz/posts/seo-practice/</link><guid isPermaLink="true">https://www.497995.xyz/posts/seo-practice/</guid><description>针对个人博客的技术性 SEO 优化，包括调整网站标题、丰富页面元描述以及使用正确的 HTML 语义化标签（如 h1），以提升博客在搜索引擎中的可见性</description><pubDate>Fri, 01 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;搜索引擎优化（SEO）对于个人博客来说，意味着让分享的技术和见解能被更多志同道合的人发现。在提交 &lt;code&gt;5d819d4b980ade52073a0907a2dc993432b70881&lt;/code&gt; 中，博客进行了一系列技术性 SEO 调整，旨在让搜索引擎更好地理解和收录博客的内容。&lt;/p&gt;
&lt;h2&gt;优化实践&lt;/h2&gt;
&lt;p&gt;本次优化主要涵盖了三个方面：&lt;/p&gt;
&lt;h3&gt;1. 调整网站标题 (&lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;网站的全局标题是搜索引擎识别博客主题的首要信息。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;变更&lt;/strong&gt;:
在 &lt;code&gt;src/config.ts&lt;/code&gt; 文件中，将网站标题从 &lt;code&gt;&apos;或许是一只龙的博客&apos;&lt;/code&gt; 修改为 &lt;code&gt;&apos;Hxsyzl blog&apos;&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;理由&lt;/strong&gt;:
使用一个更简洁、统一的标识 (&lt;code&gt;Hxsyzl&lt;/code&gt;) 作为网站标题，有助于让搜索引擎和访客快速识别这是谁的博客。对于一个技术博客来说，一个稳定且易于记忆的标识符比一个较长的中文昵称更利于传播和索引。&lt;/p&gt;
&lt;h3&gt;2. 丰富页面元描述 (&lt;code&gt;meta description&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;元描述会作为摘要显示在搜索结果中，它就像一本书的简介，直接影响读者是否愿意“翻开”看看。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;变更&lt;/strong&gt;:
在文章 &lt;code&gt;src/content/posts/chat.md&lt;/code&gt; 的 frontmatter 中，&lt;code&gt;description&lt;/code&gt; 字段被扩充，提供了更详细的信息。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;理由&lt;/strong&gt;:
一个内容详实、准确概括页面内容的描述，能够帮助潜在的读者在搜索结果中快速判断这篇文章是否是他们想要的，从而吸引到更精准的流量。&lt;/p&gt;
&lt;h3&gt;3. 强化 HTML 语义：使用 &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; 标签&lt;/h3&gt;
&lt;p&gt;在 HTML 中，使用正确的语义化标签是与搜索引擎进行高效沟通的基础。&lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; 标签告诉搜索引擎：“这是这个页面的主标题，是最重要的内容”。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;变更&lt;/strong&gt;:
在文章页面模板 &lt;code&gt;src/pages/posts/[...slug].astro&lt;/code&gt; 中，原先用于包裹文章标题的 &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; 标签被替换为了 &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; 标签。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 之前
&amp;lt;div class=&quot;...&quot;&amp;gt;{entry.data.title}&amp;lt;/div&amp;gt;

// 之后
&amp;lt;h1 class=&quot;...&quot;&amp;gt;{entry.data.title}&amp;lt;/h1&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;理由&lt;/strong&gt;:
将 &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; 更换为 &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;，是向搜索引擎明确地标示出页面的核心主题。这能帮助搜索引擎准确地理解文章结构，是页面级 SEO 中一个基础但至关重要的步骤。&lt;/p&gt;
&lt;h2&gt;结论&lt;/h2&gt;
&lt;p&gt;技术性 SEO 并不复杂。通过对网站标题、元描述和 HTML 结构这些基础元素进行简单的调整，就能显著改善个人博客对搜索引擎的友好度，让精心撰写的内容更容易被需要它的人找到。&lt;/p&gt;
</content:encoded></item><item><title>通过邮件混淆技术增强博客隐私</title><link>https://www.497995.xyz/posts/email-privacy/</link><guid isPermaLink="true">https://www.497995.xyz/posts/email-privacy/</guid><description>利用 rehype-email-protection 插件自动混淆电子邮件地址，保护免受垃圾邮件爬虫侵害的技术实现</description><pubDate>Fri, 01 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;在网页上直接暴露电子邮件地址，会使其极易受到垃圾邮件机器人的自动抓取。为了解决这一隐私和安全问题，可以采用邮件地址混淆技术。&lt;/p&gt;
&lt;p&gt;在提交 &lt;code&gt;0cc6194f35b3ff4ab53718fd98022b17ac522303&lt;/code&gt; 中，项目引入了 &lt;code&gt;rehype-email-protection&lt;/code&gt; 插件来应对此问题。&lt;/p&gt;
&lt;h2&gt;技术方案：&lt;code&gt;rehype-email-protection&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;rehype-email-protection&lt;/code&gt; 是一个 Rehype 插件，它能在网站内容处理流程中自动识别并混淆电子邮件地址。&lt;/p&gt;
&lt;h3&gt;配置实现&lt;/h3&gt;
&lt;p&gt;该功能通过在 &lt;code&gt;astro.config.mjs&lt;/code&gt; 文件中进行配置来启用。&lt;/p&gt;
&lt;p&gt;首先，导入插件模块：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import rehypeEmailProtection from &quot;./src/plugins/rehype-email-protection.mjs&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后，在 Astro 配置的 &lt;code&gt;rehypePlugins&lt;/code&gt; 数组中添加该插件，并指定 &lt;code&gt;base64&lt;/code&gt; 作为混淆方法。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;markdown: {
  rehypePlugins: [
    // ... 其他插件
    [rehypeEmailProtection, { method: &quot;base64&quot; }],
    // ... 其他插件
  ],
},
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;工作机制&lt;/h3&gt;
&lt;p&gt;配置生效后，内容中所有标准的电子邮件地址（如 &lt;code&gt;user@example.com&lt;/code&gt;）在网站构建过程中，都会被转换为 Base64 编码的字符串，并通过客户端 JavaScript 进行解码。&lt;/p&gt;
&lt;p&gt;对于普通用户，浏览器会执行脚本将编码还原为可交互的 &lt;code&gt;mailto:&lt;/code&gt; 链接，功能体验不变。而对于无法执行 JavaScript 的网络爬虫，它们只能获取到编码后的无意义字符串，从而达到了保护电子邮件地址不被轻易收集的目的。&lt;/p&gt;
&lt;h2&gt;结论&lt;/h2&gt;
&lt;p&gt;集成 &lt;code&gt;rehype-email-protection&lt;/code&gt; 插件是一种简单而有效的隐私增强手段。它以极低的配置成本，显著降低了因在公开网页上暴露电子邮件地址而导致的安全风险，是静态网站开发中值得推荐的一个实践。&lt;/p&gt;
</content:encoded></item><item><title>在 Astro 中实现全自动响应式图像：结合 Rehype 与 astro:assets</title><link>https://www.497995.xyz/posts/responsive-images/</link><guid isPermaLink="true">https://www.497995.xyz/posts/responsive-images/</guid><description>在 Astro 中实现全自动响应式图像处理的优雅方案。通过编写一个自定义 Rehype 插件，在构建时拦截 Markdown 图片，并利用 astro:assets 的强大功能将其替换为高性能的响应式组件</description><pubDate>Fri, 01 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;在 &lt;code&gt;70c1a207a437b3a7ca74faf16563f7a8abf2dcfe&lt;/code&gt; 这次提交中，博客的图像处理能力得到了质的飞跃。其核心目标是：在不改变 Markdown 写作习惯（即仍然使用 &lt;code&gt;![alt](src)&lt;/code&gt; 语法）的前提下，自动将标准图片转换为功能强大的响应式图像。&lt;/p&gt;
&lt;p&gt;这解决了传统 &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; 标签的几个痛点：无法根据设备尺寸提供不同大小的图片、无法自动转换为 WebP 等现代格式、以及需要手动添加懒加载等。&lt;/p&gt;
&lt;h2&gt;实现方案&lt;/h2&gt;
&lt;p&gt;该方案巧妙地结合了 Astro 的构建时转换能力和组件化能力，主要分为两步：&lt;/p&gt;
&lt;h3&gt;1. 使用 Rehype 插件拦截图像&lt;/h3&gt;
&lt;p&gt;第一步是在内容处理流程中，找到所有的 &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; 标签并将其替换为一个自定义的 Astro 组件。这通过一个自定义的 Rehype 插件 &lt;code&gt;rehype-figure.mjs&lt;/code&gt; 来实现。&lt;/p&gt;
&lt;p&gt;它的工作流程如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;遍历 AST&lt;/strong&gt;：插件遍历由 Markdown 生成的 HTML 抽象语法树（AST）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定位 &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;&lt;/strong&gt;：找到所有标签名为 &lt;code&gt;img&lt;/code&gt; 的节点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;创建新节点&lt;/strong&gt;：提取出原 &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; 标签的 &lt;code&gt;src&lt;/code&gt; 和 &lt;code&gt;alt&lt;/code&gt; 属性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;替换节点&lt;/strong&gt;：使用这些属性创建一个新的 &lt;code&gt;&amp;lt;markdown-image&amp;gt;&lt;/code&gt; 组件节点，并用它替换掉原来的 &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; 节点。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;// src/plugins/rehype-figure.mjs
import { visit } from &apos;unist-util-visit&apos;;
import { h } from &apos;hastscript&apos;;

export default function rehypeFigure() {
  return (tree) =&amp;gt; {
    visit(tree, &apos;element&apos;, (node, index, parent) =&amp;gt; {
      if (node.tagName !== &apos;img&apos;) return;

      const src = node.properties?.src;
      const alt = node.properties?.alt;
      if (!src) return;

      // 创建 &amp;lt;markdown-image&amp;gt; 组件节点
      const markdownImageNode = h(&apos;markdown-image&apos;, { src, alt: alt || &apos;&apos; });

      // 替换
      if (parent &amp;amp;&amp;amp; typeof index === &apos;number&apos;) {
        parent.children[index] = markdownImageNode;
      }
    });
  };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 创建强大的响应式图像组件&lt;/h3&gt;
&lt;p&gt;第二步是实现 &lt;code&gt;&amp;lt;markdown-image&amp;gt;&lt;/code&gt; 标签对应的 Astro 组件——&lt;code&gt;MarkdownImage.astro&lt;/code&gt;。这个组件是所有响应式魔法发生的地方，它利用了 Astro 内置的 &lt;code&gt;astro:assets&lt;/code&gt; 功能。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
// src/components/misc/MarkdownImage.astro
import { Image } from &quot;astro:assets&quot;;

interface Props { src: string; alt: string; }
const { src, alt } = Astro.props;
const isRemote = src.startsWith(&quot;http&quot;);
---

&amp;lt;figure class=&quot;flex flex-col items-center&quot;&amp;gt;
  {
    isRemote ? (
      &amp;lt;img {src} {alt} class=&quot;rounded-lg&quot; /&amp;gt;
    ) : (
      &amp;lt;Image
        src={/* ...动态导入本地图片的逻辑... */}
        {alt}
        class=&quot;rounded-lg&quot;
        widths={[400, 800, 1200]}
        sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
        format=&quot;webp&quot;
      /&amp;gt;
    )
  }
  {alt &amp;amp;&amp;amp; &amp;lt;figcaption class=&quot;mt-2 text-center text-sm&quot;&amp;gt;{alt}&amp;lt;/figcaption&amp;gt;}
&amp;lt;/figure&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个组件的核心逻辑是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;区分来源&lt;/strong&gt;：判断图片是远程链接还是本地文件。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;处理本地图片&lt;/strong&gt;：对于本地图片，使用 Astro 的 &lt;code&gt;&amp;lt;Image&amp;gt;&lt;/code&gt; 组件。
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;widths&lt;/code&gt; 和 &lt;code&gt;sizes&lt;/code&gt; 属性让 Astro 自动生成不同尺寸的图片，并告诉浏览器如何根据屏幕大小选择最合适的版本。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;format=&quot;webp&quot;&lt;/code&gt; 会自动将图片转换为高效的 WebP 格式。&lt;/li&gt;
&lt;li&gt;Astro 的 &lt;code&gt;&amp;lt;Image&amp;gt;&lt;/code&gt; 组件还内置了懒加载 (&lt;code&gt;loading=&quot;lazy&quot;&lt;/code&gt;) 和其他性能优化。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;处理远程图片&lt;/strong&gt;：对于远程图片，则回退到使用标准的 &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; 标签，不进行优化处理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;语义化包裹&lt;/strong&gt;：最后，使用 &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt; 和 &lt;code&gt;&amp;lt;figcaption&amp;gt;&lt;/code&gt; 为图片提供正确的 HTML 语义。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;结论&lt;/h2&gt;
&lt;p&gt;通过“Rehype 插件拦截替换” + “Astro Assets 组件实现优化”的组合拳，博客实现了一套全自动、高性能且对内容创作者完全透明的响应式图像解决方案。这不仅极大地提升了网站的加载速度和用户体验，也展示了 Astro 在内容处理和性能优化方面的强大灵活性。&lt;/p&gt;
</content:encoded></item><item><title>Twikoo 评论系统升级：性能优化与样式深度定制</title><link>https://www.497995.xyz/posts/twikoo-optimize/</link><guid isPermaLink="true">https://www.497995.xyz/posts/twikoo-optimize/</guid><description>对 Twikoo 评论组件的一次重要升级，包括通过事件驱动实现延迟加载以优化性能，以及通过自定义 CSS 实现与博客主题的深度样式集成</description><pubDate>Fri, 01 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;在 &lt;code&gt;6fab5477f745f4858c14a5da83ca1b451fbd50ea&lt;/code&gt; 这次提交中，博客的 Twikoo 评论系统得到了一次全面的功能与视觉升级。本次更新主要聚焦于两个核心目标：提升页面加载性能，以及让评论区的外观与网站的整体设计风格无缝对接。&lt;/p&gt;
&lt;h2&gt;性能优化：事件驱动的延迟加载&lt;/h2&gt;
&lt;p&gt;旧的实现方式会在每个包含评论区的页面加载时，立即下载并执行 Twikoo 的主脚本。这虽然能保证评论区立即可用，但对于那些只阅读文章而不参与评论的用户来说，却造成了不必要的带宽和性能开销。&lt;/p&gt;
&lt;p&gt;为了解决这个问题，新的实现采用了&lt;strong&gt;事件驱动的延迟加载&lt;/strong&gt;机制。&lt;/p&gt;
&lt;h4&gt;1. 更新 &lt;code&gt;Twikoo.astro&lt;/code&gt; 组件&lt;/h4&gt;
&lt;p&gt;评论组件本身被修改为监听一个自定义事件 &lt;code&gt;loadComment&lt;/code&gt;。只有当这个事件被触发时，组件才会动态创建 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 标签来加载 Twikoo 的资源。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// src/components/Twikoo.astro

// ...
&amp;lt;script define:vars={{ config }}&amp;gt;
  function loadTwikoo() {
    const script = document.createElement(&quot;script&quot;);
    script.src = &quot;https://cdn.staticfile.org/twikoo/1.6.32/twikoo.all.min.js&quot;;
    script.defer = true;
    script.onload = () =&amp;gt; {
      twikoo.init(config);
    };
    document.body.appendChild(script);
  }
  // 关键：监听自定义事件，且只执行一次
  document.addEventListener(&quot;loadComment&quot;, loadTwikoo, { once: true });
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. 在布局中触发事件&lt;/h4&gt;
&lt;p&gt;事件的触发逻辑被放置在全局布局文件 &lt;code&gt;src/layouts/Layout.astro&lt;/code&gt; 中。通过一个 &lt;code&gt;initCommentComponent&lt;/code&gt; 函数来创建并分发 &lt;code&gt;loadComment&lt;/code&gt; 事件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// src/layouts/Layout.astro

function initCommentComponent() {
  const event = new Event(&quot;loadComment&quot;);
  document.dispatchEvent(event);
}

function init() {
  // ... 其他初始化函数
  initCommentComponent();
}

// 确保在使用 Swup 进行页面切换后，评论区也能被正确加载
window.swup.hooks.on(&quot;content:replace&quot;, () =&amp;gt; {
  initCustomScrollbar();
  initCommentComponent();
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过这种方式，评论区的加载被推迟到必要时刻，有效地优化了页面的初始加载性能。&lt;/p&gt;
&lt;h2&gt;样式深度定制&lt;/h2&gt;
&lt;p&gt;除了性能优化，本次更新还通过一个全新的样式文件 &lt;code&gt;src/styles/twikoo.css&lt;/code&gt; 对评论区的外观进行了深度定制。&lt;/p&gt;
&lt;p&gt;该文件包含了一系列针对 Twikoo 组件元素的 CSS 规则，旨在：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;统一颜色方案&lt;/strong&gt;：确保评论区的文本、背景、按钮等颜色与博客的浅色及深色模式主题保持一致。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;统一设计语言&lt;/strong&gt;：调整了输入框、按钮的圆角、边框和间距，使其符合网站的整体视觉风格。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;提升细节体验&lt;/strong&gt;：对头像、链接、代码块等元素的样式进行了微调，提供了更和谐的视觉感受。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如，下面的 CSS 规则统一了评论卡片的样式：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* src/styles/twikoo.css */

.tk-comment {
  @apply border-[1px] border-[rgba(144,147,153,0.31)] p-4 rounded-2xl hover:shadow-md transition-all;        
  .tk-action-icon svg {
    @apply fill-[var(--primary)];
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;结论&lt;/h2&gt;
&lt;p&gt;这次对 Twikoo 评论系统的升级，是一次典型的在第三方集成中寻求性能与视觉平衡的实践。通过延迟加载优化了用户访问速度，通过自定义样式提升了品牌一致性和视觉体验，最终为读者提供了一个更快、更美观的交流环境。&lt;/p&gt;
</content:encoded></item><item><title>我的世界【RLCraft】整合包开服联机教程</title><link>https://www.497995.xyz/posts/vps/</link><guid isPermaLink="true">https://www.497995.xyz/posts/vps/</guid><description>Minecraft【RLCraft】整合包服务端搭建教程，搭建方式：雨云RCA云应用一键部署</description><pubDate>Wed, 23 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;📦 什么是整合包？&lt;/h2&gt;
&lt;p&gt;Minecraft 的整合包是一种包含了多个模组（mod）和配置文件（config）的游戏版本，可以让玩家体验不同的游戏风格和内容。整合包通常由社区的玩家或团队制作和发布，有些也是官方或合作方推出的。整合包的种类很多，有科技类、魔法类、冒险类、生存类等等，每种整合包都有自己的特色和玩法。&lt;/p&gt;
&lt;h2&gt;🎮《RLCraft》整合包简介&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;RLCraft&lt;/strong&gt; 整合包，全称为 &lt;strong&gt;Real Life or Realism Craft&lt;/strong&gt; ，是一款基于《Minecraft》打造的高沉浸感生存冒险模组包。它以“现实生活/现实主义”为核心设计理念，通过对数十款模组的精心筛选与深度调整，搭配自定义合成表、机制重构等设计，将“硬核生存+开放冒险+RPG成长”的体验熔于一炉，重新定义MC的游玩逻辑。&lt;/p&gt;
&lt;p&gt;在 RLCraft 的世界里，你能体验到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;真实感拉满的生存挑战&lt;/strong&gt;：饥饿、口渴、体温等维度的生存压力，让资源规划与环境互动成为生存必修课；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高自由度的开放冒险&lt;/strong&gt;：遗迹暗藏机关、地牢盘踞Boss、世界随机生成奇遇，探索过程充满未知与惊喜；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RPG式的成长脉络&lt;/strong&gt;：通过战斗、采集、制作获取经验，解锁技能树，让角色养成与世界探索深度绑定；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多元玩法的自由选择&lt;/strong&gt;：既可以扎进深渊遗迹挑战怪物、挖掘秘宝，也能回归“慢节奏”——规划基地布局、研究复杂合成链，甚至搭建幻想风格的建筑。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;从“挣扎求生”到“掌控世界”，RLCraft 用模组的巧妙融合，让“在MC里体验现实生活的多样可能”成为触手可及的游戏体验。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://fastr2.497995.xyz/fuwari/image/d791f9fa-6997-4b19-81c1-d682e5ac810c.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;官方下载地址&lt;/strong&gt;：&lt;a href=&quot;https://www.curseforge.com/minecraft/modpacks/rlcraft&quot;&gt;CurseForge - RLCraft&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;📥 下载整合包&lt;/h2&gt;
&lt;p&gt;首先需要下载好《RLCraft》的服务端和客户端。您可以从官方 CurseForge 下载，也可以使用我下方提供的已集成汉化补丁的版本。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我提供的服务端内置了 Windows 版的 JDK8，在 Windows 服务器上双击 &lt;code&gt;run.bat&lt;/code&gt; 即可直接运行。&lt;/li&gt;
&lt;li&gt;客户端则包含了 JDK8 和 PCL2 启动器，下载后解压即可开始游戏。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;RLCraft 汉化版客户端和服务端下载链接：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;百度网盘&lt;/strong&gt;: &lt;a href=&quot;https://pan.baidu.com/s/1noDIKen6_ML6AkhnW9kLRA?pwd=yiu9&quot;&gt;https://pan.baidu.com/s/1noDIKen6_ML6AkhnW9kLRA?pwd=yiu9&lt;/a&gt; (提取码: &lt;code&gt;yiu9&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;123云盘 (免登陆高速下载)&lt;/strong&gt;: &lt;a href=&quot;https://www.123684.com/s/2Y9Djv-fIVvH&quot;&gt;https://www.123684.com/s/2Y9Djv-fIVvH&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;📝 &lt;strong&gt;注意&lt;/strong&gt;：服务端压缩包文件名为 &lt;code&gt;RLCraft_Server_2.9.3.zip&lt;/code&gt;，客户端压缩包文件名为 &lt;code&gt;RLCraft_2.9.3_Client.zip&lt;/code&gt;。（文件取自网络）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;🚀 云应用一键部署&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;✨ &lt;strong&gt;福利&lt;/strong&gt;：雨云云应用目前新用户可免费试用15天（免费的总资源限制为8核8G），也就是可以免费开服15天！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;☁️ 云应用简介&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;云应用（RCA，Rain Cloud Apps）&lt;/strong&gt; 是雨云基于 Kubernetes 开发的容器应用平台，为用户开发、部署和使用容器应用提供了全新的平台，产品经过精心设计，具有高可用、高灵活性、易用的特点。 云应用内置提供App、网站、数据库三大板块，并且提供内置的应用商店，首批上架数百款App，并且适配1Panel等第三方商店，让您可以在不买服务器的情况下快速部署包括Alist、Cloudreve等数百种热门应用，对应用的更新、文件管理、设置等方便快捷，一键生效。&lt;/p&gt;
&lt;p&gt;简单来说，它就是一个&lt;strong&gt;按小时计费&lt;/strong&gt;、可弹性增减配置、随时删除项目的 Docker 容器出租/托管平台。&lt;/p&gt;
&lt;h3&gt;☸️ Kubernetes 简介&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Kubernetes（简称 K8s）&lt;/strong&gt; 是由谷歌开源、云原生计算基金会（CNCF）托管的容器编排平台，旨在解决容器化应用的部署、管理和扩展难题。作为云原生技术栈的核心，它通过自动化机制实现应用的高效运行，支持从单节点到跨多云环境的大规模集群管理。&lt;/p&gt;
&lt;p&gt;其核心能力包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自动化部署与滚动更新&lt;/li&gt;
&lt;li&gt;弹性伸缩&lt;/li&gt;
&lt;li&gt;服务发现与负载均衡&lt;/li&gt;
&lt;li&gt;故障自愈机制&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;凭借模块化架构和开放生态，Kubernetes 成为微服务、CI/CD、边缘计算等场景的首选方案，助力企业实现应用的快速迭代与高可用性。&lt;/p&gt;
&lt;h3&gt;🌧️ 雨云简介&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;雨云&lt;/strong&gt; 成立于2018年，是具有自主知识产权的国产云计算服务提供商。 雨云为广大用户提供简单易用、便宜实惠、可信赖的云产品。主营包括云服务器、裸金属服务器、虚拟主机、游戏云、对象存储、云应用、CDN内容分发等广受好评的云服务产品。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;持有国家工信部颁发的《增值电信业务经营许可证》ISP证、IDC证、CDN证。&lt;/li&gt;
&lt;li&gt;支持7天内无理由退款（每个账号限3次）。&lt;/li&gt;
&lt;li&gt;云服务器/游戏云产品可1元试用一天。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;优惠地址：&lt;a href=&quot;https://www.rainyun.com/NTY0MDUy_?s=blog&quot;&gt;https://www.rainyun.com/NTY0MDUy_?s=blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;优惠码：&lt;code&gt;NTY0MDUy&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;使用优惠码注册后绑定微信可获得5折优惠券！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;🛠️ 创建项目 &amp;amp; 一键开服&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;注册雨云账号后，在控制台点击 &lt;strong&gt;云产品 -&amp;gt; 云应用&lt;/strong&gt;。
&lt;img src=&quot;https://fastr2.497995.xyz/fuwari/image/7c7d9527-8f1c-4f5c-99d5-28a9a9806ee9.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;点击 &lt;strong&gt;我的项目 -&amp;gt; 创建&lt;/strong&gt;。
&lt;img src=&quot;https://fastr2.497995.xyz/fuwari/image/03ef54d6-1b14-43dd-b39f-d04e409b222d.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;项目名称&lt;/strong&gt;自己定一个，&lt;strong&gt;磁盘大小&lt;/strong&gt; 3GB 基本够用（不够可随时扩容），然后点击 &lt;strong&gt;创建项目&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;访问此链接直接跳转到 RLCraft 服务端应用的安装页面：&lt;a href=&quot;https://app.rainyun.com/apps/rca/store/6674/zeruns_?s=blog&quot;&gt;点击这里&lt;/a&gt;，或在应用商店中搜索并点击 &lt;strong&gt;立即安装&lt;/strong&gt;。
&lt;img src=&quot;https://fastr2.497995.xyz/fuwari/image/c4e881d9-3e91-487e-872e-c249256e1d8f.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;资源配置&lt;/strong&gt;建议选 &lt;code&gt;2核4G&lt;/code&gt;，如果10人以上同时在线玩建议选 &lt;code&gt;4核8G&lt;/code&gt;。一般选 &lt;strong&gt;使用共享IP&lt;/strong&gt; 即可。服务端默认端口是 &lt;code&gt;25565&lt;/code&gt;，但共享IP的这个端口可能已被占用，可以随便输入一个端口（或使用随机生成的）。如果你购买了独立IP，则可以直接使用 &lt;code&gt;25565&lt;/code&gt;。最后点击 &lt;strong&gt;安装应用&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在项目管理页面的 &lt;strong&gt;应用管理&lt;/strong&gt; 中可以看到刚安装的应用。点击卡片进入管理页面。如果显示 &lt;strong&gt;运行中&lt;/strong&gt;，表示服务端安装已完成。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;点击 &lt;strong&gt;日志&lt;/strong&gt;，选择 &lt;strong&gt;安装时容器&lt;/strong&gt;，可以查看安装过程的日志。
&lt;img src=&quot;https://fastr2.497995.xyz/fuwari/image/e16c6a10-4121-43da-8198-efe3aae6905b.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;切换到 &lt;strong&gt;运行时容器&lt;/strong&gt; 可以看到服务端运行日志。如果日志基本不再滚动，表示服务端已启动完成，可以进入游戏了。
&lt;img src=&quot;https://fastr2.497995.xyz/fuwari/image/69e35ed3-a68f-4d4a-8bc8-d238a881e360.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;strong&gt;应用管理&lt;/strong&gt; 页面点击端口号即可复制服务器的 &lt;strong&gt;IP和端口&lt;/strong&gt;。
&lt;img src=&quot;https://fastr2.497995.xyz/fuwari/image/aa72a937-9195-4221-8a0b-234b2e2ad493.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;🎉 进入游戏&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;打开整合包客户端（可从上方的下载链接获取）。&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;多人游戏 -&amp;gt; 添加服务器&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;输入你服务器的 &lt;strong&gt;IP地址和端口&lt;/strong&gt;，例如 &lt;code&gt;110.42.45.225:5956&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;完成&lt;/strong&gt;，然后 &lt;strong&gt;加入服务器&lt;/strong&gt; 即可开始你的 RLCraft 之旅！&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;提示&lt;/strong&gt;：如果你使用的是默认端口 &lt;code&gt;25565&lt;/code&gt;，则可以省略端口号，直接输入 IP 地址即可连接。&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Xiaomi HyperOS2.0.3.0.UGGCNXM 安卓14 R1 For Redmi Note 8 Pro发布</title><link>https://www.497995.xyz/posts/xiaomi/</link><guid isPermaLink="true">https://www.497995.xyz/posts/xiaomi/</guid><description>Xiaomi HyperOS2.0.3.0.UGGCNXM 安卓14 R1 For Redmi Note 8 Pro的移植包发布</description><pubDate>Sat, 15 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;[稳定版]Xiaomi HyperOS2.0.3.0.UGGCNXM 安卓14 R1 For Redmi Note 8 Pro发布&lt;/p&gt;
&lt;p&gt;基于Redmi K60E移植&lt;/p&gt;
&lt;p&gt;发布时间：20250208&lt;/p&gt;
&lt;p&gt;更新内容&lt;/p&gt;
&lt;p&gt;[内核]切换到kernelSU Next分支&lt;/p&gt;
&lt;p&gt;[系统]优化系统稳定性&lt;/p&gt;
&lt;p&gt;特别说明&lt;/p&gt;
&lt;p&gt;○本ROM需要扩容system分区，请按照要求的教程进行刷入，教程在酷安（wuxin）帖子里面&lt;/p&gt;
&lt;p&gt;○在上一个版本的(OS1.0.23)，可以直接更新&lt;/p&gt;
&lt;p&gt;○不会刷的，第一次刷的，可以参考第一条的后半段教程&lt;/p&gt;
&lt;p&gt;○本ROM刷机包大于4GB，请以各种方法把ROM传到手机（adb push或者搞机助手都可以）&lt;/p&gt;
&lt;p&gt;○本ROM自带ksu next，需要使用root和模块的请自己安装即可使用(与ROM同个目录)&lt;/p&gt;
&lt;p&gt;○需要转换格式才可以正常开机（升级不需要）&lt;/p&gt;
&lt;p&gt;如何转换格式？&lt;/p&gt;
&lt;p&gt;1.刷完刷机包之后，正常流程格式化data分区，这时不要重启系统，直接返回，选择高级清除勾选&lt;/p&gt;
&lt;p&gt;data，点下方的更改/修改文件系统，选择右下角的更改文件系统，选择F2FS即可重启系统&lt;/p&gt;
&lt;p&gt;注: 如果不小心格式化了，就得再转一次&lt;/p&gt;
&lt;p&gt;○如果遇到相册日历应用出问题，请覆盖安装该应用即可&lt;/p&gt;
&lt;p&gt;○如需使用SUS-FS，请安装模块即可使用(与ROM同目录)&lt;/p&gt;
&lt;p&gt;注意：当前susfs存在不稳定性，如遇到模块使用异常，请及时关闭susfs&lt;/p&gt;
&lt;p&gt;○如果NFC不能用，重启系统即可&lt;/p&gt;
&lt;p&gt;○Bug与1.0一致&lt;/p&gt;
</content:encoded></item><item><title>几分钟，让Deepseek接入QQ！</title><link>https://www.497995.xyz/posts/dpintoqq/</link><guid isPermaLink="true">https://www.497995.xyz/posts/dpintoqq/</guid><description>通过 Koishi 和 ChatLuna 插件，将强大的 DeepSeek AI 模型接入你的 QQ 机器人，实现智能聊天和更多扩展功能。</description><pubDate>Tue, 04 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;介绍&lt;a href=&quot;https://chatluna.chat/guide/introduction.html#%E4%BB%8B%E7%BB%8D&quot;&gt;​&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ChatLunaLab/chatluna&quot;&gt;ChatLuna&lt;/a&gt; 是一款强大的语言模型聊天服务插件，基于 &lt;a href=&quot;https://github.com/langchain-ai/langchainjs&quot;&gt;LangChain&lt;/a&gt; 开发，目前作为 &lt;a href=&quot;https://koishi.chat/zh-CN/&quot;&gt;Koishi&lt;/a&gt; 上的插件存在。ChatLuna 支持与多种主流大语言模型进行交互，如 OpenAI、Google Gemini 和 Claude 等。&lt;/p&gt;
&lt;p&gt;ChatLuna 不仅为用户提供了模型聊天功能，还为其他 Koishi 插件开发者提供了便捷的 &lt;a href=&quot;https://js.langchain.com/docs/concepts/#chat-models&quot;&gt;LangChain Model&lt;/a&gt; 接口，方便他们与大语言模型进行交互和扩展开发&lt;/p&gt;
&lt;h2&gt;安装插件&lt;/h2&gt;
&lt;p&gt;在使用 ChatLuna 之前，你需要安装 Koishi。&lt;/p&gt;
&lt;p&gt;按照 &lt;a href=&quot;https://koishi.chat/zh-CN/&quot;&gt;Koishi 官方文档&lt;/a&gt; 来安装 Koishi。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;社区成员为 Windows 和 Linux 提供了一键安装脚本，该脚本可以一键自动安装 Koishi 以及 ChatLuna。
项目地址：https://github.com/hxsyzl/chatluna-install-auto&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;数据库服务&lt;/h4&gt;
&lt;p&gt;ChatLuna 需要 &lt;code&gt;database&lt;/code&gt; 服务，用于存储会话信息等持久化数据。&lt;/p&gt;
&lt;p&gt;我们推荐使用 &lt;code&gt;database-sqlite&lt;/code&gt;，它自带在大部分 Koishi 环境里，已被默认安装并启用。&lt;/p&gt;
&lt;p&gt;你也可以安装并配置其他在 Koishi 插件市场上的数据库插件，如 MySQL、MongoDB 等。&lt;/p&gt;
&lt;h4&gt;&lt;/h4&gt;
&lt;h4&gt;可选服务&lt;/h4&gt;
&lt;p&gt;这些服务是为了 ChatLuna 的某些功能而额外需要的服务。你可以根据需要选择安装。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;censor&lt;/code&gt; 服务：用于回复内容过滤。注意，有的插件不审核文本信息，请注意识别。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vits&lt;/code&gt; 服务：用于渲染模型回复，生成语音。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;DeepSeek&lt;a href=&quot;https://chatluna.chat/guide/configure-model-platform/deepseek.html#deepseek&quot;&gt;​&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;DeepSeek 是一家专注于通用人工智能底层模型与技术研究的公司，成立于2023年，由知名私募巨头幻方量化创立。公司致力于探索人工智能的本质，发布了多个开源大模型，包括 DeepSeek-LLM 通用大语言模型和 DeepSeek-Coder 代码大模型等。&lt;/p&gt;
&lt;p&gt;我们可以安装 &lt;code&gt;openai-deepseek-adapter&lt;/code&gt; 适配器来使用该公司提供的模型。&lt;/p&gt;
&lt;h2&gt;安装&lt;/h2&gt;
&lt;p&gt;前往插件市场，搜索 &lt;code&gt;chatluna-deepseek-adapter&lt;/code&gt;，安装即可。&lt;/p&gt;
&lt;p&gt;如果无法正常搜索到 &lt;code&gt;chatluna-deepseek-adapter&lt;/code&gt;，则说明官方插件源没有正常更新。
前往 market 插件设置为其他源即可：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://oss.497995.xyz/fuwari/image/937485e4-24fd-419b-be86-258bec9d328b.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;以下是推荐的一些插件源：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://koishi-registry.yumetsuki.moe/index.json&quot;&gt;https://koishi-registry.yumetsuki.moe/index.json&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;%5Bhttps://kp.itzdrli.cc&quot;&gt;https://kp.itzdrli.cc&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;配置&lt;/h2&gt;
&lt;p&gt;在配置之前，请先前往 &lt;a href=&quot;https://platform.deepseek.com/api_keys&quot;&gt;DeepSeek&lt;/a&gt; 获取 API key。&lt;/p&gt;
&lt;p&gt;获取到 API key 后，转到 &lt;code&gt;deepseek-adapter&lt;/code&gt; 的配置页面。
。
当然，你也可以更改你喜欢的其他平台名。&lt;/p&gt;
&lt;p&gt;完成后在请求设置里填入你的 API key 和 请求地址。请求地址应为 &lt;code&gt;https://api.deepseek.com/v1&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://oss.497995.xyz/fuwari/image/6c4bf5fc-81be-4d53-8ec9-52adc995c069.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;记得点击右上角的保存按钮。&lt;/p&gt;
&lt;h2&gt;使用&lt;/h2&gt;
&lt;p&gt;在适配器的配置页面，点击运行按钮，如无误，你应该看不到任何错误 log，那即可转到 ChatLuna 的主插件页面。&lt;/p&gt;
&lt;p&gt;在主插件页面，下划到 模版房间选项，查看 defaultModel 的选项里是否含有 DeepSeek 模型，如果有，则说明你已经成功地接入了 DeepSeek 平台&lt;/p&gt;
&lt;h2&gt;安装NapCat&lt;/h2&gt;
&lt;p&gt;NapCat有着众多启动方式，每种方式各有优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Shell 版本&lt;/strong&gt;：具有低内存、服务器部署简单的特点。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Framework 版本&lt;/strong&gt;：具有方便人机交互、便于窥屏的特点&lt;/p&gt;
&lt;p&gt;(在这里Framework不做介绍，感兴趣的可以自行搜搜)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Shell 启动/安装方式&lt;/h3&gt;
&lt;h2&gt;NapCat.Shell - Win手动启动教程&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;前往 &lt;a href=&quot;https://github.com/NapNeko/NapCatQQ/releases&quot;&gt;NapCatQQ 的 release 页面&lt;/a&gt; 下载NapCat.Shell.zip解压&lt;/li&gt;
&lt;li&gt;确保QQ版本安装且最新&lt;/li&gt;
&lt;li&gt;双击目录下launcher.bat即可启动 如果是win10 则使用launcher-win10.bat&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;lt;mark&amp;gt;如果需要快速登录 将 QQ 号传入参数即可&amp;lt;/mark&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;launcher.bat 123456
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;launcher-win10.bat 123456
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;NapCat.Win.一键版本&lt;/h2&gt;
&lt;p&gt;特殊说明: 一键版仅适用 &lt;code&gt;Windows.AMD64&lt;/code&gt; 无需安装QQ和NapCat 已内置&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;前往 &lt;a href=&quot;https://github.com/NapNeko/NapCatQQ/releases&quot;&gt;NapCatQQ 的 release 页面&lt;/a&gt; 下载无头绿色版本解压&lt;/li&gt;
&lt;li&gt;启动对应BAT即可&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;lt;mark&amp;gt;如果需要快速启动 新建Bat文件写入如下例子&amp;lt;/mark&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;NapCatWinBootMain.exe 10001
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;NapCat.Installer - Linux一键使用脚本(支持Ubuntu 20+/Debian 10+/Centos9)&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;curl -o napcat.sh https://nclatest.znin.net/NapNeko/NapCat-Installer/main/script/install.sh &amp;amp;&amp;amp; sudo bash napcat.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;curl -o napcat.sh https://nclatest.znin.net/NapNeko/NapCat-Installer/main/script/install.sh &amp;amp;&amp;amp; sudo bash napcat.sh --tui
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;curl -o napcat.sh https://nclatest.znin.net/NapNeko/NapCat-Installer/main/script/install.sh &amp;amp;&amp;amp; sudo bash napcat.sh --docker y --qq &quot;123456789&quot; --mode ws --proxy 1 --confirm
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;curl -o napcat.sh https://nclatest.znin.net/NapNeko/NapCat-Installer/main/script/install.sh &amp;amp;&amp;amp; sudo bash napcat.sh --docker n --cli n --proxy 0 --force
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;details&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;summary&amp;gt;命令选项(高级用法)&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;p&gt;0. --tui: 使用tui可视化交互安装&lt;/p&gt;
&lt;p&gt;1. --docker [y/n]: --docker y 为使用docker安装反之为shell安装&lt;/p&gt;
&lt;p&gt;2. --qq &quot;123456789&quot;: 传入docker安装时的QQ号&lt;/p&gt;
&lt;p&gt;3. --mode [ws|reverse_ws|reverse_http]: 传入docker安装时的运行模式&lt;/p&gt;
&lt;p&gt;4. --confirm: 传入docker安装时的是否确认执行安装&lt;/p&gt;
&lt;p&gt;5. --proxy [0|1|2|3|4|5|6]: 传入代理, 0为不使用代理, 1为使用内置的第一个,不支持自定义, docker安装可选0-7, shell安装可选0-5&lt;/p&gt;
&lt;p&gt;6. --cli [y/n]: shell安装时是否安装cli&lt;/p&gt;
&lt;p&gt;7. --force: 传入则执行shell强制重装&lt;/p&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;p&gt;仓库地址: &lt;a href=&quot;https://github.com/NapNeko/NapCat-Installer&quot;&gt;NapCat.installer&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;NapCat.Docker - Linux容器化部署&lt;/h2&gt;
&lt;p&gt;仓库地址: &lt;a href=&quot;https://github.com/NapNeko/NapCat-Docker&quot;&gt;NapCat.Docker&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;安装OneBot插件&lt;/h2&gt;
&lt;p&gt;前往Koishi的插件市场搜搜adapter-onebot下载安装即可&lt;/p&gt;
&lt;p&gt;在QQ号那一栏填写QQ号，最后开启即可&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://oss.497995.xyz/fuwari/image/557fbd70-1373-4540-ac78-c0c0e35b6db9.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;通过 WebUI 配置OneBot服务（NapCat)&lt;/h2&gt;
&lt;p&gt;如果你已经启动了 NapCat，并且有多于 1 个开放端口，则可以通过 WebUI 进行配置。&lt;/p&gt;
&lt;p&gt;默认地址为 &lt;code&gt;0.0.0.0&lt;/code&gt;，即监听所有地址。当配置了不可用的地址时 WebUI 将被禁用。&lt;/p&gt;
&lt;p&gt;默认端口为 &lt;code&gt;6099&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;当端口被设置为 &lt;code&gt;0&lt;/code&gt; 时将禁用 WebUI。&lt;/p&gt;
&lt;p&gt;当端口被占用时，会自动对端口 +1，直到找到可用端口（最多尝试100次，失败则会禁用 WebUI），端口号会在启动日志中显示。&lt;/p&gt;
&lt;p&gt;启动后可在启动日志中看到形如 &lt;code&gt;[WebUi] WebUi Local Panel Url: http://127.0.0.1:6099/webui?token=xxxx&lt;/code&gt; 的token信息。&lt;/p&gt;
&lt;p&gt;也可打开 &lt;code&gt;webui.json&lt;/code&gt; 文件，在其中找到token&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{

    &quot;host&quot;: &quot;0.0.0.0&quot;, // WebUI 监听地址

    &quot;port&quot;: 6099, // WebUI 端口

    &quot;token&quot;: &quot;xxxx&quot;, //登录密钥，默认是自动生成的随机登录密码

    &quot;loginRate&quot;: 3, //每分钟登录次数限制

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;访问 &lt;code&gt;http://ip:port/webui/&lt;/code&gt;，然后进行以下操作：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;进入 QQ 登录，点击 &lt;code&gt;QRCode&lt;/code&gt; 进行二维码登录。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;登录成功后，即可进入网络配置。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;配置完成后，点击保存，重启即可生效。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;最后你的Koishi右下角会变成这样&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://oss.497995.xyz/fuwari/image/754bb8d4-05f6-4965-8dc9-40a9e69b8170.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;去QQ找你的机器人对话就好了&lt;/p&gt;
&lt;p&gt;有疑问可以进入282381753&lt;/p&gt;
&lt;p&gt;插头露娜（chatluna）的官方交流群&lt;/p&gt;
</content:encoded></item><item><title>不畏黑砖-MTK解救黑砖完整教程</title><link>https://www.497995.xyz/posts/fixspflash/</link><guid isPermaLink="true">https://www.497995.xyz/posts/fixspflash/</guid><description>使用 SP Flash Tool 和 MTK 免授权工具，为变砖的联发科（MTK）设备刷入官方固件，从而实现救砖修复。</description><pubDate>Wed, 22 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;前言&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;该教程仅支持发布于2021年5月以及之前的SOC（也就是天坤920之前的CPU）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;以红米note8Pro为例，其他mtk机型可以参考参考&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;系统建议使用win10可避免一些问题&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果您的系统已经扩容了或修改了分区表。请在最后一步刷机的时候把仅下载切换至固件升级即可正常刷机（红米Notre8Pro测试通过，不会掉IMEI和基带）&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;准备工作&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;一部已经黑砖不开机的手机&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一根数据线和一台正常的电脑（网吧不建议)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一双手和一个正常的脑子&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一个良好的网络环境&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;需要的文件&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;MTK驱动压缩包&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;VCOM驱动压缩包&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;libusb-win32安装程序&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;AuthBypassTool v11（MTK Client Tool也可以，仅支持win10）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;flashtool,压缩包&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MIUI完整线刷包（下载地址：XiaomiROM.com）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/5b4170e329d5c31f19bf80a1896d141bd95ed42c.Dp7NwcTY_Z6jFVu.webp&quot; alt=&quot;640.webp&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;说明：以上资源均可在下载站找到并下载，路径：首页→通用手机刷机资源→电脑工具→联发科救黑砖全套&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教程开始&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;安装MTK驱动。把下载好的mtk驱动解压开来。会得到两个文件夹（如图）。选择第一个文件夹进去。之后选择win10&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/d4b8a7c82066db1251cea70d8c394a53b159830e.BF27i1kr_PBm8f.webp&quot; alt=&quot;640 (1).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/c1c7ac6f9305f9c745ef02da1d2894b09d6a8532.C2BJM54x_Z9eTK.webp&quot; alt=&quot;640 (2).webp&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;双击打开MediaTek Devices Installer.bat（如图）&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/4c5a2e7bc9bd792a4e326a89fd08761e2c620ec9.SXi2wB-X_Z1ttYe6.webp&quot; alt=&quot;640 (3).webp&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;来到这个界面。直接一路回车，直到窗口关闭就行（如图）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/78cc9a2aa75139c0ce5d69bb4fc0608f3743ae14.CGby8yy3_ZdRNju.webp&quot; alt=&quot;640 (4).webp&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;安装vcom驱动&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1. 下载好vcom驱动压缩包解压开来。之后右击cdc-acm.inf这个文件。选择安装。等待弹出安装完成（如图）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/635cf678053cc53d391a75215505942691dddebc.DlbkVTWl_Z17gD4g.webp&quot; alt=&quot;640 (5).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/b068c29926338744e23c219a771d646f5aa53718.-DCf-bwN_1PSKDN.webp&quot; alt=&quot;640 (6).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;说明：如果是win11，点击安装后会没有反应，请无视即可&lt;/p&gt;
&lt;p&gt;安装libusb-win32&lt;/p&gt;
&lt;p&gt;1. 双击打开libusb-win32安装程序，一直下一步就可以了&lt;/p&gt;
&lt;p&gt;2. 出现下图这个界面，就可以直接关掉了，不用管他&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/4f6b31d2e8a9cbde5365630406166ce1893e66fb.CAnQLaSx_ZTQtkR.webp&quot; alt=&quot;640 (7).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;进行联发科跳免授权&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1. 打开AuthBypassTool v11这个软件（如图）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/6372c0c33805fdc79d7fbb1315cc281713b036c4.7DTdAFlm_1sM07I.webp&quot; alt=&quot;640 (8).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;2. 点击左下角的disable auth。这时候会有一个进度条在走。也就是倒计时。走完了就得重新点一下。之后手机按住音量+和电源键连接上电脑。如果出现下图所示，则表示成功并松开。不能拔掉数据线（如图）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/58450fe2861a71d0ad38be5c31c4716ea0e7518c.B1sHS861_1oTYGE.webp&quot; alt=&quot;640 (9).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果出现了下图显示（也就是报错）。可重新来一次。一般来讲就可以成功了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/59266a9f962321f0e1b155366c0cce011c9039a1.jul-Gvu4_1aRSRq.webp&quot; alt=&quot;640 (10).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;成功之后关闭该工具。进行下一步刷机&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最后的刷机&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1. 先把线刷包解压成一个文件夹（如果解好了，可以跳过）。把刚下载好的flashtool压缩包解压开来。得到很多文件。我们主要打开flash_tool.exe这个程序&lt;/p&gt;
&lt;p&gt;2. 打开之后，有一个报错窗口（如下图）。不要管他，直接点确定&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/1e200aef59a1e492dea3440048e066014c04ba23.DYC-vTvT_Z1nNiio.webp&quot; alt=&quot;640 (12).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;3. 来到主界面（如下图）。第一个下载DA。点击后面的浏览&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/633bb87a7507b9f035cb93e93fd7726183f60c03.s0l0YkSV_ZzCf3H.webp&quot; alt=&quot;640 (13).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;4. 选择倒数第二个（如下图）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/21ecf4a652628db091a677d97ae7a20a0991cf04.D74xye5F_Z1J8YJi.webp&quot; alt=&quot;640 (14).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;5. 选择完之后。来到第二个。选择线刷包位置。之后点第一个文件夹进去（如图）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/53c129dfd58e9f6e306625c01870ca30418d94dc.Ddm0ZGyZ_Z2iivHV.webp&quot; alt=&quot;640 (15).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;6. 选择倒数第二个的txt配置文件（如图）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/66bf4698ecc707539dcea528202a9af9e533b56b.Hm9Nam95_ZW6uVF.webp&quot; alt=&quot;640 (16).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;7. 之后点确定会开始加载镜像文件。等待加载完成（如图）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/e976282ad8187bcd8ec6c9d26ddeaca35cc90902.R2343vX7_y9CLK.webp&quot; alt=&quot;640 (17).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;检查端口&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;先别着急点下载。先检查一下连接里面的端口是否和驱动用的端口一致。点左上角选项进去。切换到连接选项卡。看看后面的串口，看一下是不是和设备管理器里面的MTK端口一致。如果一致。就可以关掉窗口，点下载刷机了&lt;br /&gt;
举个例子。如果设备管理器显示的端口是com4。那么连接这边后面的串口也得是com4。如果不一样。是可以改过来的。最后一样，就可以刷机了 （如图）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/2b58bb8c57613d8be3d65e484fc614009d8c9103.DPJOO8HS_ZvceTc.webp&quot; alt=&quot;640 (18).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;说明：如果UART没有正确显示MTK端口，但设备管理器已经显示了，请切换到USB通道再进行尝试刷机&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;开始刷机&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;如果端口确定好没错的话。就可以开始刷机了。点主界面的下载。会开始跑进度条。等待下载完成（如图）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/b86a20c341d6deabaee3f8f971c99676c9089d97.CklvD5Z0_2nNawJ.webp&quot; alt=&quot;640 (19).webp&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;再次说明：如果您的系统已经扩容了或修改了分区表。请在这一步的时候把仅下载切换至固件升级即可正常刷机（红米Notre8Pro测试通过，不会掉IMEI和基带）&lt;/p&gt;
&lt;p&gt;2. 刷机完成之后，会出现一个绿色的大√。则表示刷机成功。手机长按电源键十秒。一般来说，这时候手机已经救活了。如果跳到官方rec。请清除所有数据之后即可开机（如下图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/451ed25045e1d973bdccd4f9bf4a9ac8a58e2e8d.BTyiATr0_1cFAHF.webp&quot; alt=&quot;640 (20).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;3. 致此手机已经完全救活过来了&lt;/p&gt;
&lt;p&gt;说明：如果刷机过程中出现某个分区刷入报错，请在该分区名的前面取消勾选它，随后再次尝试刷机&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;结束&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;希望写了这么久的图文教程。能够帮助到大家。也希望小白们也不要去花钱刷机了。看到这篇教程自己学会了。也可以帮助到别人的。避免花冤枉钱。有什么问题请点击底部的发信息即可问我。如果你觉得还不错的话。可以赞赏我。自愿赞赏。不强迫。最后，祝大家刷机愉快&lt;/p&gt;
</content:encoded></item><item><title>小白教程-联发科强制解bl锁完整教程</title><link>https://www.497995.xyz/posts/forcelockbl/</link><guid isPermaLink="true">https://www.497995.xyz/posts/forcelockbl/</guid><description>为联发科（MTK）设备提供了一种强制解锁 Bootloader (BL锁) 的方法，使用 MTK Client 工具，帮助用户绕过官方解锁限制。</description><pubDate>Wed, 22 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;前言&lt;/p&gt;
&lt;p&gt;该教程仅支持发布于2021年5月以及之前的SOC（也就是天坤920之前的CPU）&lt;/p&gt;
&lt;p&gt;以红米note8Pro为例，其他mtk机型可以参考参考&lt;/p&gt;
&lt;p&gt;系统建议使用win10可避免一些问题&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;准备工作&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;一部未解除BL锁的手机&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一根数据线和一台正常的电脑（网吧不建议)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一双手和一个正常的脑子&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一个良好的网络环境&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;需要的文件&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;mtkclientgui压缩包&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;USB DK（一般用X64版本）&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;说明：以上资源均可在下载站找到并下载，路径：首页→通用手机刷机资源→电脑工具→联发科强解bl锁工具&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教程开始&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;首先下载这个工具和USBDK，下载完之后，把这个zip包解压下来，放桌面方便一些&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;首先安装USBDK，双击msi程序会自动进行安装&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;之后打开文件夹，找到最后一个Start.bat双击打开（如图）&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/5b4170e329d5c31f19bf80a1896d141bd95ed42c.Dp7NwcTY_Z6jFVu.webp&quot; alt=&quot;640.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/d4b8a7c82066db1251cea70d8c394a53b159830e.BF27i1kr_PBm8f.webp&quot; alt=&quot;640 (1).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/c1c7ac6f9305f9c745ef02da1d2894b09d6a8532.C2BJM54x_Z9eTK.webp&quot; alt=&quot;640 (2).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;5. 输入y确定下一步&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/4c5a2e7bc9bd792a4e326a89fd08761e2c620ec9.SXi2wB-X_Z1ttYe6.webp&quot; alt=&quot;640 (3).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;6. 此时手机关机状态下按住音量+和电源键连接电脑，听到连接声音响了就立马松开，如果跟我一样，弹出以下界面，那么恭喜你。bl锁解开成功（如图）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/78cc9a2aa75139c0ce5d69bb4fc0608f3743ae14.CGby8yy3_ZdRNju.webp&quot; alt=&quot;640 (4).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;7. 最后长按电源键10妙重启手机查看结果，红米note8pro已测试通过，其他联发科机型可以试试（如图）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/635cf678053cc53d391a75215505942691dddebc.DlbkVTWl_Z17gD4g.webp&quot; alt=&quot;640 (5).webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;说明：如果连接没反应，请手动安装MTK驱动&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;结束&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;希望写了这么久的图文教程。能够帮助到大家。也希望小白们也不要去花钱刷机了。看到这篇教程自己学会了。也可以帮助到别人的。避免花冤枉钱。有什么问题请点击底部的发信息即可问我。如果你觉得还不错的话。可以赞赏我。自愿赞赏。不强迫。最后，祝大家刷机愉快&lt;/p&gt;
</content:encoded></item><item><title>（国内首发）MTK IMEI 修复教程 For Redmi Note 8 Pro</title><link>https://www.497995.xyz/posts/fiximeimtk/</link><guid isPermaLink="true">https://www.497995.xyz/posts/fiximeimtk/</guid><description>一篇针对红米 Note 8 Pro (MTK) 的详细 IMEI 修复教程，通过制作卡刷包的方式，解决因刷机等原因造成的 IMEI 丢失问题。</description><pubDate>Tue, 21 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;前言&lt;/p&gt;
&lt;p&gt;经过漫长的时间等待，IMEI修复教程总算是来了（麻麻再也不用担心丢了IMEI而烦恼），不需要复杂的手段，就可以将你的手机修好IMEI，最后还是感谢这位老外Tim Josten。不墨迹，直接接下来的内容&lt;/p&gt;
&lt;p&gt;一. 准备工作&lt;/p&gt;
&lt;p&gt;1.一部丢了IMEI的n8p（解锁状态）&lt;br /&gt;
2.电脑和数据线（尽量windows 10及以上）&lt;br /&gt;
3.本文所提到的文件都需要&lt;br /&gt;
4.第三方内核/ROM（kernel或ROM）&lt;/p&gt;
&lt;p&gt;二. 开始制作专属修复imei卡刷包&lt;/p&gt;
&lt;p&gt;1.下载好这个压缩包。下载链接；&lt;a href=&quot;https://wwjo.lanzouy.com/iRXqn0w65lhc&quot;&gt;查看链接&lt;/a&gt;&lt;br /&gt;
2.解压后有以下文件（图1）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/26f995f504e7fac7bac1574018d5f6714c3c26b2.C3lawz6c_2dYtUA.webp&quot; alt=&quot;3430069_380b9e7a_7678_3751_568@1920x1030.jpeg.m.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;3.打开config.txt（如图2-3）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/59b4c8277b83c8cb75e9947c1659fd2f03372c9d.CnXVq35T_Z22GhWu.webp&quot; alt=&quot;3430069_87c9fe26_7678_376_56@1920x1030.jpeg.m.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/764e73fce12b6fc6748be028699e9ceb641a54d9.B3KsjvbB_ZGA3x7.webp&quot; alt=&quot;3430069_dcfdd3ff_7678_3766_364@1423x740.jpeg.m.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;4.解释一下各参数的用途吧&lt;br /&gt;
①cpidid=设备芯片的ID，每个手机的芯片ID都不一样，所以要如实填写（不要老想着用别人的，出问题了就不能怪自己）&lt;br /&gt;
问；如何获取芯片ID？&lt;br /&gt;
第一步，下载并打开termux（酷安或者百度都可以）&lt;br /&gt;
第二步；输入getprop ro.boot.chipid回车&lt;br /&gt;
第三步；出现图片中的结果就表示获取成功&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/07656050838c3869233a1c7327a15ef2670c77da.B0_WZsIK_2f2vgn.webp&quot; alt=&quot;3430069_0cf6acc8_7678_377_97@1080x2340.jpeg.m.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;本次教程就到这里，该说的我已经说了，要是还不会的话，那我没办法（解锁和刷入第三方twrp应该都会了吧）
强制解锁教程可以参考我；查看链接
TWRP资源可以去我站点下载
如果有其他问题，请在评论区底下进行交流，不懂的我看到了一般会回复，教程结束&lt;/p&gt;
&lt;p&gt;②第二和第三就不用说了，自己填（可以是自己的原机imei，也可以像我一样随便填MIUI系统&lt;br /&gt;
第一步，打开设置→我的设备→全部参数&lt;br /&gt;
第二步，找到状态信息→就可以查看这两个MAC地址的详细信息，也是把它复制出来，填到这个配置文件就可以&lt;br /&gt;
操作流程如下（图）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/4670f132e39eb8d1233a4892ae241c0f42b431f0.D2Iw13Ph_Z19Qt3y.webp&quot; alt=&quot;3430069_5ea81a9d_7678_3774_493@1080x2340.jpeg.m.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/8f369d0a168352800980f4251a57816d78f76406.gmVBgmts_Z1zXDr5.webp&quot; alt=&quot;3430069_b29d22ee_7678_378_889@1080x2340.jpeg.m.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/2eac2a466b707524287030be886c25c12f5fe582.BGpfRwly_1Mzpex.webp&quot; alt=&quot;3430069_9958aacc_7678_3788_576@1080x2340.jpeg.m.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/ced734ab7293500ff4734931b38d015a2e5386df.DC_KkFgm_ZKdREV.webp&quot; alt=&quot;3430069_2fc5dba4_7678_3846_922@1080x2340.jpeg.m.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;问；为什么会显示无法获取？&lt;br /&gt;
就是因为没有打开WIFI和蓝牙功能，打开之后就可以正常获取了&lt;br /&gt;
原生系统&lt;br /&gt;
操作流程跟MIUI差不多，我这里就不发图片了&lt;br /&gt;
5.配置文件全部填完之后保存&lt;br /&gt;
6.直接双击打开mtk_imei.cmd，显示图片中的结果就是制作完成（图）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/86103f65f81e018ffef7d2500e94e840a43fe8cd.BPpwmvLO_Z26ECAB.webp&quot; alt=&quot;3430069_f3ebdc62_7681_8186_657@1223x639.jpeg.m.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;7.完成之后关闭窗口，你会得到一个修补好的卡刷包，使用twrp刷入即可&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/64a66b3554bba2a074d76166e7286becfe703da8.md7rQSDu_Z1MRxW5.webp&quot; alt=&quot;3430069_028139c7_7681_8193_358@1920x1030.jpeg.m.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;8.最后就会看到你修复好的IMEI&lt;/p&gt;
&lt;p&gt;三. 其他重要说明&lt;/p&gt;
&lt;p&gt;1.本修复教程适用所有基于ROSS的ROM（包括MIUI12.5所有版本，基于这个底层的第三方ROM和类原生）&lt;br /&gt;
2.不适用基于QOSS及以下的ROM（包括miui10.miui11.miui12和基于这个底层的第三方ROM以及类原生）&lt;br /&gt;
3.不适用基于cfw底包的原生系统使用&lt;br /&gt;
4.如果你的WINDOWS缺少Visual C++ Redistributable for Visual Studio 2015(x64)，请点击下方链接下载并安装（如果有了请忽略）&lt;br /&gt;
下载链接；X64；&lt;a href=&quot;https://wwjo.lanzouy.com/ilfES0w6apmb&quot;&gt;查看链接&lt;/a&gt;&lt;br /&gt;
X86；&lt;a href=&quot;https://wwjo.lanzouy.com/i1wMD0w6aq4j&quot;&gt;查看链接&lt;/a&gt;&lt;br /&gt;
5.切换ROM时，请确保在刷入ROM后立即刷入“imei_repair.zip”文件，然后再进行第一次开机。这是必要的，因为删除系统分区将需要你再次刷入修复包&lt;br /&gt;
6.官方内核可能会不工作，请使用第三方内核（我的内核已经集成了，到时候再编译一遍不带root的供你们使用）&lt;br /&gt;
7.本教程仅适用Redmi Note 8 Pro，其他机型能不能用我不清楚（自己试试就可以了）&lt;/p&gt;
&lt;p&gt;要求就是内核版本必须是4.14的，而且集成了这个模块&lt;br /&gt;
链接；&lt;a href=&quot;https://github.com/AgentFabulous/begonia/commit/111f687d092b7fd1ccc64710795035ef30520629&quot;&gt;查看链接&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;四.目前状态&lt;br /&gt;
小米账号与小米云服务已正常使用（包括查找手机），其他的就留给你们测试了&lt;/p&gt;
&lt;p&gt;五.修复成功截图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/1df051d269bd4a2b7355289aa60250d98773e98a.CTKtSFq6_ZyAasO.webp&quot; alt=&quot;3430069_fc59e41f_7681_8201_565@3325x2494.jpeg.m.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/f50782ad13660be05f193a96c1bf756364fb9061.CAgTjcTK_Zjh3SF.webp&quot; alt=&quot;3430069_7adbaa43_7681_8203_974@3325x2494.jpeg.m.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/fd421820e00334ac4ca954a11b1b03fe771311a2.C00E_aEO_ZFdyAt.webp&quot; alt=&quot;3430069_bdd41412_7681_8208_944@3325x2494.jpeg.m.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.497995.xyz/_astro/38c93e10982a8a4b0f2eee4853a5b964f6cbc1e9.DKrTUN11_4RN4I.webp&quot; alt=&quot;3430069_e6586423_7681_8216_798@3325x2494.jpeg.m.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;本次教程就到这里，该说的我已经说了，要是还不会的话，那我没办法（解锁和刷入第三方twrp应该都会了吧）&lt;br /&gt;
强制解锁教程可以参考我；&lt;a href=&quot;https://www.coolapk.com/feed/31977436?shareKey=MGRkOTUyMmQ5NmExNjQ2MGFkYjM~&amp;amp;shareUid=3430069&amp;amp;shareFrom=com.coolapk.market_13.1.3&quot;&gt;查看链接&lt;/a&gt;&lt;br /&gt;
TWRP资源可以去我站点下载&lt;br /&gt;
如果有其他问题，请在评论区底下进行交流，不懂的我看到了一般会回复，教程结束&lt;/p&gt;
</content:encoded></item></channel></rss>