<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>学习笔记 on 彩虹兔的博客</title>
    <link>https://blog.caihongtu.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</link>
    <description>Recent content from 彩虹兔的博客</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    
    <managingEditor>admin_reply@caihongtu.top (彩虹兔)</managingEditor>
    <webMaster>admin_reply@caihongtu.top (彩虹兔)</webMaster>
    
    <copyright>本博客所有文章除特别声明外，均采用 BY-NC-SA 许可协议。转载请注明出处！</copyright>
    
    <lastBuildDate>Sat, 16 May 2026 11:50:48 +0800</lastBuildDate>
    
    
    <atom:link href="https://blog.caihongtu.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/index.xml" rel="self" type="application/rss&#43;xml" />
    

    
    

    <item>
      <title>避免重复造轮子的解决方案</title>
      <link>https://blog.caihongtu.top/post/2026/selfcli/</link>
      <pubDate>Sat, 16 May 2026 11:30:30 &#43;0800</pubDate>
      <author>admin_reply@caihongtu.top (彩虹兔)</author>
      <guid>https://blog.caihongtu.top/post/2026/selfcli/</guid>
      <description>
        <![CDATA[<h1>避免重复造轮子的解决方案</h1><p>作者：彩虹兔（admin_reply@caihongtu.top）</p>
        
          <blockquote class="alert-blockquote note">
    <p class="alert-heading">
      Note
    </p>
    <p><p>重复造轮子是独立开发者最大的效率杀手。一个管理系统项目中，<strong>登录注册、权限控制、CRUD 操作、通用组件这些重复业务通常占总开发量的 60%-80%</strong>。解决这个问题的核心思路是：<strong>建立分层复用体系，将一次性劳动转化为可重复使用的资产</strong>，最终实现 &ldquo;新项目 = 基础模板 + 业务定制 + 少量配置&rdquo; 的开发模式。</p>
        
        <hr><p>本文2026-05-16首发于<a href='https://blog.caihongtu.top/'>彩虹兔的博客</a>，最后修改于2026-05-16</p>]]>
      </description>
      
        <category>学习笔记</category>
      
    </item>
    
    

    <item>
      <title>技术栈推荐</title>
      <link>https://blog.caihongtu.top/post/2026/stack/</link>
      <pubDate>Thu, 09 Apr 2026 18:22:40 &#43;0800</pubDate>
      <author>admin_reply@caihongtu.top (彩虹兔)</author>
      <guid>https://blog.caihongtu.top/post/2026/stack/</guid>
      <description>
        <![CDATA[<h1>技术栈推荐</h1><p>作者：彩虹兔（admin_reply@caihongtu.top）</p>
        
          <blockquote>
<p>在此记录一下我觉得比较好用的个人项目技术栈。</p></blockquote>
<h2 id="推荐技术栈">
<a class="header-anchor" href="#%e6%8e%a8%e8%8d%90%e6%8a%80%e6%9c%af%e6%a0%88"></a>
推荐技术栈
</h2><div class="tabs" id="tab-tab_9ddd2e3d_1778924963951598167">
		<ul class="nav-tabs center"><li class="tab active"><a class="#tab_9ddd2e3d_1778924963951598167-1">前端开发</a></li><li class="tab"><a class="#tab_9ddd2e3d_1778924963951598167-2">小程序开发</a></li><li class="tab"><a class="#tab_9ddd2e3d_1778924963951598167-3">后端开发</a></li><div class="tab-indicator"></div></ul>
		<div class="tab-content"><div class="tab-pane active" id="tab_9ddd2e3d_1778924963951598167-1"><blockquote>
<p>这里的前端指的是：Web端、桌面端、移动端</p></blockquote>
<ol>
<li>React + Typescript + Tailwind CSS + Shadcn UI + Vite + Tauri</li>
</ol>
<p>这是一套「前端极速开发 + 桌面原生体验」的黄金技术栈，专门用来做轻量、美观、跨平台（Windows/macOS/Linux/Android/iOS）、启动超快、体积极小的桌面软件。</p>
        
        <hr><p>本文2026-04-09首发于<a href='https://blog.caihongtu.top/'>彩虹兔的博客</a>，最后修改于2026-04-11</p>]]>
      </description>
      
        <category>学习笔记</category>
      
    </item>
    
    

    <item>
      <title>利用 Cloudflare Workers 实现 Glados 自动签到</title>
      <link>https://blog.caihongtu.top/post/2026/glados-checkin/</link>
      <pubDate>Sun, 05 Apr 2026 16:48:42 -0700</pubDate>
      <author>admin_reply@caihongtu.top (彩虹兔)</author>
      <guid>https://blog.caihongtu.top/post/2026/glados-checkin/</guid>
      <description>
        <![CDATA[<h1>利用 Cloudflare Workers 实现 Glados 自动签到</h1><p>作者：彩虹兔（admin_reply@caihongtu.top）</p>
        
          <h2 id="-准备工作提前备好">
<a class="header-anchor" href="#-%e5%87%86%e5%a4%87%e5%b7%a5%e4%bd%9c%e6%8f%90%e5%89%8d%e5%a4%87%e5%a5%bd"></a>
📋 准备工作（提前备好）
</h2><ol>
<li><strong>免费 Cloudflare 账号</strong>
注册地址：https://dash.cloudflare.com/</li>
<li><strong>GLaDOS 账号 Cookie</strong>（https://glados.rocks/）通过F12查看一个请求的Cookie</li>
<li><strong>可选</strong>：企业微信/wxpusher/pushplus通知（用于接收签到成功/失败通知），推荐使用企业微信机器人密钥</li>
</ol>
<h2 id="-全流程部署步骤">
<a class="header-anchor" href="#-%e5%85%a8%e6%b5%81%e7%a8%8b%e9%83%a8%e7%bd%b2%e6%ad%a5%e9%aa%a4"></a>
🚀 全流程部署步骤
</h2><h3 id="步骤-1登录-cloudflare-控制台">
<a class="header-anchor" href="#%e6%ad%a5%e9%aa%a4-1%e7%99%bb%e5%bd%95-cloudflare-%e6%8e%a7%e5%88%b6%e5%8f%b0"></a>
步骤 1：登录 Cloudflare 控制台
</h3><ol>
<li>打开 <a href="https://dash.cloudflare.com/">https://dash.cloudflare.com/</a></li>
<li>输入你的账号密码完成登录</li>
<li>进入左侧菜单 <strong>Workers &amp; Pages</strong>（Workers 与页面）</li>
</ol>
<h3 id="步骤-2创建新的-worker-应用">
<a class="header-anchor" href="#%e6%ad%a5%e9%aa%a4-2%e5%88%9b%e5%bb%ba%e6%96%b0%e7%9a%84-worker-%e5%ba%94%e7%94%a8"></a>
步骤 2：创建新的 Worker 应用
</h3><ol>
<li>点击 <strong>创建应用程序</strong></li>
<li>选择 <strong>创建 Worker</strong></li>
<li>给 Worker 起个名字（例如 <code>glados-checkin</code>）</li>
<li>点击 <strong>部署</strong>，完成初始创建</li>
</ol>
<h3 id="步骤-3替换为完整签到代码">
<a class="header-anchor" href="#%e6%ad%a5%e9%aa%a4-3%e6%9b%bf%e6%8d%a2%e4%b8%ba%e5%ae%8c%e6%95%b4%e7%ad%be%e5%88%b0%e4%bb%a3%e7%a0%81"></a>
步骤 3：替换为完整签到代码
</h3><ol>
<li>创建完成后，点击 <strong>快速编辑</strong>（进入代码编辑器）</li>
<li><strong>清空编辑器里默认的所有代码</strong></li>
<li>粘贴下方 <strong>完整版代码</strong>（支持手动触发 + Cron 定时 + 企业微信/wxpusher/pushplus通知）：</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm"> * Cloudflare Workers 版 Glados 自动签到
</span></span></span><span class="line"><span class="cl"><span class="cm"> * 部署后可通过访问 Worker URL 触发签到，也可配置 Cron 定时触发
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="kr">async</span> <span class="kd">function</span> <span class="nx">glados</span><span class="p">(</span><span class="nx">env</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">notice</span> <span class="o">=</span> <span class="p">[];</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// 从 Workers 环境变量获取 GLADOS Cookie（多行分隔多个账号）
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">env</span><span class="p">.</span><span class="nx">GLADOS</span><span class="p">)</span> <span class="k">return</span> <span class="nx">notice</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">cookies</span> <span class="o">=</span> <span class="nx">env</span><span class="p">.</span><span class="nx">GLADOS</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;\n&#39;</span><span class="p">).</span><span class="nx">filter</span><span class="p">(</span><span class="nb">Boolean</span><span class="p">);</span> <span class="c1">// 过滤空行
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">for</span> <span class="p">(</span><span class="kr">const</span> <span class="nx">cookie</span> <span class="k">of</span> <span class="nx">cookies</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="kr">const</span> <span class="nx">commonHeaders</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;cookie&#39;</span><span class="o">:</span> <span class="nx">cookie</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;referer&#39;</span><span class="o">:</span> <span class="s1">&#39;https://glados.cloud/console/checkin&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;user-agent&#39;</span><span class="o">:</span> <span class="s1">&#39;Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="c1">// 执行签到请求
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>      <span class="kr">const</span> <span class="nx">checkinRes</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">fetch</span><span class="p">(</span><span class="s1">&#39;https://glados.cloud/api/user/checkin&#39;</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">method</span><span class="o">:</span> <span class="s1">&#39;POST&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span> <span class="p">...</span><span class="nx">commonHeaders</span><span class="p">,</span> <span class="s1">&#39;content-type&#39;</span><span class="o">:</span> <span class="s1">&#39;application/json&#39;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="nx">body</span><span class="o">:</span> <span class="s1">&#39;{&#34;token&#34;:&#34;glados.cloud&#34;}&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="p">});</span>
</span></span><span class="line"><span class="cl">      <span class="kr">const</span> <span class="nx">checkinData</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">checkinRes</span><span class="p">.</span><span class="nx">json</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">      <span class="k">if</span> <span class="p">(</span><span class="nx">checkinData</span><span class="o">?</span><span class="p">.</span><span class="nx">code</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="nx">checkinData</span><span class="o">?</span><span class="p">.</span><span class="nx">message</span> <span class="o">||</span> <span class="s1">&#39;签到接口返回错误&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="c1">// 获取账号剩余天数
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>      <span class="kr">const</span> <span class="nx">statusRes</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">fetch</span><span class="p">(</span><span class="s1">&#39;https://glados.cloud/api/user/status&#39;</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">method</span><span class="o">:</span> <span class="s1">&#39;GET&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">headers</span><span class="o">:</span> <span class="nx">commonHeaders</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="p">});</span>
</span></span><span class="line"><span class="cl">      <span class="kr">const</span> <span class="nx">statusData</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">statusRes</span><span class="p">.</span><span class="nx">json</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">      <span class="k">if</span> <span class="p">(</span><span class="nx">statusData</span><span class="o">?</span><span class="p">.</span><span class="nx">code</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="nx">statusData</span><span class="o">?</span><span class="p">.</span><span class="nx">message</span> <span class="o">||</span> <span class="s1">&#39;状态接口返回错误&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="c1">// 拼接签到成功通知
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>      <span class="nx">notice</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="sb">`✅ 账号签到成功`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="sb">`📢 </span><span class="si">${</span><span class="nx">checkinData</span><span class="p">.</span><span class="nx">message</span><span class="si">}</span><span class="sb">`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="sb">`⏳ 剩余天数：</span><span class="si">${</span><span class="nb">Number</span><span class="p">(</span><span class="nx">statusData</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">leftDays</span><span class="p">).</span><span class="nx">toFixed</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="si">}</span><span class="sb"> 天`</span>
</span></span><span class="line"><span class="cl">      <span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">notice</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="sb">`❌ 签到失败`</span><span class="p">,</span> <span class="sb">`原因：</span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">message</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">notice</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">async</span> <span class="kd">function</span> <span class="nx">notify</span><span class="p">(</span><span class="nx">notice</span><span class="p">,</span> <span class="nx">env</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// 从 Workers 环境变量获取通知配置
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">env</span><span class="p">.</span><span class="nx">NOTIFY</span> <span class="o">||</span> <span class="o">!</span><span class="nx">notice</span> <span class="o">||</span> <span class="nx">notice</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">notifyOptions</span> <span class="o">=</span> <span class="nx">env</span><span class="p">.</span><span class="nx">NOTIFY</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;\n&#39;</span><span class="p">).</span><span class="nx">filter</span><span class="p">(</span><span class="nb">Boolean</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="k">for</span> <span class="p">(</span><span class="kr">const</span> <span class="nx">option</span> <span class="k">of</span> <span class="nx">notifyOptions</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">if</span> <span class="p">(</span><span class="nx">option</span><span class="p">.</span><span class="nx">startsWith</span><span class="p">(</span><span class="s1">&#39;console:&#39;</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// 日志输出到 Cloudflare Workers 控制台
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;📩 签到结果：\n&#39;</span> <span class="o">+</span> <span class="nx">notice</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;\n&#39;</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">option</span><span class="p">.</span><span class="nx">startsWith</span><span class="p">(</span><span class="s1">&#39;wxpusher:&#39;</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// 微信推送 WxPusher
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="kr">const</span> <span class="p">[,</span> <span class="nx">appToken</span><span class="p">,</span> <span class="p">...</span><span class="nx">uids</span><span class="p">]</span> <span class="o">=</span> <span class="nx">option</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;:&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="kr">await</span> <span class="nx">fetch</span><span class="p">(</span><span class="s1">&#39;https://wxpusher.zjiecode.com/api/send/message&#39;</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">method</span><span class="o">:</span> <span class="s1">&#39;POST&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span> <span class="s1">&#39;content-type&#39;</span><span class="o">:</span> <span class="s1">&#39;application/json&#39;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">          <span class="nx">body</span><span class="o">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">            <span class="nx">appToken</span><span class="o">:</span> <span class="nx">appToken</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nx">summary</span><span class="o">:</span> <span class="nx">notice</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">            <span class="nx">content</span><span class="o">:</span> <span class="nx">notice</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&lt;br&gt;&#39;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">            <span class="nx">contentType</span><span class="o">:</span> <span class="mi">3</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nx">uids</span><span class="o">:</span> <span class="nx">uids</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nb">Boolean</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">          <span class="p">}),</span>
</span></span><span class="line"><span class="cl">        <span class="p">});</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">option</span><span class="p">.</span><span class="nx">startsWith</span><span class="p">(</span><span class="s1">&#39;pushplus:&#39;</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// 推送加 PushPlus
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="kr">const</span> <span class="p">[,</span> <span class="nx">token</span><span class="p">]</span> <span class="o">=</span> <span class="nx">option</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;:&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="kr">await</span> <span class="nx">fetch</span><span class="p">(</span><span class="s1">&#39;https://www.pushplus.plus/send&#39;</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">method</span><span class="o">:</span> <span class="s1">&#39;POST&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span> <span class="s1">&#39;content-type&#39;</span><span class="o">:</span> <span class="s1">&#39;application/json&#39;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">          <span class="nx">body</span><span class="o">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">            <span class="nx">token</span><span class="o">:</span> <span class="nx">token</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nx">title</span><span class="o">:</span> <span class="nx">notice</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">            <span class="nx">content</span><span class="o">:</span> <span class="nx">notice</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&lt;br&gt;&#39;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">            <span class="nx">template</span><span class="o">:</span> <span class="s1">&#39;markdown&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="p">}),</span>
</span></span><span class="line"><span class="cl">        <span class="p">});</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">option</span><span class="p">.</span><span class="nx">startsWith</span><span class="p">(</span><span class="s1">&#39;qyweixin:&#39;</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// 企业微信机器人
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="kr">const</span> <span class="p">[,</span> <span class="nx">robotKey</span><span class="p">]</span> <span class="o">=</span> <span class="nx">option</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;:&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="kr">await</span> <span class="nx">fetch</span><span class="p">(</span><span class="sb">`https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=</span><span class="si">${</span><span class="nx">robotKey</span><span class="si">}</span><span class="sb">`</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">method</span><span class="o">:</span> <span class="s1">&#39;POST&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span> <span class="s1">&#39;content-type&#39;</span><span class="o">:</span> <span class="s1">&#39;application/json&#39;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">          <span class="nx">body</span><span class="o">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">            <span class="nx">msgtype</span><span class="o">:</span> <span class="s1">&#39;markdown&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nx">markdown</span><span class="o">:</span> <span class="p">{</span> <span class="nx">content</span><span class="o">:</span> <span class="nx">notice</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;\n&#39;</span><span class="p">)</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">          <span class="p">}),</span>
</span></span><span class="line"><span class="cl">        <span class="p">});</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// 兜底使用 PushPlus（直接填 token 场景）
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="kr">await</span> <span class="nx">fetch</span><span class="p">(</span><span class="s1">&#39;https://www.pushplus.plus/send&#39;</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">method</span><span class="o">:</span> <span class="s1">&#39;POST&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span> <span class="s1">&#39;content-type&#39;</span><span class="o">:</span> <span class="s1">&#39;application/json&#39;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">          <span class="nx">body</span><span class="o">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">            <span class="nx">token</span><span class="o">:</span> <span class="nx">option</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nx">title</span><span class="o">:</span> <span class="nx">notice</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">            <span class="nx">content</span><span class="o">:</span> <span class="nx">notice</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&lt;br&gt;&#39;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">            <span class="nx">template</span><span class="o">:</span> <span class="s1">&#39;markdown&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="p">}),</span>
</span></span><span class="line"><span class="cl">        <span class="p">});</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">&#39;通知发送失败：&#39;</span><span class="p">,</span> <span class="nx">error</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">      <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Workers 核心请求处理函数
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">async</span> <span class="kd">function</span> <span class="nx">handleRequest</span><span class="p">(</span><span class="nx">request</span><span class="p">,</span> <span class="nx">env</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">checkinNotice</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">glados</span><span class="p">(</span><span class="nx">env</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kr">await</span> <span class="nx">notify</span><span class="p">(</span><span class="nx">checkinNotice</span><span class="p">,</span> <span class="nx">env</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 返回友好的 JSON 响应
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">return</span> <span class="k">new</span> <span class="nx">Response</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">      <span class="nx">success</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">message</span><span class="o">:</span> <span class="s1">&#39;签到流程执行完成&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">notice</span><span class="o">:</span> <span class="nx">checkinNotice</span>
</span></span><span class="line"><span class="cl">    <span class="p">}),</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span> <span class="s1">&#39;Content-Type&#39;</span><span class="o">:</span> <span class="s1">&#39;application/json; charset=utf-8&#39;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nx">status</span><span class="o">:</span> <span class="mi">200</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 异常响应
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">return</span> <span class="k">new</span> <span class="nx">Response</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">      <span class="nx">success</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">message</span><span class="o">:</span> <span class="s1">&#39;签到流程执行失败&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">error</span><span class="o">:</span> <span class="nx">error</span><span class="p">.</span><span class="nx">message</span> <span class="o">||</span> <span class="nx">error</span><span class="p">.</span><span class="nx">toString</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}),</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span> <span class="s1">&#39;Content-Type&#39;</span><span class="o">:</span> <span class="s1">&#39;application/json; charset=utf-8&#39;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nx">status</span><span class="o">:</span> <span class="mi">500</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 注册 Workers Fetch 事件（入口）
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">async</span> <span class="nx">fetch</span><span class="p">(</span><span class="nx">request</span><span class="p">,</span> <span class="nx">env</span><span class="p">,</span> <span class="nx">ctx</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nx">handleRequest</span><span class="p">(</span><span class="nx">request</span><span class="p">,</span> <span class="nx">env</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="kr">async</span> <span class="nx">scheduled</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">env</span><span class="p">,</span> <span class="nx">ctx</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">handleRequest</span><span class="p">(</span><span class="s2">&#34;&#34;</span><span class="p">,</span> <span class="nx">env</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><ol start="4">
<li>点击右上角 <strong>部署</strong></li>
</ol>
<h3 id="步骤-4配置环境变量核心">
<a class="header-anchor" href="#%e6%ad%a5%e9%aa%a4-4%e9%85%8d%e7%bd%ae%e7%8e%af%e5%a2%83%e5%8f%98%e9%87%8f%e6%a0%b8%e5%bf%83"></a>
步骤 4：配置环境变量（核心！）
</h3><p><img src="https://files.seeusercontent.com/2026/04/06/Qxa0/20260406170722223.png" alt="环境变量"></p>
        
        <hr><p>本文2026-04-05首发于<a href='https://blog.caihongtu.top/'>彩虹兔的博客</a>，最后修改于2026-04-06</p>]]>
      </description>
      
        <category>学习笔记</category>
      
    </item>
    
    

    <item>
      <title>创建第一个npm包</title>
      <link>https://blog.caihongtu.top/post/2026/create-npm-package-frist/</link>
      <pubDate>Sat, 28 Mar 2026 23:10:04 -0700</pubDate>
      <author>admin_reply@caihongtu.top (彩虹兔)</author>
      <guid>https://blog.caihongtu.top/post/2026/create-npm-package-frist/</guid>
      <description>
        <![CDATA[<h1>创建第一个npm包</h1><p>作者：彩虹兔（admin_reply@caihongtu.top）</p>
        
          <h2 id="介绍">
<a class="header-anchor" href="#%e4%bb%8b%e7%bb%8d"></a>
介绍
</h2><p>什么是npm包？</p>
<p><strong>npm 包</strong>（Node Package Manager Package），是<strong>Node.js 生态系统中，用于封装、复用和分发 JavaScript 代码的标准化模块单元</strong>。简单说，它就是一个打包好的代码工具库，可以被直接下载、引用到项目中使用。</p>
        
        <hr><p>本文2026-03-28首发于<a href='https://blog.caihongtu.top/'>彩虹兔的博客</a>，最后修改于2026-03-29</p>]]>
      </description>
      
        <category>学习笔记</category>
      
    </item>
    
    

    <item>
      <title>使用coze AI生成PPT式HTML</title>
      <link>https://blog.caihongtu.top/post/2026/html-as-ppt-by-ai/</link>
      <pubDate>Wed, 25 Mar 2026 11:31:48 -0700</pubDate>
      <author>admin_reply@caihongtu.top (彩虹兔)</author>
      <guid>https://blog.caihongtu.top/post/2026/html-as-ppt-by-ai/</guid>
      <description>
        <![CDATA[<h1>使用coze AI生成PPT式HTML</h1><p>作者：彩虹兔（admin_reply@caihongtu.top）</p>
        
          <h2 id="引言">
<a class="header-anchor" href="#%e5%bc%95%e8%a8%80"></a>
引言
</h2><p>如果由AI生成PPT，费token不说，生成的内容更是一言难尽。</p>
<p>但是用AI生成HTML就不同了啊，目前这方面AI可以说是已经很牛掰了。</p>
<p>所以，如果你有短视频方面或者个人使用的需求，那么完全可以使用PPT式的HTML来当作你的叙述画面！</p>
        
        <hr><p>本文2026-03-25首发于<a href='https://blog.caihongtu.top/'>彩虹兔的博客</a>，最后修改于2026-03-25</p>]]>
      </description>
      
        <category>学习笔记</category>
      
    </item>
    
    

    <item>
      <title>Cloudflare Workers 项目推荐</title>
      <link>https://blog.caihongtu.top/post/2026/cf-workers-recommend/</link>
      <pubDate>Mon, 23 Mar 2026 22:01:22 &#43;0800</pubDate>
      <author>admin_reply@caihongtu.top (彩虹兔)</author>
      <guid>https://blog.caihongtu.top/post/2026/cf-workers-recommend/</guid>
      <description>
        <![CDATA[<h1>Cloudflare Workers 项目推荐</h1><p>作者：彩虹兔（admin_reply@caihongtu.top）</p>
        
          <h2 id="1-saas-admin-template">
<a class="header-anchor" href="#1-saas-admin-template"></a>
1. Saas Admin Template
</h2><p>用 Astro、shadcn/ui 和 Cloudflare Workers 构建的管理仪表盘模板</p>
<a href="https://github.com/cloudflare/templates/tree/v.8.1.0/saas-admin-template" title="Saas Admin Template" target="_blank">Saas Admin Template</a>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm create cloudflare@latest -- --template<span class="o">=</span>cloudflare/templates/saas-admin-template
</span></span></code></pre></div><h2 id="2-react-router--hono-fullstack-app">
<a class="header-anchor" href="#2-react-router--hono-fullstack-app"></a>
2. React Router + Hono Fullstack App
</h2><p>这是一个基于 Cloudflare Workers 的现代化全栈模板，后端 API 使用 Hono，前端路由使用 React Router，组件美观易用，并使用 Tailwind CSS 进行样式设计。</p>
        
        <hr><p>本文2026-03-23首发于<a href='https://blog.caihongtu.top/'>彩虹兔的博客</a>，最后修改于2026-03-23</p>]]>
      </description>
      
        <category>学习笔记</category>
      
    </item>
    
    

    <item>
      <title>【02】学习Next.js框架之链接、导航、进阶路由</title>
      <link>https://blog.caihongtu.top/post/2025/learn-nextjs-02/</link>
      <pubDate>Mon, 27 Oct 2025 09:17:42 &#43;0800</pubDate>
      <author>admin_reply@caihongtu.top (彩虹兔)</author>
      <guid>https://blog.caihongtu.top/post/2025/learn-nextjs-02/</guid>
      <description>
        <![CDATA[<h1>【02】学习Next.js框架之链接、导航、进阶路由</h1><p>作者：彩虹兔（admin_reply@caihongtu.top）</p>
        
          <h2 id="链接-link">
<a class="header-anchor" href="#%e9%93%be%e6%8e%a5-link"></a>
链接 <code>Link</code>
</h2><h3 id="基础用法">
<a class="header-anchor" href="#%e5%9f%ba%e7%a1%80%e7%94%a8%e6%b3%95"></a>
基础用法
</h3><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Link</span> <span class="kr">from</span> <span class="s2">&#34;next/link&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">Home() {</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span><span class="nx">Welcome</span> <span class="nx">home</span><span class="o">!</span><span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">Link</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;/blog&#34;</span><span class="p">&gt;</span><span class="nx">Blog</span><span class="p">&lt;/</span><span class="nt">Link</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">&lt;</span><span class="nt">Link</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;/login&#34;</span> <span class="na">replace</span><span class="p">&gt;</span><span class="nx">Login</span><span class="p">&lt;/</span><span class="nt">Link</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><ul>
<li>
<p>上述代码，点击Blog后会跳转到<code>http://localhost:3000/blog</code></p>
</li>
<li>
<p>点击Login后会替换当前历史条目，此时再点返回，就会回到首页。</p>
        
        <hr><p>本文2025-10-27首发于<a href='https://blog.caihongtu.top/'>彩虹兔的博客</a>，最后修改于2025-10-27</p>]]>
      </description>
      
        <category>学习笔记</category>
      
    </item>
    
    

    <item>
      <title>【01】学习Next.js框架之安装入门、路由与布局</title>
      <link>https://blog.caihongtu.top/post/2025/learn-nextjs-01/</link>
      <pubDate>Sun, 26 Oct 2025 11:37:50 &#43;0800</pubDate>
      <author>admin_reply@caihongtu.top (彩虹兔)</author>
      <guid>https://blog.caihongtu.top/post/2025/learn-nextjs-01/</guid>
      <description>
        <![CDATA[<h1>【01】学习Next.js框架之安装入门、路由与布局</h1><p>作者：彩虹兔（admin_reply@caihongtu.top）</p>
        
          <h2 id="引言">
<a class="header-anchor" href="#%e5%bc%95%e8%a8%80"></a>
引言
</h2><p>Next.js 是 React 的一个 Web 框架，本篇文章是 “学习NextJs框架”的第一篇教程。</p>
<p>学习之前，默认读者已经熟悉 HTML、CSS、TypeScript、React。</p>
        
        <hr><p>本文2025-10-26首发于<a href='https://blog.caihongtu.top/'>彩虹兔的博客</a>，最后修改于2025-10-26</p>]]>
      </description>
      
        <category>学习笔记</category>
      
    </item>
    
    

    <item>
      <title>【持续更新中...】【全流程】使用React的Taro和Cloudflare Workers免费创建部署微信小程序！</title>
      <link>https://blog.caihongtu.top/post/2025/cwbtacwff1/</link>
      <pubDate>Tue, 14 Oct 2025 15:25:40 &#43;0800</pubDate>
      <author>admin_reply@caihongtu.top (彩虹兔)</author>
      <guid>https://blog.caihongtu.top/post/2025/cwbtacwff1/</guid>
      <description>
        <![CDATA[<h1>【持续更新中...】【全流程】使用React的Taro和Cloudflare Workers免费创建部署微信小程序！</h1><p>作者：彩虹兔（admin_reply@caihongtu.top）</p>
        
          <h2 id="引言">
<a class="header-anchor" href="#%e5%bc%95%e8%a8%80"></a>
引言
</h2><blockquote>
<p><a href="https://www.cloudflare.com/">Cloudflare</a>人称&quot;赛博活佛&quot;, 其中的<code>workers</code>更是能够作为代码初学者的一个练手工具, 其免费功能便足以支撑一个微小型的程序运行.<br>
本篇文章旨在给大家分享: 使用Taro(React框架)和Cloudflare workers 来完成一个微信小程序.<br>
预计文章会很长, 持续更新中&hellip;</p>
        
        <hr><p>本文2025-10-14首发于<a href='https://blog.caihongtu.top/'>彩虹兔的博客</a>，最后修改于2025-10-14</p>]]>
      </description>
      
        <category>学习笔记</category>
      
    </item>
    
    

    <item>
      <title>GitHub 个人主页 README 美化 &amp; Star 趋势图</title>
      <link>https://blog.caihongtu.top/post/2024/github-profile/</link>
      <pubDate>Thu, 14 Nov 2024 22:49:27 &#43;0800</pubDate>
      <author>admin_reply@caihongtu.top (彩虹兔)</author>
      <guid>https://blog.caihongtu.top/post/2024/github-profile/</guid>
      <description>
        <![CDATA[<h1>GitHub 个人主页 README 美化 & Star 趋势图</h1><p>作者：彩虹兔（admin_reply@caihongtu.top）</p>
        
          <h2 id="引言">
<a class="header-anchor" href="#%e5%bc%95%e8%a8%80"></a>
引言
</h2><p>每次看到有大佬的 Github 主页很炫酷，自己总是羡慕不已，那些大佬真是厉害，不仅技术强，就连 Github 个人主页都酷的一批。<br>
于是我便查阅资料，最终决定美化一下自己的 Github 主页 <del>（虽然我是个小菜鸡，什么开源好项目都没写出来&hellip;）</del></p>
        
        <hr><p>本文2024-11-14首发于<a href='https://blog.caihongtu.top/'>彩虹兔的博客</a>，最后修改于2024-11-14</p>]]>
      </description>
      
        <category>学习笔记</category>
      
    </item>
    
  </channel>
</rss>
