<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:media="http://search.yahoo.com/mrss/"
  xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title><![CDATA[⚡ 异类 Space]]></title>
    <link>https://758192.xyz</link>
    <description><![CDATA[记录一点技术，生活]]></description>
    <language>zh-CN</language>
    <lastBuildDate>Sat, 01 Aug 2026 11:37:35 GMT</lastBuildDate>
    <atom:link href="https://758192.xyz/feed.xml" rel="self" type="application/rss+xml"/>
    
    <item>
      <title><![CDATA[用Let‘s Encrypt签发ssl证书]]></title>
      <link>https://758192.xyz/post/ssl</link>
      <description><![CDATA[通过腾讯云SCF云函数用Let&#039;s Encrypt签发ssl证书]]></description>
      <content:encoded><![CDATA[<p><img src="https://letsencrypt.org/images/LetsEncrypt-SocialShare.png" alt="" /></p><h1 id="yourdomain-com-ssl-证书自动化方案">yourdomain.com SSL 证书自动化方案</h1>
<blockquote>
<p>为 <code>yourdomain.com</code> 域名签发 Let&#39;s Encrypt 通配符证书，通过腾讯云 SCF 云函数自动续签，本地 Tengine 部署，证书存 COS 备份并上传到 SSL 证书管理。</p>
</blockquote>
<hr>
<h2 id="目录">目录</h2>
<ol>
<li><a href="#1-%E6%9E%B6%E6%9E%84%E6%A6%82%E8%A7%88">架构概览</a></li>
<li><a href="#2-acme-%E5%8D%8F%E8%AE%AE%E4%B8%8E-lets-encrypt">ACME 协议与 Let&#39;s Encrypt</a></li>
<li><a href="#3-%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84">项目结构</a></li>
<li><a href="#4-%E6%A0%B8%E5%BF%83%E6%B5%81%E7%A8%8B%E8%AF%A6%E8%A7%A3">核心流程详解</a></li>
<li><a href="#5-dns-01-%E6%8C%91%E6%88%98">DNS-01 挑战</a></li>
<li><a href="#6-scf-%E4%BA%91%E5%87%BD%E6%95%B0%E8%87%AA%E5%8A%A8%E9%83%A8%E7%BD%B2">SCF 云函数自动部署</a></li>
<li><a href="#7-%E6%9C%AC%E5%9C%B0-tengine-%E9%83%A8%E7%BD%B2">本地 Tengine 部署</a></li>
<li><a href="#8-%E8%AF%81%E4%B9%A6%E4%B8%8A%E4%BC%A0%E5%88%B0%E8%85%BE%E8%AE%AF%E4%BA%91-ssl-%E7%AE%A1%E7%90%86">证书上传到腾讯云 SSL 管理</a></li>
<li><a href="#9-%E8%BF%90%E8%A1%8C%E6%97%A5%E5%BF%97%E7%A4%BA%E4%BE%8B">运行日志示例</a></li>
<li><a href="#10-%E7%BB%B4%E6%8A%A4%E5%91%BD%E4%BB%A4">维护命令</a></li>
</ol>
<hr>
<h2 id="1-架构概览">1. 架构概览</h2>
<pre><code>┌─────────────────────────────────────────────────────────────┐
│                    用户请求 HTTPS                            │
│                         │                                    │
│                   ┌─────┴──────┐                            │
│                   │  Tengine   │  本地 Web 服务器             │
│                   │  :80 → 301 │                            │
│                   │  :443 SSL  │                            │
│                   └─────┬──────┘                            │
│                         │ 读取证书                            │
│                   ┌─────┴──────┐   /usr/local/tengine/certs/ │
│                   │  COS 存储   │   fullchain.pem              │
│                   │  (广州)     │   privkey.pem                │
│                   └─────┬──────┘                            │
│                         │                                    │
│          ┌──────────────┼──────────────┐                     │
│          │              │              │                     │
│   ┌──────┴──────┐ ┌────┴─────┐ ┌─────┴──────┐              │
│   │ SCF 云函数  │ │ SSL 证书  │ │ 本地备份   │              │
│   │ 自动续签    │ │ 管理平台  │ │ scf-ssl/   │              │
│   │ ap-shanghai │ │ CERTIFICATE_ID │ │ certs/     │              │
│   └──────┬──────┘ └──────────┘ └────────────┘              │
│          │                                                  │
│   ┌──────┴──────┐                                          │
│   │  Let&#39;s      │  ACME v2 协议                             │
│   │  Encrypt    │  DNS-01 挑战                              │
│   │  CA         │◄────────────────────────────              │
│   └─────────────┘                                          │
│          │                                                  │
│   ┌──────┴──────┐                                          │
│   │  DNSPod     │  TXT 记录 _acme-challenge                 │
│   │  域名解析    │  添加/删除                                │
│   └─────────────┘                                          │
└─────────────────────────────────────────────────────────────┘
</code></pre><h2 id="2-acme-协议与-let-s-encrypt">2. ACME 协议与 Let's Encrypt</h2>
<h3 id="acme-automatic-certificate-management-environment">ACME（Automatic Certificate Management Environment）</h3>
<p>ACME v2 是 IETF 标准协议（RFC 8555），用于自动化证书申请和管理。Let&#39;s Encrypt 是全球最大的 ACME CA。</p>
<p><strong>核心概念：</strong></p>
<table>
<thead>
<tr>
<th>概念</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Account Key</strong></td>
<td>用于识别身份的 RSA 密钥对</td>
</tr>
<tr>
<td><strong>Order</strong></td>
<td>一次证书申请订单，包含一个或多个 identifier</td>
</tr>
<tr>
<td><strong>Authorization</strong></td>
<td>每个 identifier 需要完成至少一项挑战</td>
</tr>
<tr>
<td><strong>Challenge</strong></td>
<td>证明域名控制权的方式</td>
</tr>
<tr>
<td><strong>CSR</strong></td>
<td>证书签名请求（Certificate Signing Request）</td>
</tr>
</tbody></table>
<h3 id="挑战类型">挑战类型</h3>
<table>
<thead>
<tr>
<th>类型</th>
<th>说明</th>
<th>适用场景</th>
</tr>
</thead>
<tbody><tr>
<td><strong>HTTP-01</strong></td>
<td>在 <code>/.well-known/acme-challenge/</code> 放指定文件</td>
<td>有 Web 服务器，端口 80 可访问</td>
</tr>
<tr>
<td><strong>DNS-01</strong></td>
<td>在 DNS TXT 记录 <code>_acme-challenge.example.com</code> 放指定值</td>
<td>通配符证书、无 HTTP 服务器</td>
</tr>
<tr>
<td><strong>TLS-ALPN-01</strong></td>
<td>在 443 端口返回特定证书</td>
<td>精细控制 TLS 层</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>本方案选择 DNS-01</strong>，原因：</p>
<ul>
<li>支持通配符证书 <code>*.yourdomain.com</code></li>
<li>不需要对外暴露 HTTP 服务</li>
<li>通过 DNSPod API 自动完成</li>
</ul>
</blockquote>
<h2 id="3-项目结构">3. 项目结构</h2>
<pre><code>scf-ssl/
├── src/
│   ├── index.js        SCF 主入口 + 流程编排
│   ├── config.js       环境变量配置模块
│   ├── acme.js         ACME 协议核心逻辑
│   ├── dnspod.js       DNSPod API（TC3-HMAC-SHA256）
│   └── cos-store.js    COS 对象存储读写
├── deploy.js           SCF 一键部署脚本
├── certs/              本地证书文件（gitignore）
├── package.json
├── .env.example
└── README.md
</code></pre><h2 id="4-核心流程详解">4. 核心流程详解</h2>
<h3 id="4-1-完整签发流程">4.1 完整签发流程</h3>
<pre><code>SCF 触发 → 从 COS 读取 meta.json
  │
  ├─ 到期 &gt; 15 天
  │   └─ 跳过，直接返回
  │
  └─ 需要续签（或首次）
      │
      ├─ 1. 加载 ACME 账户密钥
      │     ├─ COS 有 account-key.pem → 直接使用
      │     └─ 首次运行 → 生成 RSA 4096 密钥 → 保存到 COS
      │
      ├─ 2. 连接 Let&#39;s Encrypt
      │     ├─ ENV=staging → acme-staging-v02.api.letsencrypt.org ✓ 无速率限制
      │     └─ 生产环境  → acme-v02.api.letsencrypt.org ⚠️ 有速率限制
      │
      ├─ 3. 注册账户（首次自动创建）
      │     POST /acme/new-account
      │     { termsOfServiceAgreed: true, contact: [&quot;mailto:email&quot;] }
      │
      ├─ 4. 生成 CSR
      │     域名私钥 (RSA 2048)
      │     ├─ CN = yourdomain.com
      │     └─ SAN = [yourdomain.com, *.yourdomain.com]
      │
      ├─ 5. 下单
      │     POST /acme/new-order
      │     identifiers: [
      │       { type: &quot;dns&quot;, value: &quot;yourdomain.com&quot; },
      │       { type: &quot;dns&quot;, value: &quot;*.yourdomain.com&quot; }
      │     ]
      │
      ├─ 6. 获取鉴权 + DNS-01 挑战
      │     每个 identifier 一个 authorization
      │     每个 authorization 包含 dns-01 challenge
      │
      ├─ 7. DNS 挑战（以下在 auto 模式中自动完成）
      │     ├─ challengeCreateFn  →  DNSPod 添加 TXT 记录
      │     ├─ 等待 60 秒 DNS 传播
      │     ├─ verifiyChallenge  →  本地验证 DNS 已生效
      │     ├─ completeChallenge  →  通知 Let&#39;s Encrypt 验证
      │     └─ challengeRemoveFn →  DNSPod 删除 TXT 记录
      │
      ├─ 8. Finalize 订单
      │     POST /acme/order/{id}/finalize
      │     { csr: &quot;base64 CSR&quot; }
      │
      ├─ 9. 下载证书
      │     GET /acme/cert/{id}
      │     → 返回 PEM 格式证书链（3 张证书）
      │
      └─ 10. 保存到 COS
            ├─ fullchain.pem    证书链
            ├─ privkey.pem      域名私钥
            └─ meta.json        到期元信息
</code></pre><h3 id="4-2-scf-主入口-src-index-js">4.2 SCF 主入口 (src/index.js)</h3>
<pre><code class="hljs language-javascript">export async function main_handler(event, context) {
  // 1. 读取 COS meta.json，检查到期时间
  const meta = await cosStore.readMeta(config.domain)

  if (meta &amp;&amp; daysUntilExpiry(meta.expiresAt) &gt; 15) {
    return { status: &quot;skipped&quot;, daysRemaining }  // 无需续签
  }

  // 2. 加载 ACME 账户密钥
  const accountKey = await loadOrCreateAccountKey(config.domain)

  // 3. 完整 ACME 签发流程
  const result = await requestCertificate(config.domain, accountKey)

  // 4. 保存证书到 COS
  await cosStore.saveCertificates(config.domain, result)
  await cosStore.writeMeta(config.domain, result)
}
</code></pre><h3 id="4-3-使用-acme-client-的-auto-模式">4.3 使用 acme-client 的 auto 模式</h3>
<p>本项目使用 <code>acme-client</code> npm 包的 auto 模式，它封装了整个 ACME 流程：</p>
<pre><code class="hljs language-javascript">const certificate = await client.auto({
  csr: csrBuf,
  email: config.email,
  termsOfServiceAgreed: true,
  challengePriority: [&quot;dns-01&quot;],

  // 挑战前：添加 DNS TXT 记录
  challengeCreateFn: async (authz, challenge, keyAuthorization) =&gt; {
    const value = keyAuthorization  // 这是 DNS-01 的 TXT 记录值
    await dnspod.addTxtRecord(domain, &quot;_acme-challenge&quot;, value)
    await sleep(60000)  // 等待 DNS 传播
  },

  // 挑战后：清理 DNS TXT 记录
  challengeRemoveFn: async () =&gt; {
    await dnspod.cleanChallengeRecords(domain, &quot;_acme-challenge&quot;)
  },
})
</code></pre><h2 id="5-dns-01-挑战">5. DNS-01 挑战</h2>
<h3 id="5-1-dnspod-api-调用-tc3-hmac-sha256-签名">5.1 DNSPod API 调用（TC3-HMAC-SHA256 签名）</h3>
<p>腾讯云 API 使用 TC3-HMAC-SHA256 签名算法。核心步骤：</p>
<pre><code class="hljs language-javascript">function sign(secretId, secretKey, action, params) {
  const algorithm = &quot;TC3-HMAC-SHA256&quot;
  const timestamp = Math.floor(Date.now() / 1000)
  const date = new Date(timestamp * 1000).toISOString().slice(0, 10)
  const service = &quot;dnspod&quot;
  const endpoint = &quot;dnspod.tencentcloudapi.com&quot;

  // Step 1: 构建 CanonicalRequest
  const payload = JSON.stringify(params)
  const hashedPayload = sha256(payload)
  const canonicalRequest = [
    &quot;POST&quot;,
    &quot;/&quot;,
    &quot;&quot;,
    `content-type:application/json
host:${endpoint}
`,
    &quot;content-type;host&quot;,
    hashedPayload,
  ].join(&quot;
&quot;)

  // Step 2: 构建 StringToSign
  const stringToSign = [
    algorithm,
    timestamp,
    `${date}/${service}/tc3_request`,
    sha256(canonicalRequest),
  ].join(&quot;
&quot;)

  // Step 3: 派生签名密钥
  const kDate = hmacSha256(&quot;TC3&quot; + secretKey, date)
  const kService = hmacSha256(kDate, service)
  const kSigning = hmacSha256(kService, &quot;tc3_request&quot;)
  const signature = hmacSha256(kSigning, stringToSign)

  // Step 4: 构建 Authorization
  const authorization = `${algorithm} Credential=${secretId}/${date}/${service}/tc3_request, SignedHeaders=content-type;host, Signature=${signature}`

  return { authorization, timestamp, payload }
}
</code></pre><h3 id="5-2-通配符证书的特殊处理">5.2 通配符证书的特殊处理</h3>
<p>通配符证书需要同时验证两个 identifier：</p>
<table>
<thead>
<tr>
<th>Identifier</th>
<th>TXT 主机记录</th>
<th>TXT 记录值</th>
</tr>
</thead>
<tbody><tr>
<td><code>yourdomain.com</code></td>
<td><code>_acme-challenge.yourdomain.com</code></td>
<td>keyAuthorization A</td>
</tr>
<tr>
<td><code>*.yourdomain.com</code></td>
<td><code>_acme-challenge.yourdomain.com</code></td>
<td>keyAuthorization B</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>注意：</strong> 两个 identifier 使用相同的主机记录但不同的值！</p>
<p>在 <code>challengeCreateFn</code> 中<strong>不能</strong>先清理再添加，否则会导致两条记录互相覆盖。
正确的做法是直接追加 TXT 记录（DNSPod 支持相同主机记录的多条 TXT），
在 <code>challengeRemoveFn</code> 中统一清理。</p>
</blockquote>
<pre><code class="hljs language-javascript">// ✅ 正确做法
challengeCreateFn: async (authz, challenge, keyAuthorization) =&gt; {
  // 不清理，直接添加（两条不同的 TXT 记录共存）
  await dnspod.addTxtRecord(domain, &quot;_acme-challenge&quot;, keyAuthorization)
  await sleep(60000)
}

// ❌ 错误做法（会导致通配符记录被覆盖）
challengeCreateFn: async (authz, challenge, keyAuthorization) =&gt; {
  await dnspod.cleanChallengeRecords(domain, &quot;_acme-challenge&quot;)  // 不要!
  await dnspod.addTxtRecord(domain, &quot;_acme-challenge&quot;, keyAuthorization)
}
</code></pre><h2 id="6-scf-云函数自动部署">6. SCF 云函数自动部署</h2>
<h3 id="6-1-部署脚本-deploy-js">6.1 部署脚本 (deploy.js)</h3>
<pre><code class="hljs language-javascript">async function main() {
  // 1. 打包代码（ZipArchive）
  const archive = new ZipArchive({ zlib: { level: 9 } })
  archive.file(&quot;src/index.js&quot;, { name: &quot;index.js&quot; })
  archive.file(&quot;src/config.js&quot;, { name: &quot;config.js&quot; })
  archive.file(&quot;src/acme.js&quot;, { name: &quot;acme.js&quot; })
  archive.file(&quot;src/dnspod.js&quot;, { name: &quot;dnspod.js&quot; })
  archive.file(&quot;src/cos-store.js&quot;, { name: &quot;cos-store.js&quot; })
  archive.directory(&quot;node_modules/&quot;, &quot;node_modules/&quot;)
  // 注意: SCF 要求入口文件在 zip 根目录

  // 2. 上传到 COS

  // 3. 调用 CreateFunction API
  await callAPI(&quot;scf&quot;, &quot;CreateFunction&quot;, {
    FunctionName: &quot;ssl-auto-renew&quot;,
    Runtime: &quot;Nodejs18.15&quot;,
    Handler: &quot;index.main_handler&quot;,
    Code: { CosBucketName, CosBucketRegion, CosObjectName },
    Timeout: 180,
    MemorySize: 128,
    Environment: { Variables: [...] },
  })

  // 4. 创建定时触发器
  await callAPI(&quot;scf&quot;, &quot;CreateTrigger&quot;, {
    Type: &quot;timer&quot;,
    TriggerDesc: &quot;0 3 1,16 * *&quot;,  // 每月 1日、16日 03:00
    Enable: &quot;OPEN&quot;,
  })
}
</code></pre><h3 id="6-2-部署命令">6.2 部署命令</h3>
<pre><code class="hljs language-bash">SECRET_ID=xxx SECRET_KEY=xxx COS_BUCKET=xxx node deploy.js
</code></pre><h3 id="6-3-scf-函数配置">6.3 SCF 函数配置</h3>
<table>
<thead>
<tr>
<th>配置项</th>
<th>值</th>
</tr>
</thead>
<tbody><tr>
<td>函数名</td>
<td><code>ssl-auto-renew</code></td>
</tr>
<tr>
<td>运行时</td>
<td>Nodejs 18.15</td>
</tr>
<tr>
<td>地域</td>
<td>上海 (ap-shanghai)</td>
</tr>
<tr>
<td>入口</td>
<td><code>index.main_handler</code></td>
</tr>
<tr>
<td>超时</td>
<td>180 秒</td>
</tr>
<tr>
<td>内存</td>
<td>128 MB</td>
</tr>
<tr>
<td>触发器</td>
<td>timer, cron=<code>0 3 1,16 * *</code></td>
</tr>
</tbody></table>
<h3 id="6-4-环境变量">6.4 环境变量</h3>
<table>
<thead>
<tr>
<th>变量</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td><code>SECRET_ID</code></td>
<td>腾讯云 API 密钥 ID（需 DNSPod + COS 权限）</td>
</tr>
<tr>
<td><code>SECRET_KEY</code></td>
<td>腾讯云 API 密钥 Key</td>
</tr>
<tr>
<td><code>COS_BUCKET</code></td>
<td>COS 存储桶名称</td>
</tr>
<tr>
<td><code>COS_REGION</code></td>
<td>COS 地域，默认 <code>ap-guangzhou</code></td>
</tr>
<tr>
<td><code>DOMAIN</code></td>
<td>证书域名，默认 <code>yourdomain.com</code></td>
</tr>
<tr>
<td><code>EMAIL</code></td>
<td>ACME 注册邮箱</td>
</tr>
</tbody></table>
<h2 id="7-本地-tengine-部署">7. 本地 Tengine 部署</h2>
<h3 id="7-1-编译安装-tengine">7.1 编译安装 Tengine</h3>
<pre><code class="hljs language-bash"># 安装编译依赖
sudo apt-get install -y libpcre3-dev libssl-dev zlib1g-dev build-essential

# 下载 Tengine 3.1.0
wget https://tengine.taobao.org/download/tengine-3.1.0.tar.gz
tar xzf tengine-3.1.0.tar.gz
cd tengine-3.1.0

# 编译配置
./configure \
  --prefix=/usr/local/tengine \
  --sbin-path=/usr/local/tengine/sbin/nginx \
  --conf-path=/usr/local/tengine/conf/nginx.conf \
  --with-http_ssl_module \
  --with-http_v2_module \
  --with-stream \
  --with-stream_ssl_module

# 编译安装
make -j$(nproc)
sudo make install
</code></pre><h3 id="7-2-nginx-配置">7.2 Nginx 配置</h3>
<pre><code class="hljs language-nginx">server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    return 301 https://yourdomain.com$request_uri;
}

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    ssl_certificate     /usr/local/tengine/certs/fullchain.pem;
    ssl_certificate_key /usr/local/tengine/certs/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    root /var/www/yourdomain.com;
    index index.html;
}
</code></pre><h3 id="7-3-加载证书">7.3 加载证书</h3>
<pre><code class="hljs language-bash">sudo cp certs/fullchain.pem /usr/local/tengine/certs/
sudo cp certs/privkey.pem /usr/local/tengine/certs/
sudo /usr/local/tengine/sbin/nginx -t     # 验证配置
sudo /usr/local/tengine/sbin/nginx        # 启动
sudo /usr/local/tengine/sbin/nginx -s reload  # 重载
</code></pre><h2 id="8-证书上传到腾讯云-ssl-管理">8. 证书上传到腾讯云 SSL 管理</h2>
<p>通过 <code>ssl.tencentcloudapi.com</code> 的 <code>UploadCertificate</code> API：</p>
<pre><code class="hljs language-javascript">const result = await callAPI(&quot;ssl&quot;, &quot;UploadCertificate&quot;, {
  CertificatePublicKey: fullchainPem,
  CertificatePrivateKey: privkeyPem,
  Alias: &quot;yourdomain.com (*.yourdomain.com)&quot;,
  ProjectId: 0,
})
// 返回 CertificateId: &quot;CERTIFICATE_ID&quot;
</code></pre><p>上传后可在腾讯云控制台 → SSL 证书管理 中查看，可用于 CDN、CLB、API 网关等服务。</p>
<h2 id="9-运行日志示例">9. 运行日志示例</h2>
<h3 id="首次签发">首次签发</h3>
<pre><code>[ssl-auto-renew] 开始执行
[ssl-auto-renew] 环境模式: production(正式)
[ssl-auto-renew] 目标域名: yourdomain.com
[ssl-auto-renew] 检查现存证书...
[ssl-auto-renew] 未找到现存证书，首次签发
[ssl-auto-renew] 准备 ACME 账户密钥...
[ACME] 生成新账户密钥 (RSA 4096)
[COS] ACME 账户密钥已保存
[ssl-auto-renew] 开始 ACME 签发流程...
[ACME] 目标 CA: PRODUCTION (正式)
[ACME] 为 yourdomain.com 签发证书
[ACME] 生成域名密钥对和 CSR（含通配符 *.yourdomain.com）
[ACME] 启动 auto 模式...
[ACME] DNS-01 挑战: yourdomain.com → SOMVYBzEItFCNctq1PYV...
[DNSPod] 添加 TXT 记录: _acme-challenge.yourdomain.com
[ACME] 等待 DNS 传播 (60s)...
[DNSPod] 挑战记录已清理
[ACME] ✅ 证书签发成功!
[ACME]    签发日期: 2026-07-14T02:26:31Z
[ACME]    到期日期: 2026-10-12T02:26:31Z
[COS] 证书已保存: fullchain.pem + privkey.pem
[ssl-auto-renew] ✅ 签发成功!  耗时: 220.8s
</code></pre><h3 id="跳过续签">跳过续签</h3>
<pre><code>[ssl-auto-renew] 开始执行
[ssl-auto-renew] 检查现存证书...
[ssl-auto-renew] 现存证书到期日: 2026-10-12, 剩余 89 天
[ssl-auto-renew] 证书仍有效 (89 天 &gt; 15 天)，无需续签，跳过
</code></pre><h3 id="证书验证">证书验证</h3>
<pre><code class="hljs language-bash"># 检查 SAN（Subject Alternative Name）
openssl x509 -in fullchain.pem -noout -ext subjectAltName
# → DNS:*.yourdomain.com, DNS:yourdomain.com

# 检查有效期
openssl x509 -in fullchain.pem -noout -dates
# → notBefore=Jul 14 01:27:59 2026 GMT
# → notAfter=Oct 12 01:27:58 2026 GMT

# 检查 TLS 握手
openssl s_client -connect localhost:443 -servername yourdomain.com
</code></pre><h2 id="10-维护命令">10. 维护命令</h2>
<h3 id="证书相关">证书相关</h3>
<pre><code class="hljs language-bash"># 从 COS 下载证书
node -e &quot;
  import COS from &#39;cos-nodejs-sdk-v5&#39;;
  const cos = new COS({ SecretId, SecretKey });
  cos.getObject({ Bucket, Key: &#39;ssl/yourdomain.com/fullchain.pem&#39; }, ...);
&quot;

# 更新 Tengine 证书
sudo cp fullchain.pem /usr/local/tengine/certs/
sudo cp privkey.pem /usr/local/tengine/certs/
sudo /usr/local/tengine/sbin/nginx -s reload

# 上传到腾讯云 SSL 管理
node deploy-ssl-manager.js
</code></pre><h3 id="scf-相关">SCF 相关</h3>
<pre><code class="hljs language-bash"># 部署
SECRET_ID=xxx SECRET_KEY=xxx COS_BUCKET=xxx node deploy.js

# 本地测试（staging）
cd scf-ssl &amp;&amp; ENV=staging node src/index.js

# 本地测试（production）
cd scf-ssl &amp;&amp; node src/index.js
</code></pre><h3 id="证书到期管理">证书到期管理</h3>
<table>
<thead>
<tr>
<th>触发条件</th>
<th>行为</th>
</tr>
</thead>
<tbody><tr>
<td>SCF 定时触发</td>
<td>检查 COS 中 meta.json 的 <code>expiresAt</code></td>
</tr>
<tr>
<td>剩余 &gt; 15 天</td>
<td>跳过，等待下次触发器</td>
</tr>
<tr>
<td>剩余 ≤ 15 天</td>
<td>走完整 ACME 流程重新签发</td>
</tr>
<tr>
<td>首次（无 meta）</td>
<td>走完整 ACME 流程签发</td>
</tr>
</tbody></table>
<hr>
<h2 id="附录-a-使用的服务">附录 A：使用的服务</h2>
<table>
<thead>
<tr>
<th>服务</th>
<th>用途</th>
</tr>
</thead>
<tbody><tr>
<td>Let&#39;s Encrypt</td>
<td>ACME CA，签发证书</td>
</tr>
<tr>
<td>DNSPod</td>
<td>域名解析 DNS-01 挑战</td>
</tr>
<tr>
<td>COS（腾讯云对象存储）</td>
<td>证书持久化存储、SCF 代码存储</td>
</tr>
<tr>
<td>SCF（腾讯云云函数）</td>
<td>自动续签执行环境</td>
</tr>
<tr>
<td>SSL 证书管理（腾讯云）</td>
<td>证书统一管理</td>
</tr>
<tr>
<td>Tengine</td>
<td>本地 Web 服务器</td>
</tr>
</tbody></table>
<h2 id="附录-b-依赖的-npm-包">附录 B：依赖的 npm 包</h2>
<table>
<thead>
<tr>
<th>包</th>
<th>版本</th>
<th>用途</th>
</tr>
</thead>
<tbody><tr>
<td><code>acme-client</code></td>
<td>^5.4.0</td>
<td>ACME v2 协议客户端</td>
</tr>
<tr>
<td><code>cos-nodejs-sdk-v5</code></td>
<td>^2.12.6</td>
<td>腾讯云 COS SDK</td>
</tr>
</tbody></table>
<h2 id="附录-c-关键文件路径">附录 C：关键文件路径</h2>
<table>
<thead>
<tr>
<th>文件</th>
<th>路径</th>
</tr>
</thead>
<tbody><tr>
<td>证书链</td>
<td><code>/usr/local/tengine/certs/fullchain.pem</code></td>
</tr>
<tr>
<td>私钥</td>
<td><code>/usr/local/tengine/certs/privkey.pem</code></td>
</tr>
<tr>
<td>COS 证书</td>
<td><code>cos://your-cos-bucket/ssl/yourdomain.com/</code></td>
</tr>
<tr>
<td>本地源码</td>
<td><code>~/Projects/marriott/scf-ssl/</code></td>
</tr>
<tr>
<td>Tengine 配置</td>
<td><code>/usr/local/tengine/conf/nginx.conf</code></td>
</tr>
<tr>
<td>Tengine 日志</td>
<td><code>/var/log/tengine/error.log</code></td>
</tr>
</tbody></table>
]]></content:encoded>
      <pubDate>Tue, 14 Jul 2026 02:52:40 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/ssl</guid>
      <category>linux</category>
      <category>Let's Encrypt</category>
      <category>SCF</category>
    </item>
    <item>
      <title><![CDATA[Nacos Skills 完整速查手册]]></title>
      <link>https://758192.xyz/post/skill</link>
      <description><![CDATA[查看skill]]></description>
      <content:encoded><![CDATA[<p><img src="https://specials-images.forbesimg.com/imageserve/6958cea06455f1737b026327/960x0.jpg" alt="" /></p><h1 id="nacos-skills-完整速查手册">🧰 Nacos Skills 完整速查手册</h1>
<blockquote>
<p>你的 Claude Code 上一共安装了 <strong>192 个 Skills</strong>，按场景分类整理如下。</p>
<p><strong>怎么用这本手册：</strong></p>
<ul>
<li>想做什么事 → 找到对应的分类 → 看看哪个 skill 名最匹配</li>
<li>直接用那句话跟我说就行，我会自动调用对应的 Skill</li>
<li>以下 &quot;触发方式&quot; 列出的关键词就是你直接说出来的话</li>
</ul>
</blockquote>
<hr>
<h2 id="目录">📖 目录</h2>
<ol>
<li><a href="#1-%E5%BC%80%E5%8F%91%E5%B7%A5%E4%BD%9C%E6%B5%81%E6%9C%80%E5%B8%B8%E7%94%A8">开发工作流（最常用）</a></li>
<li><a href="#2-%E4%BB%A3%E7%A0%81%E5%AE%A1%E6%9F%A5--%E8%B4%A8%E9%87%8F">代码审查 &amp; 质量</a></li>
<li><a href="#3-bug-%E8%B0%83%E8%AF%95--%E7%BB%B4%E6%8A%A4">Bug 调试 &amp; 维护</a></li>
<li><a href="#4-%E8%AE%A1%E5%88%92--%E8%AE%BE%E8%AE%A1">计划 &amp; 设计</a></li>
<li><a href="#5-%E6%96%87%E6%A1%A3--%E5%86%99%E4%BD%9C">文档 &amp; 写作</a></li>
<li><a href="#6-%E6%96%87%E4%BB%B6%E7%94%9F%E6%88%90">文件生成（docx/xlsx/pptx/pdf）</a></li>
<li><a href="#7-ai-%E5%9B%BE%E7%89%87%E7%94%9F%E6%88%90">AI 图片生成</a></li>
<li><a href="#8-ai-%E8%A7%86%E9%A2%91%E7%94%9F%E6%88%90">AI 视频生成</a></li>
<li><a href="#9-ai-%E9%9F%B3%E9%A2%91--%E8%AF%AD%E9%9F%B3">AI 音频 &amp; 语音</a></li>
<li><a href="#10-ai-%E5%86%85%E5%AE%B9%E5%88%9B%E4%BD%9C%E7%BB%BC%E5%90%88">AI 内容创作（综合）</a></li>
<li><a href="#11-cloudflare-%E5%85%A8%E5%AE%B6%E6%A1%B6">Cloudflare 全家桶</a></li>
<li><a href="#12-%E5%89%8D%E7%AB%AF--ui-%E8%AE%BE%E8%AE%A1">前端 &amp; UI 设计</a></li>
<li><a href="#13-%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F">微信小程序</a></li>
<li><a href="#14-%E8%90%A5%E9%94%80--%E5%A2%9E%E9%95%BF">营销 &amp; 增长</a></li>
<li><a href="#15-%E5%B9%BF%E5%91%8A--%E5%88%9B%E6%84%8F">广告 &amp; 创意</a></li>
<li><a href="#16-seo--%E6%90%9C%E7%B4%A2">SEO &amp; 搜索</a></li>
<li><a href="#17-%E6%95%B0%E6%8D%AE--%E5%88%86%E6%9E%90">数据 &amp; 分析</a></li>
<li><a href="#18-%E8%AE%BE%E8%AE%A1--%E5%93%81%E7%89%8C">设计 &amp; 品牌</a></li>
<li><a href="#19-skill-%E7%AE%A1%E7%90%86">Skill 管理</a></li>
<li><a href="#20-%E5%B7%A5%E5%85%B7--%E5%85%B6%E4%BB%96">工具 &amp; 其他</a></li>
</ol>
<hr>
<h2 id="1-开发工作流-最常用">1. 开发工作流（最常用）</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式（跟我说这些）</th>
</tr>
</thead>
<tbody><tr>
<td><code>writing-plans</code></td>
<td>写实现计划，复杂功能先出方案再动手</td>
<td>&quot;帮我出个实现计划&quot;、&quot;plan 一下&quot;</td>
</tr>
<tr>
<td><code>brainstorming</code></td>
<td>探索方案/新思路讨论</td>
<td>&quot;我们来讨论一下方案&quot;、&quot;brainstorm&quot;</td>
</tr>
<tr>
<td><code>executing-plans</code></td>
<td>按写好的计划执行</td>
<td>&quot;按计划执行&quot;</td>
</tr>
<tr>
<td><code>test-driven-development</code></td>
<td>TDD 流程，先写测试再写代码</td>
<td>&quot;TDD 走一遍&quot;</td>
</tr>
<tr>
<td><code>subagent-driven-development</code></td>
<td>多子 agent 并行开发</td>
<td>&quot;多个任务并行开发&quot;</td>
</tr>
<tr>
<td><code>finishing-a-development-branch</code></td>
<td>收尾分支工作，决定 merge/PR/cleanup</td>
<td>&quot;收尾这个分支&quot;</td>
</tr>
<tr>
<td><code>verification-before-completion</code></td>
<td>完成前自检确认</td>
<td>&quot;确认一下做完了&quot;、&quot;verify&quot;</td>
</tr>
<tr>
<td><code>using-git-worktrees</code></td>
<td>创建隔离 git worktree，不影响当前工作区</td>
<td>&quot;开个 worktree&quot;、&quot;隔离环境&quot;</td>
</tr>
<tr>
<td><code>dispatching-parallel-agents</code></td>
<td>把 2+ 个独立任务同时做</td>
<td>&quot;这几个任务同时跑&quot;</td>
</tr>
</tbody></table>
<h2 id="2-代码审查-质量">2. 代码审查 & 质量</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>code-review</code></td>
<td>审查当前 diff，找正确性 Bug</td>
<td>&quot;review 代码&quot;、&quot;审查 diff&quot;</td>
</tr>
<tr>
<td><code>requesting-code-review</code></td>
<td>完成功能后请求审查，确认满足要求再合并</td>
<td>&quot;帮我审查一下准备提交&quot;</td>
</tr>
<tr>
<td><code>receiving-code-review</code></td>
<td>收到别人审查意见后，验证是否合理再改</td>
<td>&quot;收到 review 意见了&quot;</td>
</tr>
<tr>
<td><code>simplify</code></td>
<td>简化/重构代码，去除重复</td>
<td>&quot;简化一下这段代码&quot;</td>
</tr>
<tr>
<td><code>py-refactor</code></td>
<td>Python 代码全面重构</td>
<td>&quot;重构这段 Python&quot;</td>
</tr>
<tr>
<td><code>karpathy-guidelines</code></td>
<td>编码规范检查，避免过度设计</td>
<td>&quot;检查编码规范&quot;</td>
</tr>
<tr>
<td><code>security-review</code></td>
<td>安全审查</td>
<td>&quot;做安全审查&quot;</td>
</tr>
</tbody></table>
<h2 id="3-bug-调试-维护">3. Bug 调试 & 维护</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>systematic-debugging</code></td>
<td>系统性分步排查 Bug，不盲目改代码</td>
<td>&quot;排查这个 bug&quot;、&quot;调试一下&quot;</td>
</tr>
<tr>
<td><code>audit</code></td>
<td>审查可访问性/性能/主题/响应式，出评分报告</td>
<td>&quot;给个项目做个审计&quot;</td>
</tr>
<tr>
<td><code>audit-website</code></td>
<td>网站 230+ 条规则全面审计</td>
<td>&quot;审计这个网站&quot;</td>
</tr>
<tr>
<td><code>webapp-testing</code></td>
<td>用 Playwright 测试本地 Web 应用</td>
<td>&quot;测试这个 web 应用&quot;</td>
</tr>
<tr>
<td><code>web-perf</code></td>
<td>分析 Core Web Vitals 等性能指标</td>
<td>&quot;分析性能&quot;、&quot;网站好慢&quot;</td>
</tr>
<tr>
<td><code>harden</code></td>
<td>加固代码：错误处理/国际化/边界情况</td>
<td>&quot;加固一下&quot;、&quot;让代码更健壮&quot;</td>
</tr>
<tr>
<td><code>optimize</code></td>
<td>诊断 UI 性能：加载/渲染/动画/包体积</td>
<td>&quot;优化性能&quot;、&quot;太卡了&quot;</td>
</tr>
</tbody></table>
<h2 id="4-计划-设计">4. 计划 & 设计</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>writing-plans</code></td>
<td>写实现计划（同上）</td>
<td>&quot;写个计划&quot;</td>
</tr>
<tr>
<td><code>brainstorming</code></td>
<td>探索方案（同上）</td>
<td>&quot;讨论方案&quot;</td>
</tr>
<tr>
<td><code>site-architecture</code></td>
<td>规划网站页面层级/导航/URL 结构</td>
<td>&quot;规划网站结构&quot;、&quot;画 sitemap&quot;</td>
</tr>
<tr>
<td><code>storyboard-creation</code></td>
<td>视频/电影分镜设计</td>
<td>&quot;画分镜&quot;</td>
</tr>
</tbody></table>
<h2 id="5-文档-写作">5. 文档 & 写作</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>doc-coauthoring</code></td>
<td>协作写文档/提案/技术规格/决策文档</td>
<td>&quot;一起写个文档&quot;、&quot;写提案&quot;</td>
</tr>
<tr>
<td><code>writing-skills</code></td>
<td>通用写作</td>
<td>&quot;帮我写一段文字&quot;</td>
</tr>
<tr>
<td><code>internal-comms</code></td>
<td>内部沟通/周报/公司邮件</td>
<td>&quot;写周报&quot;、&quot;写内部通知&quot;</td>
</tr>
<tr>
<td><code>technical-blog-writing</code></td>
<td>技术博客，含代码示例</td>
<td>&quot;写技术博客&quot;</td>
</tr>
<tr>
<td><code>case-study-writing</code></td>
<td>B2B 案例研究（STAR 框架）</td>
<td>&quot;写案例研究&quot;</td>
</tr>
<tr>
<td><code>press-release-writing</code></td>
<td>新闻稿（AP 风格/倒金字塔结构）</td>
<td>&quot;写新闻稿&quot;</td>
</tr>
<tr>
<td><code>product-changelog</code></td>
<td>产品更新日志</td>
<td>&quot;写 changelog&quot;、&quot;更新日志&quot;</td>
</tr>
<tr>
<td><code>newsletter-curation</code></td>
<td>邮件新闻通讯策划</td>
<td>&quot;写 newsletter&quot;</td>
</tr>
<tr>
<td><code>product-marketing-context</code></td>
<td>创建/更新产品营销上下文文档</td>
<td>&quot;写产品定位文档&quot;</td>
</tr>
<tr>
<td><code>copywriting</code></td>
<td>营销文案撰写</td>
<td>&quot;写营销文案&quot;、&quot;写广告语&quot;</td>
</tr>
<tr>
<td><code>copy-editing</code></td>
<td>编辑/润色已有营销文案</td>
<td>&quot;润色这段文案&quot;、&quot;proofread&quot;</td>
</tr>
<tr>
<td><code>clarify</code></td>
<td>改进 UX 文案/错误提示/标签/说明</td>
<td>&quot;这个提示写清楚点&quot;</td>
</tr>
<tr>
<td><code>teach-impeccable</code></td>
<td>一次性设置项目设计规范</td>
<td>&quot;设置设计规范&quot;</td>
</tr>
</tbody></table>
<h2 id="6-文件生成">6. 文件生成</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>docx</code></td>
<td>创建/读取/编辑 Word 文档</td>
<td>&quot;生成 Word 文档&quot;</td>
</tr>
<tr>
<td><code>xlsx</code></td>
<td>创建/读取/编辑 Excel 表格</td>
<td>&quot;生成 Excel&quot;、&quot;做个表格&quot;</td>
</tr>
<tr>
<td><code>pptx</code></td>
<td>创建/编辑/读取 PowerPoint 演示文稿</td>
<td>&quot;做个 PPT&quot;、&quot;做 slides&quot;</td>
</tr>
<tr>
<td><code>pdf</code></td>
<td>读取/合并/拆分/提取 PDF</td>
<td>&quot;处理 PDF&quot;、&quot;合并 PDF&quot;</td>
</tr>
</tbody></table>
<h2 id="7-ai-图片生成">7. AI 图片生成</h2>
<p>能调用的 AI 模型：FLUX、Gemini、Grok、Seedream、Reve、Imagen、Qwen 等 50+ 模型</p>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>ai-image-generation</code></td>
<td>通用 AI 图片生成（50+ 模型）</td>
<td>&quot;生成一张图片&quot;、&quot;AI 画图&quot;</td>
</tr>
<tr>
<td><code>flux-image</code></td>
<td>用 FLUX 模型生成图片（Black Forest Labs）</td>
<td>&quot;用 flux 生成图&quot;</td>
</tr>
<tr>
<td><code>nano-banana</code></td>
<td>用 Google Gemini 生成/编辑图片</td>
<td>&quot;用 Gemini 画图&quot;</td>
</tr>
<tr>
<td><code>nano-banana-2</code></td>
<td>Google Gemini 3.1 Flash 图片生成（支持多图输入）</td>
<td>&quot;用 Gemini 3.1 画图&quot;</td>
</tr>
<tr>
<td><code>qwen-image-2</code></td>
<td>用阿里 Qwen-Image-2.0 生成图片</td>
<td>&quot;用通义万相生成图&quot;</td>
</tr>
<tr>
<td><code>qwen-image-2-pro</code></td>
<td>Qwen-Image-2.0-Pro 专业版（文字渲染更强）</td>
<td>&quot;通义万相专业版&quot;</td>
</tr>
<tr>
<td><code>p-image</code></td>
<td>用 Pruna P-Image 生成/编辑图片</td>
<td>&quot;用 Pruna 生成图&quot;</td>
</tr>
<tr>
<td><code>logo-design-guide</code></td>
<td>Logo 设计（含 AI 图生图）</td>
<td>&quot;设计一个 logo&quot;</td>
</tr>
<tr>
<td><code>book-cover-design</code></td>
<td>书籍封面设计</td>
<td>&quot;设计书籍封面&quot;</td>
</tr>
<tr>
<td><code>youtube-thumbnail-design</code></td>
<td>YouTube 缩略图设计</td>
<td>&quot;做 YouTube 封面&quot;</td>
</tr>
<tr>
<td><code>og-image-design</code></td>
<td>Open Graph 社交分享图</td>
<td>&quot;做 OG 分享图&quot;</td>
</tr>
<tr>
<td><code>app-store-screenshots</code></td>
<td>App Store / Google Play 截图</td>
<td>&quot;做应用商店截图&quot;</td>
</tr>
<tr>
<td><code>social-media-carousel</code></td>
<td>社交媒体轮播图</td>
<td>&quot;做轮播图&quot;</td>
</tr>
<tr>
<td><code>product-photography</code></td>
<td>产品摄影/商品图</td>
<td>&quot;拍产品照&quot;</td>
</tr>
<tr>
<td><code>ai-product-photography</code></td>
<td>AI 生成专业产品摄影（电商/商业）</td>
<td>&quot;做电商产品图&quot;</td>
</tr>
<tr>
<td><code>background-removal</code></td>
<td>抠图/去背景</td>
<td>&quot;抠图&quot;、&quot;去掉背景&quot;</td>
</tr>
<tr>
<td><code>image-upscaling</code></td>
<td>图片放大/增强清晰度</td>
<td>&quot;放大图片&quot;、&quot;清晰化&quot;</td>
</tr>
<tr>
<td><code>colorize</code></td>
<td>给设计添加色彩</td>
<td>&quot;加点颜色&quot;、&quot;太素了&quot;</td>
</tr>
</tbody></table>
<h2 id="8-ai-视频生成">8. AI 视频生成</h2>
<p>能调用的模型：Google Veo、Seedance、Wan、Grok Video、HunyuanVideo 等 40+ 模型</p>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>ai-video-generation</code></td>
<td>通用 AI 视频生成（40+ 模型）</td>
<td>&quot;生成一段视频&quot;</td>
</tr>
<tr>
<td><code>google-veo</code></td>
<td>用 Google Veo 生成视频</td>
<td>&quot;用 Veo 生成视频&quot;</td>
</tr>
<tr>
<td><code>p-video</code></td>
<td>用 Pruna P-Video / WAN 生成视频</td>
<td>&quot;用 Pruna 生成视频&quot;</td>
</tr>
<tr>
<td><code>image-to-video</code></td>
<td>图片转视频/让图片动起来</td>
<td>&quot;让这张图动起来&quot;</td>
</tr>
<tr>
<td><code>ai-avatar-video</code></td>
<td>AI 主播/口播视频（OmniHuman）</td>
<td>&quot;做个数字人视频&quot;</td>
</tr>
<tr>
<td><code>ai-marketing-videos</code></td>
<td>营销视频制作（广告/产品演示）</td>
<td>&quot;做营销视频&quot;</td>
</tr>
<tr>
<td><code>talking-head-production</code></td>
<td>虚拟主播/口播视频制作</td>
<td>&quot;做口播视频&quot;</td>
</tr>
<tr>
<td><code>explainer-video-guide</code></td>
<td>产品讲解视频制作指南</td>
<td>&quot;做产品讲解视频&quot;</td>
</tr>
<tr>
<td><code>video-prompting-guide</code></td>
<td>AI 视频提示词编写技巧</td>
<td>&quot;怎么写视频 prompt&quot;</td>
</tr>
<tr>
<td><code>video-ad-specs</code></td>
<td>各平台视频广告规格</td>
<td>&quot;查视频广告规格&quot;</td>
</tr>
</tbody></table>
<h2 id="9-ai-音频-语音">9. AI 音频 & 语音</h2>
<p>能调用的模型：ElevenLabs、Kokoro TTS、DIA、Chatterbox、Higgs 等</p>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>ai-voice-cloning</code></td>
<td>AI 语音生成/TTS（22+ 语音，32 语言）</td>
<td>&quot;生成语音&quot;、&quot;配音&quot;</td>
</tr>
<tr>
<td><code>text-to-speech</code></td>
<td>文字转语音</td>
<td>&quot;文字转语音&quot;、&quot;TTS&quot;</td>
</tr>
<tr>
<td><code>elevenlabs-tts</code></td>
<td>ElevenLabs 高质量 TTS</td>
<td>&quot;用 ElevenLabs 配音&quot;</td>
</tr>
<tr>
<td><code>speech-to-text</code></td>
<td>语音转文字/音频转录</td>
<td>&quot;语音转文字&quot;、&quot;转录&quot;</td>
</tr>
<tr>
<td><code>elevenlabs-stt</code></td>
<td>ElevenLabs 语音转文字（98%+ 准确率）</td>
<td>&quot;用 ElevenLabs 转文字&quot;</td>
</tr>
<tr>
<td><code>elevenlabs-dialogue</code></td>
<td>多角色对话音频（不同声音对话）</td>
<td>&quot;生成多角色对话&quot;</td>
</tr>
<tr>
<td><code>elevenlabs-dubbing</code></td>
<td>视频/音频自动翻译配音（29 种语言）</td>
<td>&quot;视频配音翻译&quot;</td>
</tr>
<tr>
<td><code>elevenlabs-music</code></td>
<td>AI 音乐生成（最长 10 分钟，商用）</td>
<td>&quot;生成背景音乐&quot;</td>
</tr>
<tr>
<td><code>ai-music-generation</code></td>
<td>AI 音乐/歌曲生成（ElevenLabs/Diffrythm/腾讯）</td>
<td>&quot;写首歌&quot;、&quot;生成音乐&quot;</td>
</tr>
<tr>
<td><code>elevenlabs-sound-effects</code></td>
<td>音效生成</td>
<td>&quot;生成音效&quot;</td>
</tr>
<tr>
<td><code>elevenlabs-voice-changer</code></td>
<td>变声器</td>
<td>&quot;变声&quot;</td>
</tr>
<tr>
<td><code>elevenlabs-voice-isolator</code></td>
<td>去噪/人声提取</td>
<td>&quot;去背景噪音&quot;</td>
</tr>
<tr>
<td><code>dialogue-audio</code></td>
<td>多说话人对话音频</td>
<td>&quot;做对话音频&quot;</td>
</tr>
</tbody></table>
<h2 id="10-ai-内容创作-综合">10. AI 内容创作（综合）</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>ai-content-pipeline</code></td>
<td>多步骤创作流水线（图片→视频→配音→配乐）</td>
<td>&quot;做个内容流水线&quot;</td>
</tr>
<tr>
<td><code>ai-podcast-creation</code></td>
<td>AI 播客制作（多角色/背景音乐/片头片尾）</td>
<td>&quot;做个播客&quot;</td>
</tr>
<tr>
<td><code>ai-social-media-content</code></td>
<td>社交平台内容（图/视频/字幕/话题标签）</td>
<td>&quot;做个社交媒体内容&quot;</td>
</tr>
<tr>
<td><code>ai-automation-workflows</code></td>
<td>AI 自动化工作流（批处理/定时任务/事件驱动）</td>
<td>&quot;做自动化流程&quot;</td>
</tr>
<tr>
<td><code>agent-browser</code></td>
<td>浏览器自动化（爬取/填表/截图/录屏）</td>
<td>&quot;自动浏览网页&quot;</td>
</tr>
<tr>
<td><code>browser-use</code></td>
<td>浏览器自动化测试</td>
<td>&quot;浏览器自动化&quot;</td>
</tr>
<tr>
<td><code>remote-browser</code></td>
<td>远程控制浏览器（沙箱环境用）</td>
<td>&quot;远程控制浏览器&quot;</td>
</tr>
<tr>
<td><code>web-search</code></td>
<td>网络搜索和内容提取（Tavily/Exa）</td>
<td>&quot;搜索一下&quot;</td>
</tr>
<tr>
<td><code>ai-rag-pipeline</code></td>
<td>RAG 检索增强生成（搜索+LLM）</td>
<td>&quot;做个 RAG 流程&quot;</td>
</tr>
<tr>
<td><code>deep-research</code></td>
<td>深度多源调研报告</td>
<td>&quot;做个深度调研&quot;</td>
</tr>
<tr>
<td><code>character-design-sheet</code></td>
<td>AI 角色一致性参考图</td>
<td>&quot;设计角色&quot;</td>
</tr>
</tbody></table>
<h2 id="11-cloudflare-全家桶">11. Cloudflare 全家桶</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>cloudflare</code></td>
<td>Cloudflare 全平台（Workers/Pages/D1/R2/AI/WAF）</td>
<td>&quot;Cloudflare 相关&quot;</td>
</tr>
<tr>
<td><code>wrangler</code></td>
<td>Cloudflare Workers CLI 部署和管理</td>
<td>&quot;用 wrangler 部署&quot;</td>
</tr>
<tr>
<td><code>workers-best-practices</code></td>
<td>Workers 最佳实践审查</td>
<td>&quot;检查 Workers 代码&quot;</td>
</tr>
<tr>
<td><code>agents-sdk</code></td>
<td>Cloudflare Agents SDK（有状态 Agent/WebSocket/MCP）</td>
<td>&quot;做 Cloudflare Agent&quot;</td>
</tr>
<tr>
<td><code>durable-objects</code></td>
<td>Durable Objects 开发（多人游戏/聊天室）</td>
<td>&quot;做 Durable Object&quot;</td>
</tr>
<tr>
<td><code>turnstile-spin</code></td>
<td>Cloudflare Turnstile 验证码接入</td>
<td>&quot;接入 Turnstile&quot;</td>
</tr>
<tr>
<td><code>cloudflare-email-service</code></td>
<td>邮件收发（Email Sending + Routing）</td>
<td>&quot;用 Cloudflare 发邮件&quot;</td>
</tr>
</tbody></table>
<h2 id="12-前端-ui-设计">12. 前端 & UI 设计</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>frontend-design</code></td>
<td>高质量前端界面设计</td>
<td>&quot;设计前端界面&quot;</td>
</tr>
<tr>
<td><code>ui-ux-pro-max</code></td>
<td>UI/UX 设计大全（50+ 风格/161 配色/57 字体）</td>
<td>&quot;做 UI 设计&quot;</td>
</tr>
<tr>
<td><code>web-artifacts-builder</code></td>
<td>创建复杂 HTML 组件/Artifact</td>
<td>&quot;做个网页组件&quot;</td>
</tr>
<tr>
<td><code>landing-page-design</code></td>
<td>落地页设计（首屏公式/CTA 心理学）</td>
<td>&quot;设计落地页&quot;</td>
</tr>
<tr>
<td><code>email-design</code></td>
<td>邮件模板设计</td>
<td>&quot;设计邮件模板&quot;</td>
</tr>
<tr>
<td><code>chat-ui</code></td>
<td>Chat UI 组件（容器/消息/输入框/打字指示）</td>
<td>&quot;做聊天界面&quot;</td>
</tr>
<tr>
<td><code>agent-ui</code></td>
<td>AI Agent 对话 UI 组件（含流式/审批/工具）</td>
<td>&quot;做 AI 对话界面&quot;</td>
</tr>
<tr>
<td><code>tools-ui</code></td>
<td>工具调用 UI 组件（进度/审批/结果展示）</td>
<td>&quot;做工具调用界面&quot;</td>
</tr>
<tr>
<td><code>widgets-ui</code></td>
<td>声明式 UI 组件（从 JSON 渲染）</td>
<td>&quot;渲染 UI 组件&quot;</td>
</tr>
<tr>
<td><code>theme-factory</code></td>
<td>主题工厂（10 套预设主题）</td>
<td>&quot;换个主题&quot;</td>
</tr>
<tr>
<td><code>pitch-deck-visuals</code></td>
<td>Pitch Deck 视觉设计</td>
<td>&quot;做 Pitch Deck&quot;</td>
</tr>
<tr>
<td><code>social-media-carousel</code></td>
<td>社交媒体轮播图（已列在图片分类）</td>
<td>&quot;做轮播图&quot;</td>
</tr>
</tbody></table>
<h3 id="ui-微调-优化">UI 微调 & 优化</h3>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>adapt</code></td>
<td>响应式适配/多端适配</td>
<td>&quot;适配移动端&quot;、&quot;响应式&quot;</td>
</tr>
<tr>
<td><code>arrange</code></td>
<td>改进布局/间距/视觉层次</td>
<td>&quot;布局调整一下&quot;、&quot;间距不对&quot;</td>
</tr>
<tr>
<td><code>typeset</code></td>
<td>改进字体/层级/字号/可读性</td>
<td>&quot;字体调一下&quot;、&quot;排版&quot;</td>
</tr>
<tr>
<td><code>polish</code></td>
<td>最终质量检查：对齐/间距/一致性</td>
<td>&quot;润色一下 UI&quot;、&quot;上线前检查&quot;</td>
</tr>
<tr>
<td><code>distill</code></td>
<td>减负设计，去掉不必要的元素</td>
<td>&quot;太复杂了简化&quot;、&quot;做减法&quot;</td>
</tr>
<tr>
<td><code>bolder</code></td>
<td>让设计更大胆/更有冲击力</td>
<td>&quot;再大胆点&quot;、&quot;不够突出&quot;</td>
</tr>
<tr>
<td><code>quieter</code></td>
<td>降低设计强度，更温和</td>
<td>&quot;太刺眼了&quot;、&quot;温和点&quot;</td>
</tr>
<tr>
<td><code>delight</code></td>
<td>增加令人愉悦的细节/惊喜</td>
<td>&quot;加点小惊喜&quot;、&quot;更生动&quot;</td>
</tr>
<tr>
<td><code>animate</code></td>
<td>加动画/微交互</td>
<td>&quot;加点动画&quot;</td>
</tr>
<tr>
<td><code>normalize</code></td>
<td>对齐设计系统规范/间距/主题</td>
<td>&quot;对齐设计规范&quot;</td>
</tr>
<tr>
<td><code>colorize</code></td>
<td>加颜色</td>
<td>&quot;加点颜色&quot;</td>
</tr>
<tr>
<td><code>overdrive</code></td>
<td>炫技级效果（Shader/物理动画/60fps）</td>
<td>&quot;来个炫酷效果&quot;</td>
</tr>
<tr>
<td><code>critique</code></td>
<td>UX 评审打分</td>
<td>&quot;评审这个设计&quot;</td>
</tr>
<tr>
<td><code>extract</code></td>
<td>从现有 UI 中提取可复用的组件</td>
<td>&quot;提取公共组件&quot;</td>
</tr>
<tr>
<td><code>onboard</code></td>
<td>改进引导流程/空状态/首次体验</td>
<td>&quot;优化新手引导&quot;</td>
</tr>
</tbody></table>
<h2 id="13-微信小程序">13. 微信小程序</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>wxa-create-ai-miniprogram</code></td>
<td>从零创建带 AI 能力的微信小程序</td>
<td>&quot;新建一个 AI 小程序&quot;</td>
</tr>
<tr>
<td><code>wxa-ai-mode-dev</code></td>
<td>小程序 AI 开发模式完整指南</td>
<td>&quot;小程序 AI 开发&quot;</td>
</tr>
<tr>
<td><code>wxa-find-skills</code></td>
<td>搜索安装微信小程序 AI Skill</td>
<td>&quot;找小程序 Skill&quot;</td>
</tr>
</tbody></table>
<h2 id="14-营销-增长">14. 营销 & 增长</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>content-strategy</code></td>
<td>内容策略规划</td>
<td>&quot;做内容策略&quot;</td>
</tr>
<tr>
<td><code>content-repurposing</code></td>
<td>内容复用/一鱼多吃（博文→推文→轮播→播客）</td>
<td>&quot;内容复用&quot;、&quot;一鱼多吃&quot;</td>
</tr>
<tr>
<td><code>marketing-ideas</code></td>
<td>营销创意/增长策略</td>
<td>&quot;有什么营销创意&quot;</td>
</tr>
<tr>
<td><code>marketing-psychology</code></td>
<td>营销心理学/认知偏差应用</td>
<td>&quot;用心理学做营销&quot;</td>
</tr>
<tr>
<td><code>launch-strategy</code></td>
<td>产品发布/Go-to-Market 策略</td>
<td>&quot;做发布策略&quot;</td>
</tr>
<tr>
<td><code>product-hunt-launch</code></td>
<td>Product Hunt 发布优化</td>
<td>&quot;上 Product Hunt&quot;</td>
</tr>
<tr>
<td><code>pricing-strategy</code></td>
<td>定价策略/套餐设计</td>
<td>&quot;定个价&quot;、&quot;定价策略&quot;</td>
</tr>
<tr>
<td><code>lead-magnets</code></td>
<td>引流磁石/电子书/模板等</td>
<td>&quot;做引流资料&quot;</td>
</tr>
<tr>
<td><code>free-tool-strategy</code></td>
<td>免费工具营销策略</td>
<td>&quot;做免费工具引流&quot;</td>
</tr>
<tr>
<td><code>referral-program</code></td>
<td>推荐/分销计划</td>
<td>&quot;做推荐计划&quot;</td>
</tr>
<tr>
<td><code>churn-prevention</code></td>
<td>降低流失/挽回流程/失败支付恢复</td>
<td>&quot;减少流失&quot;、&quot;挽回用户&quot;</td>
</tr>
<tr>
<td><code>sales-enablement</code></td>
<td>销售材料/一页纸/演示脚本</td>
<td>&quot;做销售材料&quot;</td>
</tr>
<tr>
<td><code>competitor-teardown</code></td>
<td>竞品拆解分析（SWOT/对比矩阵）</td>
<td>&quot;分析竞品&quot;</td>
</tr>
<tr>
<td><code>competitor-alternatives</code></td>
<td>竞品替代页（&quot;vs&quot; 页面）</td>
<td>&quot;写竞品对比页&quot;</td>
</tr>
<tr>
<td><code>customer-persona</code></td>
<td>客户画像</td>
<td>&quot;做用户画像&quot;</td>
</tr>
<tr>
<td><code>ab-test-setup</code></td>
<td>A/B 测试规划和设计</td>
<td>&quot;做个 A/B 测试&quot;</td>
</tr>
<tr>
<td><code>analytics-tracking</code></td>
<td>分析追踪设置（GA4/GTM/Mixpanel）</td>
<td>&quot;设置数据追踪&quot;</td>
</tr>
<tr>
<td><code>seo-audit</code></td>
<td>SEO 整体审计</td>
<td>&quot;做 SEO 审计&quot;</td>
</tr>
<tr>
<td><code>ai-seo</code></td>
<td>AI 搜索引擎优化（ChatGPT/Perplexity 可见性）</td>
<td>&quot;优化 AI 搜索可见性&quot;</td>
</tr>
</tbody></table>
<h2 id="15-广告-创意">15. 广告 & 创意</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>paid-ads</code></td>
<td>付费广告策略（Google/Meta/LinkedIn/Twitter）</td>
<td>&quot;做广告投放&quot;</td>
</tr>
<tr>
<td><code>ad-creative</code></td>
<td>广告文案/创意批量生成</td>
<td>&quot;写广告文案&quot;</td>
</tr>
<tr>
<td><code>video-ad-specs</code></td>
<td>各平台视频广告规格规范</td>
<td>&quot;视频广告规格&quot;</td>
</tr>
<tr>
<td><code>cold-email</code></td>
<td>B2B 冷邮件/跟进序列</td>
<td>&quot;写冷邮件&quot;</td>
</tr>
<tr>
<td><code>email-sequence</code></td>
<td>邮件序列/滴灌营销</td>
<td>&quot;做邮件序列&quot;</td>
</tr>
</tbody></table>
<h2 id="16-seo-搜索">16. SEO & 搜索</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>seo-audit</code></td>
<td>SEO 审计（技术/OA 页面/元标签）</td>
<td>&quot;SEO 审计&quot;</td>
</tr>
<tr>
<td><code>ai-seo</code></td>
<td>AI 搜索引擎优化</td>
<td>&quot;AI SEO&quot;</td>
</tr>
<tr>
<td><code>schema-markup</code></td>
<td>结构化数据/JSON-LD 标记</td>
<td>&quot;加结构化数据&quot;</td>
</tr>
<tr>
<td><code>seo-content-brief</code></td>
<td>SEO 内容简报（关键词/搜索意图/结构）</td>
<td>&quot;写 SEO 内容简报&quot;</td>
</tr>
<tr>
<td><code>programmatic-seo</code></td>
<td>程序化 SEO 页面批量生成</td>
<td>&quot;做程序化 SEO&quot;</td>
</tr>
<tr>
<td><code>site-architecture</code></td>
<td>网站结构规划（已列在计划分类）</td>
<td>&quot;规划网站结构&quot;</td>
</tr>
</tbody></table>
<h2 id="17-数据-分析">17. 数据 & 分析</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>data-visualization</code></td>
<td>数据可视化（图表选择/配色/标注）</td>
<td>&quot;数据可视化&quot;</td>
</tr>
<tr>
<td><code>analytics-tracking</code></td>
<td>分析追踪设置</td>
<td>&quot;设置追踪&quot;</td>
</tr>
<tr>
<td><code>supabase-postgres-best-practices</code></td>
<td>Postgres 数据库性能优化</td>
<td>&quot;优化数据库&quot;</td>
</tr>
<tr>
<td><code>python-executor</code></td>
<td>沙箱执行 Python（已预装 NumPy/Pandas 等）</td>
<td>&quot;执行 Python 代码&quot;</td>
</tr>
<tr>
<td><code>revops</code></td>
<td>收入运营/客户生命周期管理</td>
<td>&quot;RevOps&quot;</td>
</tr>
<tr>
<td><code>web3-py</code></td>
<td>以太坊区块链交互 Python 库</td>
<td>&quot;Web3 开发&quot;</td>
</tr>
</tbody></table>
<h2 id="18-设计-品牌">18. 设计 & 品牌</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>brand-guidelines</code></td>
<td>Anthropic 品牌风格（色/字体）</td>
<td>&quot;用 Anthropic 品牌风格&quot;</td>
</tr>
<tr>
<td><code>canvas-design</code></td>
<td>视觉艺术创作（海报/PNG/PDF）</td>
<td>&quot;做个海报&quot;</td>
</tr>
<tr>
<td><code>algorithmic-art</code></td>
<td>p5.js 算法艺术生成</td>
<td>&quot;做算法艺术&quot;</td>
</tr>
<tr>
<td><code>open-design</code></td>
<td>Open Design 150+ 品牌规范 + 模板</td>
<td>&quot;用 Open Design&quot;</td>
</tr>
<tr>
<td><code>theme-factory</code></td>
<td>主题预设（已列在 UI 分类）</td>
<td>&quot;换个主题&quot;</td>
</tr>
<tr>
<td><code>logo-design-guide</code></td>
<td>Logo 设计（已列在图片分类）</td>
<td>&quot;设计 Logo&quot;</td>
</tr>
<tr>
<td><code>book-cover-design</code></td>
<td>封面设计（已列在图片分类）</td>
<td>&quot;设计封面&quot;</td>
</tr>
<tr>
<td><code>pitch-deck-visuals</code></td>
<td>Pitch Deck 设计（已列在 UI 分类）</td>
<td>&quot;做 Pitch Deck&quot;</td>
</tr>
</tbody></table>
<h2 id="19-skill-管理">19. Skill 管理</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>skill-creator</code></td>
<td>创建/修改/优化 Skill，运行评估</td>
<td>&quot;创建新 Skill&quot;、&quot;写技能&quot;</td>
</tr>
<tr>
<td><code>writing-skills</code></td>
<td>编写 Skill 描述，优化触发准确性</td>
<td>&quot;优化 Skill 描述&quot;</td>
</tr>
<tr>
<td><code>mcp-builder</code></td>
<td>构建 MCP Server（FastMCP/MCP SDK）</td>
<td>&quot;构建 MCP Server&quot;</td>
</tr>
<tr>
<td><code>find-skills</code></td>
<td>发现/安装 Skill</td>
<td>&quot;找一下有没有 XX 的 skill&quot;</td>
</tr>
<tr>
<td><code>nacos-skill-registry</code></td>
<td>从 Nacos 服务器查找/上传/发布 Skill</td>
<td>&quot;从 Nacos 找 skill&quot;</td>
</tr>
<tr>
<td><code>related-skill</code></td>
<td>推荐相关的 skill</td>
<td>&quot;有什么相关的 skill&quot;</td>
</tr>
</tbody></table>
<h2 id="20-工具-其他">20. 工具 & 其他</h2>
<table>
<thead>
<tr>
<th>Skill 名称</th>
<th>作用</th>
<th>触发方式</th>
</tr>
</thead>
<tbody><tr>
<td><code>claude-api</code></td>
<td>Claude API / Anthropic SDK 开发</td>
<td>&quot;用 Claude API&quot;</td>
</tr>
<tr>
<td><code>prompt-engineering</code></td>
<td>Prompt 工程设计（Chain-of-Thought/Few-shot）</td>
<td>&quot;写 prompt&quot;</td>
</tr>
<tr>
<td><code>mojo-python-interop</code></td>
<td>Mojo 与 Python 互操作</td>
<td>&quot;写 Mojo 调用 Python&quot;</td>
</tr>
<tr>
<td><code>sandbox-sdk</code></td>
<td>安全沙箱应用构建</td>
<td>&quot;做沙箱环境&quot;</td>
</tr>
<tr>
<td><code>remotion-best-practices</code></td>
<td>Remotion（React 视频渲染）最佳实践</td>
<td>&quot;Remotion 开发&quot;</td>
</tr>
<tr>
<td><code>remotion-render</code></td>
<td>Remotion 渲染为 MP4</td>
<td>&quot;渲染 Remotion 视频&quot;</td>
</tr>
<tr>
<td><code>javascript-sdk</code></td>
<td>inference.sh JavaScript/TypeScript SDK</td>
<td>&quot;用 JS SDK 调 AI 模型&quot;</td>
</tr>
<tr>
<td><code>python-sdk</code></td>
<td>inference.sh Python SDK</td>
<td>&quot;用 Python SDK 调 AI 模型&quot;</td>
</tr>
<tr>
<td><code>infsh-cli</code></td>
<td>inference.sh CLI - 调 150+ AI 应用</td>
<td>&quot;用 infsh 命令&quot;</td>
</tr>
<tr>
<td><code>building-inferencesh-apps</code></td>
<td>在 inference.sh 上构建和部署应用</td>
<td>&quot;部署到 inference.sh&quot;</td>
</tr>
<tr>
<td><code>agent-tools</code></td>
<td>运行 150+ AI 应用的命令集合</td>
<td>&quot;运行 AI 应用&quot;</td>
</tr>
<tr>
<td><code>llm-models</code></td>
<td>通过 OpenRouter 访问 100+ LLM</td>
<td>&quot;调大模型&quot;</td>
</tr>
<tr>
<td><code>cloud</code></td>
<td>云相关（通用）</td>
<td>&quot;云相关&quot;</td>
</tr>
<tr>
<td><code>open-source</code></td>
<td>开源相关</td>
<td>&quot;开源相关&quot;</td>
</tr>
<tr>
<td><code>overdrive</code></td>
<td>炫技效果（已列在 UI 分类）</td>
<td>&quot;来个炫技&quot;</td>
</tr>
<tr>
<td><code>using-superpowers</code></td>
<td>会话启动时查找技能</td>
<td>&quot;有什么技能可以用&quot;</td>
</tr>
<tr>
<td><code>slack-gif-creator</code></td>
<td>创建优化 Slack 用的 GIF</td>
<td>&quot;做个 Slack GIF&quot;</td>
</tr>
<tr>
<td><code>template-skill</code></td>
<td>Skill 模板</td>
<td>&quot;创建 Skill 模板&quot;</td>
</tr>
</tbody></table>
<hr>
<h2 id="快速索引">💡 快速索引</h2>
<h3 id="我日常写代码时最可能用到的-top-20">我日常写代码时最可能用到的 Top 20</h3>
<pre><code>writing-plans        → 写计划
brainstorming        → 讨论方案
systematic-debugging → 排查 Bug
code-review          → 审查代码
requesting-code-review → 提交前审查
simplify             → 代码简化
verification-before-completion → 交付前确认
karpathy-guidelines  → 编码规范
doc-coauthoring      → 写文档
py-refactor          → Python 重构
test-driven-development → TDD
subagent-driven-development → 并行开发
finishing-a-development-branch → 收尾分支
internal-comms       → 写周报
frontend-design      → 前端设计
ui-ux-pro-max        → UI 设计
skill-creator        → 创建 Skill
writing-skills       → 写 Skill 描述
mcp-builder          → 构建 MCP Server
using-git-worktrees  → Git 隔离开发
</code></pre><h3 id="关键词-skill-快速查找">关键词 → Skill 快速查找</h3>
<table>
<thead>
<tr>
<th>你想做的事</th>
<th>对应的 Skill</th>
</tr>
</thead>
<tbody><tr>
<td><strong>写计划</strong></td>
<td>→ <code>writing-plans</code></td>
</tr>
<tr>
<td><strong>讨论方案</strong></td>
<td>→ <code>brainstorming</code></td>
</tr>
<tr>
<td><strong>修 Bug</strong></td>
<td>→ <code>systematic-debugging</code></td>
</tr>
<tr>
<td><strong>写代码</strong></td>
<td>→ <code>karpathy-guidelines</code></td>
</tr>
<tr>
<td><strong>审查代码</strong></td>
<td>→ <code>code-review</code> 或 <code>requesting-code-review</code></td>
</tr>
<tr>
<td><strong>准备提交</strong></td>
<td>→ <code>requesting-code-review</code> → <code>verification-before-completion</code></td>
</tr>
<tr>
<td><strong>写文档/周报</strong></td>
<td>→ <code>doc-coauthoring</code> / <code>internal-comms</code></td>
</tr>
<tr>
<td><strong>生成表格/文档/PPT</strong></td>
<td>→ <code>xlsx</code> / <code>docx</code> / <code>pptx</code></td>
</tr>
<tr>
<td><strong>做网页/设计</strong></td>
<td>→ <code>frontend-design</code> / <code>ui-ux-pro-max</code></td>
</tr>
<tr>
<td><strong>做图片/视频</strong></td>
<td>→ <code>ai-image-generation</code> / <code>ai-video-generation</code></td>
</tr>
<tr>
<td><strong>做配音/播客</strong></td>
<td>→ <code>text-to-speech</code> / <code>ai-podcast-creation</code></td>
</tr>
<tr>
<td><strong>做 Cloudflare 开发</strong></td>
<td>→ <code>cloudflare</code></td>
</tr>
<tr>
<td><strong>创建 Skill</strong></td>
<td>→ <code>skill-creator</code></td>
</tr>
<tr>
<td><strong>做微信小程序</strong></td>
<td>→ <code>wxa-create-ai-miniprogram</code></td>
</tr>
<tr>
<td><strong>优化网站 SEO</strong></td>
<td>→ <code>seo-audit</code></td>
</tr>
<tr>
<td><strong>分析竞品</strong></td>
<td>→ <code>competitor-teardown</code></td>
</tr>
<tr>
<td><strong>定营销策略</strong></td>
<td>→ <code>marketing-ideas</code></td>
</tr>
<tr>
<td><strong>写营销文案</strong></td>
<td>→ <code>copywriting</code> / <code>ad-creative</code></td>
</tr>
</tbody></table>
<hr>
<blockquote>
<p>💡 <strong>记住一句话就够了：不用记！</strong></p>
<p>直接跟我说你想做什么，我会自动匹配最合适的 Skill。
这本手册是给你<strong>浏览参考</strong>用的，不是让你背诵的 😊%</p>
</blockquote>
]]></content:encoded>
      <pubDate>Sat, 27 Jun 2026 15:32:48 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/skill</guid>
      <category>AI</category>
      <category>skill</category>
    </item>
    <item>
      <title><![CDATA[Claude Code 常用高效用法]]></title>
      <link>https://758192.xyz/post/claude-use</link>
      <description><![CDATA[Claude Code 常用用法]]></description>
      <content:encoded><![CDATA[<p><img src="https://d8r3hf7cxo9nn.cloudfront.net/cms/2026-04-01/20260401073708_9xy8m0ig.png" alt="" /></p><h1 id="claude-code-高效用法-完整手册">Claude Code 高效用法 — 完整手册</h1>
<blockquote>
<p>解决一个核心问题：<strong>如何减少&quot;一问一答&quot;的低效循环，让 Agent 一次做对事。</strong></p>
</blockquote>
<h2 id="一-为什么聊天效率低">一、为什么聊天效率低</h2>
<h3 id="默认行为的问题">默认行为的问题</h3>
<pre><code>你：帮我修这个 Bug
        ↓
Agent 扫一眼代码 → *猜*一个原因 → 直接改
        ↓
     改错了
        ↓
你：不对，是 xxx 的原因
        ↓
Agent 又 *猜*一个 → 又改
        ↓
     还是不对
        ↓
... 来回 3-5 轮
</code></pre><p><strong>根因：Agent 没有花那 30 秒先彻底搞懂问题就动手了。</strong> &quot;猜 → 改 → 错 → 再猜&quot; 的循环。</p>
<h3 id="解决方案-先出计划-再执行">解决方案：先出计划，再执行</h3>
<pre><code>你：帮我修这个 Bug
        ↓
Agent 先输出一个排查计划（用 systematic-debugging skill）
        ↓
你扫一眼计划 → &quot;方向不对，先检查日志&quot;
        ↓
Agent 修正计划
        ↓
你确认 → Agent 按计划执行 → 一次到位
</code></pre><p><strong>从&quot;改代码 3-5 次&quot;变成&quot;改计划 1 次 + 执行 1 次&quot;</strong>。
计划是文本，改起来 5 秒；代码改错了要回滚重来。</p>
<h2 id="二-强制规则-写在-claude-md-里">二、强制规则：写在 CLAUDE.md 里</h2>
<p>在项目根目录 <code>CLAUDE.md</code> 写入：</p>
<pre><code class="hljs language-markdown">## 效率规则（强制）

遇到以下情况，**必须先输出计划/方案，确认后再执行**：

1. **修 Bug** → 先用 `systematic-debugging` 输出排查步骤
   - 定位根因 → 确认 → 修复
2. **加功能** → 先用 `writing-plans` 输出实现方案
   - 方案 A / 方案 B / 方案 C → 确认用哪个 → 实现
3. **重构** → 先用 `brainstorming` 或 `writing-plans` 输出方案
   - 涉及哪些文件、不改哪些、分几步、怎么验证
4. **复杂变更** → 用 `writing-plans` + `executing-plans`

未经确认就动手改代码 → 驳回。
</code></pre><h3 id="实际对话效果">实际对话效果</h3>
<p>加上这条规则后：</p>
<pre><code>你：战斗系统退出战斗时有 Bug
    ↓
Agent：好的，让我用 systematic-debugging 排查。

排查计划：
1. 检查 B_SEND(fid=14) 发送的结束战斗指令格式
2. 检查服务端 BU 消息的处理
3. 检查客户端 Battle 状态机是否在等待超时

你看这个方向对吗？
    ↓
你：先查第 3 项，我怀疑是状态机没重置
    ↓
Agent：好，直接检查 Battle.ts → 找到问题 → 一次修好
</code></pre><p><strong>总对话轮数：3 轮（确认计划 1 轮 + 确认修正 1 轮 + 执行结果 1 轮）</strong>
<strong>没有规则时：5-8 轮（猜→改→错→再猜→再改...）</strong></p>
<h2 id="三-并行工作-run_in_background">三、并行工作：run_in_background</h2>
<h3 id="什么时候用">什么时候用</h3>
<table>
<thead>
<tr>
<th>场景</th>
<th>效果</th>
</tr>
</thead>
<tbody><tr>
<td>你在改 A 文件，让后台去查 B 文件的 Bug</td>
<td>省掉等你改完 A 再查 B 的时间</td>
</tr>
<tr>
<td>你在调 UI，让后台去跑测试</td>
<td>不用在那干等测试跑完</td>
</tr>
<tr>
<td>你在写客户端，让后台去看服务端代码</td>
<td>两边同时推进</td>
</tr>
</tbody></table>
<h3 id="怎么用">怎么用</h3>
<p>不需要记任何语法，说人话就行：</p>
<pre><code>帮我在后台检查一下 Nacos 上的接口契约和 server/mock.js 有没有对齐
查完了告诉我
</code></pre><p>Claude 会自己决定要不要在后台跑。</p>
<h3 id="内部原理-不用记-了解即可">内部原理（不用记，了解即可）</h3>
<p>Claude Code 会调用 Agent 工具，设置 <code>run_in_background: true</code>，启动一个独立的子会话。子会话有自己的上下文窗口，不占用你当前会话的 token。做完后通知你。</p>
<h3 id="进阶-worktree-隔离">进阶：Worktree 隔离</h3>
<p>如果后台任务也要改代码，用 worktree 隔离，互不干扰：</p>
<pre><code>在后台帮我做一个独立的分支实现登录接口，跟我当前改的代码不冲突
</code></pre><h2 id="四-后台持续监听-monitor">四、后台持续监听：Monitor</h2>
<p>不是所有场景都要后台 Agent 跑一遍就结束。有些场景需要<strong>持续监控</strong>：</p>
<pre><code># 场景：正在构建项目，你想知道什么时候完成
Monitor(
  command=&quot;npm run build 2&gt;&amp;1 | tail -f&quot;,
  description=&quot;等待构建完成&quot;
)
</code></pre><table>
<thead>
<tr>
<th>Monitor vs run_in_background</th>
<th>Monitor</th>
<th>run_in_background</th>
</tr>
</thead>
<tbody><tr>
<td>做一次就结束</td>
<td>❌</td>
<td>✅</td>
</tr>
<tr>
<td>持续监听变化</td>
<td>✅</td>
<td>❌</td>
</tr>
<tr>
<td>每有一条新输出就通知</td>
<td>✅</td>
<td>❌</td>
</tr>
<tr>
<td>例</td>
<td>等构建完成、等测试跑完、等服务器启动</td>
<td>去查一个 Bug、去改一个文件</td>
</tr>
</tbody></table>
<h2 id="五-task-跟踪列表">五、Task 跟踪列表</h2>
<p>Claude Code 内置了任务列表功能，让你看到当前在做什么：</p>
<pre><code>TaskCreate(&quot;修复登录 Bug&quot;)         # 创建一个任务
TaskList()                         # 查看所有任务
TaskUpdate(taskId, status=&quot;done&quot;)  # 标记完成
TaskStop(taskId)                   # 终止任务
</code></pre><h3 id="和-kanban-nacos-的关系">和 Kanban/Nacos 的关系</h3>
<pre><code>如果你需要：                        用：
────────────────────────────────────────────────
当前会话内跟踪进度 → TaskCreate
跨会话任务跟踪     → Hermes Kanban / Nacos 配置
跨机器任务协调     → Nacos 通知（sa-notify）
</code></pre><h2 id="六-claude-md-最佳实践">六、CLAUDE.md 最佳实践</h2>
<h3 id="必须包含的内容">必须包含的内容</h3>
<pre><code class="hljs language-markdown">## 📋 项目信息
- 技术栈、构建工具、目录结构

## 🎯 开发工作流
- 每次任务自动执行：改代码 → 跑测试 → lint → 提交

## 🧰 Skills 映射表
- 什么场景用什么 skill（方便 Agent 匹配）

## 📝 行为约定
- 每次开始先说用了什么 skills
- 修改前先读
- 不随意删除

## ⚡ 效率规则
- 先计划再执行（上面写的强制规则）

## ✅ 检查清单
- 测试通过了？lint 过了？提交了？
</code></pre><h3 id="跨-agent-共享">跨 Agent 共享</h3>
<p>你机器上有 10 个 Agent。想让所有 Agent 读同一套规则：</p>
<pre><code class="hljs language-bash"># Claude Code 读 CLAUDE.md
# Codex 读 AGENTS.md
# Cline 读 .clinerules

# 全部指向同一个文件
ln -sf CLAUDE.md AGENTS.md       # Codex 用
</code></pre><p>已经通过 nacos-cli skill-sync 做好了的配置：</p>
<ul>
<li>Claude Code: 191 skills</li>
<li>Codex: 191 skills（含 AGENTS.md symlink）</li>
<li>Cursor / OpenClaw / Hermes / 其他: 同步完成</li>
</ul>
]]></content:encoded>
      <pubDate>Thu, 25 Jun 2026 03:32:25 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/claude-use</guid>
      <category>AI</category>
      <category>claude</category>
    </item>
    <item>
      <title><![CDATA[Hermes Orchestrator 编排器]]></title>
      <link>https://758192.xyz/post/hermes-orchestrator</link>
      <description><![CDATA[Hermes Orchestrator]]></description>
      <content:encoded><![CDATA[<p><img src="https://i.ytimg.com/vi/EKVRqcpTT6s/maxresdefault.jpg" alt="" /></p><h1 id="hermes-orchestrator-编排器-完整手册">Hermes Orchestrator（编排器）— 完整手册</h1>
<blockquote>
<p>Orchestrator 是 Hermes 的&quot;大脑&quot;，收到复杂任务时自动判断要不要拆解、怎么拆、派发给谁。</p>
</blockquote>
<h2 id="一-为什么需要-orchestrator">一、为什么需要 Orchestrator</h2>
<p>没有 Orchestrator 时，Agent 只有一个会话、一条线：</p>
<pre><code>你：帮我把登录系统做完
     ↓
Agent：好的
     → 先写界面（30s）
     → 再写网络层（30s）
     → 再写服务端（60s）
     总共耗时：120s 串行
     ↓
你：干等着它一个个做
</code></pre><p>有 Orchestrator 时：</p>
<pre><code>你：帮我把登录系统做完
     ↓
Orchestrator：
  &quot;这个任务可以拆成 3 个互不依赖的子任务&quot;
     ↓
  并发派发：
    Worker A → 写界面     (30s)
    Worker B → 写网络层    (30s)    ← 同时进行
    Worker C → 写服务端    (60s)
    总共耗时：60s（最慢的那个）
     ↓
  收集结果 → 汇报
</code></pre><p><strong>时间节省：120s → 60s，而且你不用参与中间过程。</strong></p>
<h2 id="二-orchestrator-的判断逻辑">二、Orchestrator 的判断逻辑</h2>
<p>收到一个任务时，Orchestrator 的工作流程：</p>
<pre><code>收到任务
    ↓
是否开启编排？（orchestrator_enabled）
    ├── 否 → 当作普通任务，自己不拆，单线程做
    └── 是 → 判断能否分解
            ↓
    有 auto_decompose？
    ├── 否 → 等待你用 writing-plans 告诉它怎么拆
    └── 是 → 自动分析任务，决定：
            │
            ├── 太简单（改个变量名）→ 不拆，自己直接做
            ├── 中等（改一个模块）→ 拆 2-3 个子任务
            └── 复杂（重构整个项目）→ 拆多个子任务 + 分批派发
                 ↓
    派发给 worker（最多 max_concurrent_children 个）
</code></pre><h2 id="三-配置详解">三、配置详解</h2>
<pre><code class="hljs language-yaml"># ~/.hermes/config.yaml
delegation:
  orchestrator_enabled: true       # 是否启用编排
                                   # true → 自动拆解大任务
                                   # false → 所有任务单线程做

  max_concurrent_children: 3       # 同时最多几个子任务并行
                                   # 设置太大：API 并发超限
                                   # 设置太小：串行效率低
                                   # 3 是平衡值

  max_async_children: 3            # 后台异步子任务上限
                                   # 和上面的区别：
                                   # concurrent = 你还在对话中
                                   # async = 你切去做别的事了

  max_spawn_depth: 1               # 子任务能不能再拆孙子任务
                                   # 0 = 不拆
                                   # 1 = 子任务不能再拆
                                   # 2 = 子任务可以拆孙子任务
                                   # 防止无限递归

  child_timeout_seconds: 0         # 子任务超时时间
                                   # 0 = 不限时
                                   # 3600 = 1 小时没做完强制终止

  subagent_auto_approve: false     # 子任务操作是否自动批准
                                   # false → 每个子任务操作需要你确认
                                   # true → 子任务自己决定，不打扰你

  max_iterations: 50               # 单个任务的总体迭代次数上限
                                   # 防止死循环

  orphan_timeout: 300              # 子任务失联后多久判定为孤儿（秒）
                                   # 仅 gateway 模式有效
</code></pre><h3 id="和-claude-code-的对比">和 Claude Code 的对比</h3>
<table>
<thead>
<tr>
<th>场景</th>
<th>Hermes Orchestrator</th>
<th>Claude Code</th>
</tr>
</thead>
<tbody><tr>
<td>拆任务</td>
<td>自动拆（auto_decompose）</td>
<td>你手动写 writing-plans</td>
</tr>
<tr>
<td>并发</td>
<td>内建，自动 3 个并发</td>
<td>你手动调 Agent()、parallel()</td>
</tr>
<tr>
<td>结果审查</td>
<td>Verifier 自动审查</td>
<td>你手动 review</td>
</tr>
<tr>
<td>结果合并</td>
<td>Synthesizer 自动合并</td>
<td>你手动合并</td>
</tr>
<tr>
<td>失败重试</td>
<td>自动（failure_limit=2）</td>
<td>你手动处理</td>
</tr>
<tr>
<td>最适场景</td>
<td>说一句话，全自动执行</td>
<td>你参与决策，精细控制</td>
</tr>
</tbody></table>
<h2 id="四-实际使用方式">四、实际使用方式</h2>
<h3 id="方式-1-完全自动-推荐">方式 1：完全自动（推荐）</h3>
<p>什么都不用配置，直接说：</p>
<pre><code>重构战斗系统的核心逻辑，包括状态机、AI、伤害计算
</code></pre><p>Hermes 自动判断能不能拆、怎么拆、并发跑。</p>
<h3 id="方式-2-指定-worker-profiles">方式 2：指定 worker profiles</h3>
<p>如果有多台机器的 Hermes 实例：</p>
<pre><code class="hljs language-yaml"># ~/.hermes/profiles/client.yaml → 客户端开发机器
# ~/.hermes/profiles/server.yaml → 服务端开发机器
</code></pre><pre><code>帮我把登录系统做了，客户端部分用 client profile，服务端部分用 server profile
</code></pre><h3 id="方式-3-和-kanban-swarm-配合">方式 3：和 Kanban Swarm 配合</h3>
<pre><code class="hljs language-bash">hermes kanban swarm &quot;实现登录系统&quot; \
  --worker client:登录界面 \
  --worker server:登录接口 \
  --verifier senior-dev \
  --synthesizer lead-dev
</code></pre><p>Kanban 上会看到 5 张卡片（3 Worker + 1 Verifier + 1 Synthesizer），Orchestrator 控制执行顺序。</p>
<h2 id="五-常见问题">五、常见问题</h2>
<h3 id="q-orchestrator-能编排-claude-code-吗">Q: Orchestrator 能编排 Claude Code 吗？</h3>
<p>不能。Orchestrator 只能在 Hermes 自己的 profiles 之间编排。如果需要编排 Claude Code，需要通过 Nacos 或共享看板的方式间接协作。</p>
<h3 id="q-自动拆错了怎么办">Q: 自动拆错了怎么办？</h3>
<p><code>auto_decompose: true</code> 不一定每次拆得对。可以显式关闭自动拆解：</p>
<pre><code class="hljs language-yaml">auto_decompose: false
</code></pre><p>然后你自己用 writing-plans 输出方案让 Hermes 执行。</p>
<h3 id="q-子任务做一半失败了">Q: 子任务做一半失败了？</h3>
<p>failure_limit=2：同一任务重试 2 次还是失败，就标记 Failed 并通知你。你修复后手动 promote 重新执行。</p>
<h3 id="q-3-个并发不够">Q: 3 个并发不够？</h3>
<pre><code class="hljs language-yaml">max_concurrent_children: 5
</code></pre><p>但注意 API 并发限制，一般 3 是安全值。</p>
<h2 id="六-orchestrator-执行过程-有-kanban-时">六、Orchestrator 执行过程（有 Kanban 时）</h2>
<pre><code>Orchestrator 检测到看板上有新任务
    ↓
Kanban: Todo → In Progress（标记为有人在做）
    ↓
子任务拆分
    ↓
每个子任务创建为独立卡片，建立依赖关系
    ↓
子任务 Ready → worker claim → 执行
    ↓
worker 完成 → Kanban: Done
    ↓
依赖该子任务的其他子任务自动变为 Ready
    ↓
所有子任务 Done
    ↓
父任务 Done
</code></pre>]]></content:encoded>
      <pubDate>Thu, 25 Jun 2026 03:29:31 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/hermes-orchestrator</guid>
      <category>AI</category>
      <category>hermes</category>
    </item>
    <item>
      <title><![CDATA[Hermes 多平台同源]]></title>
      <link>https://758192.xyz/post/hermes-mutil</link>
      <description><![CDATA[Hermes 多平台同源]]></description>
      <content:encoded><![CDATA[<p><img src="https://i.ytimg.com/vi/cw12fxm6yNE/maxresdefault.jpg" alt="" /></p><h1 id="hermes-多平台同源-完整手册">Hermes 多平台同源 — 完整手册</h1>
<blockquote>
<p>同一个 Hermes 实例，同时在 CLI、Telegram、Discord、Slack 等多个平台上工作。所有平台共享同一份会话和记忆。</p>
</blockquote>
<h2 id="一-核心概念">一、核心概念</h2>
<h3 id="什么是-同源">什么是"同源"</h3>
<p>不是&quot;多设备登录同一个账号&quot;，而是：</p>
<pre><code>你在 CLI 里：帮我把登录功能做了
                      ↓
Hermes 开始干活，会话进入&quot;任务进行中&quot;
                      ↓
你合上电脑，出门在地铁上打开 Telegram：
  给 Hermes bot 发：那个登录功能做完了吗？
                      ↓
Hermes 知道你在说哪个任务：
  &quot;还在做，Worker B 在处理网络层，预计 5 分钟&quot;
</code></pre><p><strong>CLI 和 Telegram 看到的是同一个 Hermes、同一个会话、同一个状态。</strong></p>
<h3 id="架构">架构</h3>
<pre><code>┌────────────────────────────────────────────────┐
│              Hermes Gateway                      │
│                                                  │
│   ┌────────┐  ┌──────────┐  ┌──────┐  ┌──────┐ │
│   │  CLI   │  │ Telegram │  │Discord│  │Slack │ │
│   └────┬───┘  └────┬─────┘  └──┬───┘  └──┬───┘ │
│        │           │           │         │      │
│   ┌────┴───────────┴───────────┴─────────┴────┐ │
│   │         统一路由层 + 会话管理               │ │
│   └────────────────┬──────────────────────────┘ │
│                    │                            │
│   ┌────────────────┴──────────────────────────┐ │
│   │      共享记忆 + 共享 Skills + 共享看板      │ │
│   └───────────────────────────────────────────┘ │
└──────────────────────────────────────────────────┘
</code></pre><h2 id="二-配置步骤">二、配置步骤</h2>
<h3 id="第一步-安装-gateway-依赖">第一步：安装 Gateway 依赖</h3>
<p>Gateway 需要长期运行的后台服务。</p>
<pre><code class="hljs language-bash"># 安装为系统服务（macOS launchd / Linux systemd）
hermes gateway install
</code></pre><h3 id="第二步-交互式配置">第二步：交互式配置</h3>
<pre><code class="hljs language-bash">hermes gateway setup
</code></pre><p>这是一个向导，会依次问你：</p>
<pre><code>? 是否启用 Telegram？(y/N)
? 输入 Telegram Bot Token：123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
? 是否启用 Discord？(y/N)
? 输入 Discord Bot Token：...
? 是否启用 Slack？(y/N)
...
</code></pre><p>配置完成后写入 <code>~/.hermes/config.yaml</code>。</p>
<h3 id="第三步-启动-gateway">第三步：启动 Gateway</h3>
<pre><code class="hljs language-bash"># 后台服务（推荐）
hermes gateway start
hermes gateway status      # 确认运行中

# 或前台运行（看实时日志）
hermes gateway run

# 停止
hermes gateway stop
</code></pre><h2 id="三-各平台详细配置">三、各平台详细配置</h2>
<h3 id="telegram">Telegram</h3>
<p>步骤：</p>
<pre><code>1. 打开 Telegram，搜索 @BotFather
2. 发送 /newbot，按提示创建 bot，取名
3. BotFather 给你一个 token：123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
4. hermes gateway setup → 选 Telegram → 填入 token
5. 在 Telegram 里找到你的 bot，点 Start
</code></pre><p>配置项：</p>
<pre><code class="hljs language-yaml">telegram:
  require_mention: false        # 群聊里要不要 @bot 才回复
  free_response_channels: &#39;&#39;     # 哪些频道不用 @ 也能触发
  allowed_chats: &#39;&#39;              # 只允许这些聊天使用（空=全部）
  reactions: false               # 给消息加 emoji 反应
  channel_prompts: {}            # 不同频道设置不同的 prompt
  extra:
    rich_messages: false         # 是否支持富文本（按钮、卡片等）
</code></pre><h3 id="discord">Discord</h3>
<pre><code>1. 去 https://discord.com/developers/applications 创建应用
2. 创建 Bot，复制 token
3. 在 OAuth2 → URL Generator 勾选 bot → 生成邀请链接
4. 把 bot 邀请到你的服务器
5. hermes gateway setup → 选 Discord → 填入 token
</code></pre><p>配置项：</p>
<pre><code class="hljs language-yaml">discord:
  require_mention: true          # 需要 @Hermes 才回复
  auto_thread: true              # 自动建线程（避免刷屏）
  thread_require_mention: false  # 线程里也要 @ 才回复
  history_backfill: true         # 恢复会话时拉取最近消息
  history_backfill_limit: 50     # 拉取最近 50 条
  reactions: true                # 给消息加 emoji
  dm_role_auth_guild: &#39;&#39;         # 仅某个角色的用户能 DM bot
  allowed_channels: &#39;&#39;           # 只在这些频道工作（空=全部）
  server_actions: &#39;&#39;             # 是否允许 bot 管理服务器
  channel_prompts: {}            # 不同频道不同 prompt
</code></pre><h3 id="slack">Slack</h3>
<pre><code class="hljs language-bash"># 先生成 manifest 文件
hermes slack manifest
# 输出一个 JSON，到 Slack API 后台创建 app 时用
</code></pre><p>配置项：</p>
<pre><code class="hljs language-yaml">slack:
  require_mention: true
  free_response_channels: &#39;&#39;     # 这些频道不用 @ 也能触发
  allowed_channels: &#39;&#39;           # 只在这些频道工作
  channel_prompts: {}
</code></pre><h3 id="whatsapp">WhatsApp</h3>
<pre><code class="hljs language-bash">hermes whatsapp                 # WhatsApp 个人号集成
hermes whatsapp-cloud           # WhatsApp Business API
</code></pre><h2 id="四-跨平台使用技巧">四、跨平台使用技巧</h2>
<h3 id="1-cli-和手机交替工作">1. CLI 和手机交替工作</h3>
<pre><code>在 CLI 里发起任务：
  $ hermes chat
  &gt; 重构战斗系统状态机

出门后继续：
  打开 Telegram → 给 bot 发消息
  &quot;做完了吗？&quot;
  → Hermes 回复进度
  &quot;把伤害计算公式改成百分比&quot;
  → Hermes 更新任务规格

回到电脑前：
  CLI 里继续上下文
  $ hermes chat
  # 自动恢复上次会话
</code></pre><h3 id="2-不同平台设不同角色">2. 不同平台设不同角色</h3>
<pre><code class="hljs language-yaml">channel_prompts:
  telegram:
    &quot;Work Chat&quot;: &quot;你是一个简洁的技术助手，只说要点&quot;
    &quot;闲聊&quot;: &quot;你是一个轻松友好的聊天伙伴&quot;
  discord:
    &quot;bug-reports&quot;: &quot;你是一个专业的 QA 工程师&quot;
</code></pre><h3 id="3-手机端快速指令">3. 手机端快速指令</h3>
<p>Telegram/Discord 上给 bot 发简短指令：</p>
<pre><code>/status         → 当前在看板上有什么任务
/tasks          → 我有哪些未完成的任务
/summary        → 当前项目进度摘要
/kanban ls      → 列出看板任务
</code></pre><p>这些是 Hermes 内置的 slash commands，Gateway 自动注册。</p>
<h2 id="五-gateway-管理">五、Gateway 管理</h2>
<pre><code class="hljs language-bash"># 服务管理
hermes gateway start             # 启动
hermes gateway stop              # 停止
hermes gateway restart           # 重启
hermes gateway status            # 查看状态
hermes gateway run               # 前台运行（调试用）
hermes gateway install           # 安装为系统服务
hermes gateway uninstall         # 卸载系统服务

# 查看所有 profiles 的 gateway 状态
hermes gateway list

# Gateway 日志
hermes logs                      # 查看 Hermes 日志
</code></pre><h2 id="六-注意事项">六、注意事项</h2>
<h3 id="gateway-需要长期运行">Gateway 需要长期运行</h3>
<ul>
<li>建议装在服务器或长期开机的机器上</li>
<li>用 <code>hermes gateway install</code> 装成系统服务（自动开机启动）</li>
<li>你的 MacBook 合盖后 Gateway 会断</li>
</ul>
<h3 id="各平台需要的-token">各平台需要的 token</h3>
<table>
<thead>
<tr>
<th>平台</th>
<th>需要什么</th>
</tr>
</thead>
<tbody><tr>
<td>Telegram</td>
<td>Bot Token（从 @BotFather 获取）</td>
</tr>
<tr>
<td>Discord</td>
<td>Bot Token + Application ID</td>
</tr>
<tr>
<td>Slack</td>
<td>App manifest + Bot Token</td>
</tr>
<tr>
<td>WhatsApp</td>
<td>手机号验证 / Business API 账号</td>
</tr>
</tbody></table>
<h3 id="安全建议">安全建议</h3>
<pre><code class="hljs language-yaml">security:
  allow_private_urls: false      # 禁止 bot 访问内网资源
  redact_secrets: true           # 日志中隐藏敏感信息
</code></pre><h2 id="七-常见问题">七、常见问题</h2>
<p><strong>Q: 为什么 Telegram 上发了消息没反应？</strong>
A: Gateway 没运行。检查 <code>hermes gateway status</code>。</p>
<p><strong>Q: CLI 和 Telegram 上看到的状态不一致？</strong>
A: CLI 是直接连接，Telegram 通过 Gateway 转发。检查 Gateway 日志是否有错误：<code>hermes gateway run</code> 看实时输出。</p>
<p><strong>Q: 能不能在飞机上离线用？</strong>
A: 不能。Hermes 需要网络连接 LLM API。Gateway 也需要网络。</p>
]]></content:encoded>
      <pubDate>Thu, 25 Jun 2026 03:28:10 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/hermes-mutil</guid>
      <category>AI</category>
      <category>hermes</category>
    </item>
    <item>
      <title><![CDATA[nacos-cli 使用手册]]></title>
      <link>https://758192.xyz/post/nacos-cli</link>
      <description><![CDATA[nacos-cli 使用手册]]></description>
      <content:encoded><![CDATA[<p><img src="https://opengraph.githubassets.com/9b632c122bf8d436727bdea0c744153b4b0ad6979aa8a94460b563960e04da84/k8scat/nacos-cli" alt="" /></p><h1 id="nacos-cli-使用手册-完整版">nacos-cli 使用手册 — 完整版</h1>
<blockquote>
<p>nacos-cli 是一个命令行工具，管理 Nacos 配置中心 + AI Skills 同步。</p>
</blockquote>
<h2 id="一-安装">一、安装</h2>
<pre><code class="hljs language-bash"># 一键安装（推荐）
curl -fsSL https://nacos.io/nacos-installer.sh | bash -s -- --cli

# 安装后添加 PATH
export PATH=&quot;$HOME/.nacos/bin:$PATH&quot;

# 验证
nacos-cli --help
</code></pre><p><strong>安装后完成的操作：</strong></p>
<ul>
<li><code>~/.nacos/bin/nacos-cli</code> 二进制文件</li>
<li><code>~/.nacos/</code> 配置目录</li>
<li>PATH 已写入 <code>~/.zshrc</code></li>
</ul>
<h2 id="二-profile-管理">二、Profile 管理</h2>
<p>Profile = 环境配置（服务器地址、账号）。可以建多个：dev / prod / home。</p>
<h3 id="创建-profile">创建 Profile</h3>
<pre><code class="hljs language-bash"># 交互式（会打开编辑器让你填）
nacos-cli profile edit home

# 一行命令设置所有字段
nacos-cli profile set home \
  host=192.168.1.108 \
  port=8848 \
  username=nacos \
  password=nacos
</code></pre><p><strong>安全说明：</strong> <code>username</code>、<code>password</code>、<code>accessKey</code>、<code>secretKey</code>、<code>securityToken</code> 这五个字段用 AES-256-GCM 加密后存到文件。加密密钥在 <code>~/.nacos-cli/key</code>（权限 600）。</p>
<h3 id="查看-profile">查看 Profile</h3>
<pre><code class="hljs language-bash">nacos-cli profile list          # 列出所有 profiles
nacos-cli profile show home     # 查看某个 profile 的值
                                # 密码显示为 ******
nacos-cli profile get home host # 只看单个字段
</code></pre><h3 id="切换默认-profile">切换默认 Profile</h3>
<pre><code class="hljs language-bash">nacos-cli profile switch home
# 之后运行 nacos-cli 命令时不加 --profile，默认使用 home
</code></pre><h3 id="删除-profile">删除 Profile</h3>
<pre><code class="hljs language-bash">nacos-cli profile delete dev
</code></pre><h2 id="三-配置管理-config">三、配置管理（Config）</h2>
<p>Nacos 最核心的功能：增删改查配置。</p>
<pre><code class="hljs language-bash"># 读取配置
nacos-cli config-get &lt;dataId&gt; &lt;group&gt;
nacos-cli --profile home config-get sa-contract.yaml GAME

# 写入配置
nacos-cli config-set &lt;dataId&gt; &lt;group&gt;              # 从 stdin 读取
nacos-cli config-set &lt;dataId&gt; &lt;group&gt; --file ./f.yaml  # 从文件读取
echo &#39;content&#39; | nacos-cli config-set &lt;dataId&gt; &lt;group&gt;

# 列出配置
nacos-cli config-list
nacos-cli config-list --data-id sa-*    # 支持通配符过滤
nacos-cli config-list --page 2 --size 10
</code></pre><h3 id="配置优先级">配置优先级</h3>
<pre><code>命令行参数 &gt; --profile &gt; profile switch &gt; 环境变量 &gt; 默认值
</code></pre><h2 id="四-skill-管理">四、Skill 管理</h2>
<h3 id="skill-三阶段生命周期">Skill 三阶段生命周期</h3>
<p>每个 Skill 经历三个阶段才能上线：</p>
<pre><code class="hljs language-bash"># 📤 阶段一：上传草稿（editing）
nacos-cli skill-upload ./my-skill                # 单个
nacos-cli skill-upload --all ./skills/           # 批量

# 📋 阶段二：提交审核（reviewing → reviewed）
nacos-cli skill-review my-skill
# 审核是异步的，状态从 reviewing 变为 reviewed
# 可以查看状态：
nacos-cli skill-describe my-skill

# 🚀 阶段三：发布上线（online）
nacos-cli skill-release my-skill --version 0.0.2
</code></pre><h3 id="查看和下载">查看和下载</h3>
<pre><code class="hljs language-bash">nacos-cli skill-list                              # 列表
nacos-cli skill-list --output json                # JSON 输出（脚本用）
nacos-cli skill-list --name my-skill --page 1 --size 20  # 过滤+分页

nacos-cli skill-describe my-skill                 # 详情+版本历史
nacos-cli skill-describe my-skill --output json

nacos-cli skill-get my-skill                      # 下载到 ~/.skills/
nacos-cli skill-get my-skill -o /custom/path      # 指定路径
</code></pre><h3 id="可见性和标签">可见性和标签</h3>
<pre><code class="hljs language-bash">nacos-cli skill-scope my-skill --scope PUBLIC    # 公开
nacos-cli skill-scope my-skill --scope PRIVATE   # 私有（仅自己可见）
nacos-cli skill-tags my-skill --tags retail,finance  # 标签分类
</code></pre><h2 id="五-skill-sync-跨-agent-同步">五、Skill Sync（跨 Agent 同步）</h2>
<p>Skill Sync 是最常用的功能：<strong>让多个 Agent 共用同一套 Skills</strong>。</p>
<h3 id="原理">原理</h3>
<pre><code>中心仓库（~/.nacos-cli/skill-sync/profiles/&lt;profile&gt;/skill-repo/）
    │
    ├── symlink → ~/.claude/skills/skill-a
    ├── symlink → ~/.cursor/skills/skill-a
    ├── symlink → ~/.codex/skills/skill-a
    └── symlink → ~/.hermes/skills/skill-a
</code></pre><p>磁盘上 Skill 文件只存<strong>一份</strong>在中心仓库，其他 Agent 目录都是 symlink。</p>
<h3 id="本地模式-local-mode">本地模式（Local Mode）</h3>
<p>不需要 Nacos 服务器，本地文件做中心。</p>
<pre><code class="hljs language-bash"># 添加 skill 到 sync
nacos-cli skill-sync add my-skill
nacos-cli skill-sync add --all                    # 全部

# 注册自定义 Agent 目录（nacos-cli 不认识的需要手动加）
nacos-cli skill-sync agent add hermes ~/.hermes/skills
nacos-cli skill-sync agent add workbuddy ~/.workbuddy/skills
nacos-cli skill-sync agent list

# 查看状态
nacos-cli skill-sync status

# 加完所有 skill 后启动守护进程（持续同步）
nacos-cli skill-sync start
</code></pre><h3 id="nacos-模式">Nacos 模式</h3>
<p>有 Nacos 服务器时，以服务器为中央源。</p>
<pre><code class="hljs language-bash">nacos-cli --profile home skill-sync add --all
nacos-cli --profile home skill-sync start
# 启动后自动每 60 秒检查同步状态
# 本地有修改自动上传为 draft
# 远程有更新自动拉取到本地
</code></pre><h3 id="解决冲突">解决冲突</h3>
<pre><code class="hljs language-bash"># 查看冲突
nacos-cli skill-sync status
# 显示 Conflict 状态的 skill

# 以 Nacos 版本为准
nacos-cli skill-sync resolve my-skill --use-nacos

# 以本地某个 Agent 的版本为准
nacos-cli skill-sync resolve my-skill --use-agent codex
</code></pre><h3 id="同步状态说明">同步状态说明</h3>
<table>
<thead>
<tr>
<th>状态</th>
<th>含义</th>
<th>需要操作吗</th>
</tr>
</thead>
<tbody><tr>
<td>Synced</td>
<td>✅ 完全同步（Nacos 版本号一致）</td>
<td>不需要</td>
</tr>
<tr>
<td>Linked</td>
<td>✅ Local mode 已关联</td>
<td>不需要</td>
</tr>
<tr>
<td>Local changes</td>
<td>⚠️ 本地改了但没上传</td>
<td>自动上传（auto-upload）</td>
</tr>
<tr>
<td>Uploaded</td>
<td>📤 草稿已上传</td>
<td>等 review/release</td>
</tr>
<tr>
<td>Upload blocked</td>
<td>🔒 Nacos 上已有草稿</td>
<td>先去服务端处理</td>
</tr>
<tr>
<td>Conflict</td>
<td>❌ 本地和远程不一致</td>
<td>resolve 解决</td>
</tr>
</tbody></table>
<h2 id="六-你本机已完成的配置">六、你本机已完成的配置</h2>
<pre><code class="hljs language-yaml">Nacos 服务器: 192.168.1.108:8848
Profile 名称: home
已同步 Skills: 191 个
已注册 Agent: 10 个
  - codex / claude / cursor
  - openclaw / agents / hermes
  - workbuddy / qclaw / cc-switch / open-design
</code></pre><h3 id="日常使用">日常使用</h3>
<pre><code class="hljs language-bash"># 查看同步状态
nacos-cli --profile home skill-sync status

# 加新 skill
nacos-cli --profile home skill-sync add &lt;skill-name&gt;

# 查看 Nacos 上的 Skills
nacos-cli --profile home skill-list

# 读/写接口契约
nacos-cli --profile home config-get sa-contract.yaml GAME
nacos-cli --profile home config-set sa-contract.yaml GAME --file ./contract.yaml
</code></pre><h2 id="七-交互终端模式">七、交互终端模式</h2>
<p>不想每次都敲 <code>--profile home</code> 前缀？用交互模式：</p>
<pre><code class="hljs language-bash">nacos-cli -s 192.168.1.108:8848 -u nacos -p nacos
</code></pre><p>进入后支持命令：</p>
<pre><code>nacos&gt; help           # 显示所有命令
nacos&gt; server         # 服务器信息
nacos&gt; ns             # 当前命名空间
nacos&gt; ns production  # 切换命名空间
nacos&gt; skill-list     # 列出 skills
nacos&gt; config-list    # 列出配置
nacos&gt; clear          # 清屏
nacos&gt; quit           # 退出
</code></pre><h2 id="八-完整命令速查">八、完整命令速查</h2>
<table>
<thead>
<tr>
<th>分类</th>
<th>命令</th>
<th>操作</th>
</tr>
</thead>
<tbody><tr>
<td>Profile</td>
<td><code>nacos-cli profile edit &lt;name&gt;</code></td>
<td>创建/编辑</td>
</tr>
<tr>
<td>Profile</td>
<td><code>nacos-cli profile switch &lt;name&gt;</code></td>
<td>设为默认</td>
</tr>
<tr>
<td>Profile</td>
<td><code>nacos-cli profile list</code></td>
<td>列出</td>
</tr>
<tr>
<td>Config</td>
<td><code>nacos-cli config-get &lt;d&gt; &lt;g&gt;</code></td>
<td>读配置</td>
</tr>
<tr>
<td>Config</td>
<td><code>nacos-cli config-set &lt;d&gt; &lt;g&gt;</code></td>
<td>写配置</td>
</tr>
<tr>
<td>Skill</td>
<td><code>nacos-cli skill-list</code></td>
<td>列 skill</td>
</tr>
<tr>
<td>Skill</td>
<td><code>nacos-cli skill-upload &lt;path&gt;</code></td>
<td>上传草稿</td>
</tr>
<tr>
<td>Skill</td>
<td><code>nacos-cli skill-review &lt;name&gt;</code></td>
<td>提交审核</td>
</tr>
<tr>
<td>Skill</td>
<td><code>nacos-cli skill-release &lt;name&gt;</code></td>
<td>发布</td>
</tr>
<tr>
<td>Skill</td>
<td><code>nacos-cli skill-get &lt;name&gt;</code></td>
<td>下载</td>
</tr>
<tr>
<td>Sync</td>
<td><code>nacos-cli skill-sync add &lt;name&gt;</code></td>
<td>加入同步</td>
</tr>
<tr>
<td>Sync</td>
<td><code>nacos-cli skill-sync status</code></td>
<td>查看状态</td>
</tr>
<tr>
<td>Sync</td>
<td><code>nacos-cli skill-sync start</code></td>
<td>启动守护</td>
</tr>
<tr>
<td>Sync</td>
<td><code>nacos-cli skill-sync resolve &lt;name&gt;</code></td>
<td>解决冲突</td>
</tr>
<tr>
<td>Agent</td>
<td><code>nacos-cli skill-sync agent add &lt;name&gt; &lt;path&gt;</code></td>
<td>注册 Agent</td>
</tr>
</tbody></table>
]]></content:encoded>
      <pubDate>Thu, 25 Jun 2026 03:26:29 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/nacos-cli</guid>
      <category>AI</category>
      <category>nacos-cli</category>
      <category>nacos</category>
    </item>
    <item>
      <title><![CDATA[Hermes Kanban完整手册]]></title>
      <link>https://758192.xyz/post/hermes-kanban</link>
      <description><![CDATA[Hermes Kanban 看板系统介绍]]></description>
      <content:encoded><![CDATA[<p><img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRjfqotSAkn7LiqB86kOjCJIImZWkEI-VkWYEM8O-Li0OQbgmnL3m9xO7j4&s=10" alt="" /></p><h1 id="hermes-kanban-看板系统-完整手册">Hermes Kanban 看板系统 — 完整手册</h1>
<blockquote>
<p>Kanban 是 &quot;信号卡&quot; 的意思。在 Hermes 里，它是一个 SQLite 任务看板，可以把大需求拆成小卡片，自动或手动派发给 worker 去执行。</p>
</blockquote>
<h2 id="一-kanban-能解决什么问题">一、Kanban 能解决什么问题</h2>
<p>没有看板时，你只能靠对话来推进任务：</p>
<pre><code>你：重构战斗系统
Hermes：好的我要做 A
你：还要做 B
Hermes：好的
你：别忘了 C
...
</code></pre><p>有了看板，任务变成卡片，你一目了然：</p>
<pre><code>看板状态：
╔═══════════════════════════════════════╗
║  待处理          进行中        已完成   ║
║ ┌─────────┐  ┌─────────┐  ┌─────────┐║
║ │战斗系统B │  │战斗系统A │  │战斗系统C │║
║ │(等待中)  │  │(worker1)│  │(已做完)  │║
║ └─────────┘  └─────────┘  └─────────┘║
╚═══════════════════════════════════════╝
</code></pre><h2 id="二-核心概念">二、核心概念</h2>
<h3 id="看板-board">看板（Board）</h3>
<p>每个项目一个看板。比如石器时代项目一个看板，Nacos 配置项目另一个看板。</p>
<h3 id="任务卡片-task">任务卡片（Task）</h3>
<p>一个卡片 = 一件事。卡片有：标题、描述、状态、负责人、优先级、依赖关系。</p>
<h3 id="任务状态流转">任务状态流转</h3>
<pre><code>Scheduled ──→ Todo ──→ Ready ──→ In Progress ──→ Done
   ↑                       ↑            │
   └── 定时触发             └── blocked ─┘
</code></pre><table>
<thead>
<tr>
<th>状态</th>
<th>含义</th>
</tr>
</thead>
<tbody><tr>
<td>Scheduled</td>
<td>定时任务，到时间自动变为 Ready</td>
</tr>
<tr>
<td>Todo</td>
<td>任务已创建，等待人认领</td>
</tr>
<tr>
<td>Ready</td>
<td>可以开始做了（依赖已完成或手动 promote）</td>
</tr>
<tr>
<td>In Progress</td>
<td>有人正在做</td>
</tr>
<tr>
<td>Blocked</td>
<td>被阻塞（依赖另一个任务、等审批等）</td>
</tr>
<tr>
<td>Done</td>
<td>完成</td>
</tr>
<tr>
<td>Archived</td>
<td>归档（保留记录、不显示在看板上）</td>
</tr>
</tbody></table>
<h3 id="依赖关系">依赖关系</h3>
<p>卡片之间可以建立父子依赖：</p>
<pre><code>hermes kanban link 3 1   # 任务 3 依赖任务 1
                          # 任务 1 做完后，任务 3 自动变为 Ready
</code></pre><h2 id="三-配置">三、配置</h2>
<p>不需要改配置也能用，但了解这些可以更好地调优：</p>
<pre><code class="hljs language-yaml"># ~/.hermes/config.yaml 中 kanban 相关配置
kanban:
  dispatch_in_gateway: true        # 让 Gateway 自动派发任务
  dispatch_interval_seconds: 60    # 每 60 秒检查一次看板
  failure_limit: 2                 # 任务失败 2 次就标记失败
  worker_log_rotate_bytes: 2097152 # worker 日志单个文件上限 2MB
  worker_log_backup_count: 1       # 保留 1 份日志备份
  orchestrator_profile: &#39;&#39;         # 编排器使用的 profile
  default_assignee: &#39;&#39;             # 默认指派给谁
  max_in_progress_per_profile: null # 每个人最多同时做几个任务（null=不限）
  auto_decompose: true             # 自动拆分子任务
  auto_decompose_per_tick: 3       # 每次派发最多拆 3 个
  dispatch_stale_timeout_seconds: 14400  # 任务超时 4 小时
</code></pre><h2 id="四-命令行完整参考">四、命令行完整参考</h2>
<h3 id="初始化">初始化</h3>
<pre><code class="hljs language-bash">hermes kanban init
# 创建 ~/.hermes/kanban.db，已有则跳过（幂等操作）
</code></pre><h3 id="看板管理">看板管理</h3>
<pre><code class="hljs language-bash">hermes kanban boards list                       # 列出所有看板
hermes kanban boards create sa-game             # 新建看板
hermes kanban boards switch sa-game             # 切换到某个看板
# 切换后，后续所有命令都针对这个看板操作
</code></pre><h3 id="创建任务">创建任务</h3>
<pre><code class="hljs language-bash"># 交互式：会依次询问标题、描述、优先级等
hermes kanban create

# 一行命令创建
hermes kanban create \
  --title &quot;实现登录接口&quot; \
  --body &quot;客户端写 LoginView
服务端实现 fid=71/72
两端对齐 Nacos 契约&quot;

# 创建 Swarm 编排任务（见下面 Swarm 章节）
hermes kanban swarm &quot;实现登录功能&quot; \
  --worker profile-a:UI:skill-vue \
  --verifier profile-b \
  --synthesizer profile-c
</code></pre><h3 id="查看任务">查看任务</h3>
<pre><code class="hljs language-bash">hermes kanban list          # 列所有任务（标题+ID+状态+负责人）
hermes kanban stats         # 统计板：各状态数量 + 最老的 Ready 任务等待多久
hermes kanban show &lt;id&gt;     # 任务详情（描述、评论、事件历史、日志）
hermes kanban tail &lt;id&gt;     # 实时跟踪某个任务的进展（Ctrl+C 退出）
hermes kanban watch         # 持续看板事件流（新任务、状态变更等实时打印）
</code></pre><h3 id="认领和指派">认领和指派</h3>
<pre><code class="hljs language-bash">hermes kanban claim &lt;id&gt;            # 认领一个 Ready 任务给自己
hermes kanban assign &lt;id&gt; --profile name  # 指派给某个 profile
hermes kanban reassign &lt;id&gt; --profile name  # 改派
hermes kanban reclaim &lt;id&gt;          # 释放当前认领（让别人能认领）
</code></pre><h3 id="状态变更">状态变更</h3>
<pre><code class="hljs language-bash">hermes kanban complete &lt;id&gt;         # 标记完成
hermes kanban block &lt;id&gt;            # 标记阻塞
hermes kanban unblock &lt;id&gt;          # 解除阻塞
hermes kanban promote &lt;id&gt;          # 手动将 Todo/Blocked 提升为 Ready
hermes kanban schedule &lt;id&gt;         # 转为定时任务（需配合时间条件）
hermes kanban archive &lt;id&gt;          # 归档（保留历史但不显示）
</code></pre><h3 id="依赖管理">依赖管理</h3>
<pre><code class="hljs language-bash">hermes kanban link 3 1       # 任务 3 依赖任务 1（1 做完后 3 自动 Ready）
hermes kanban unlink 3 1     # 解除依赖
</code></pre><h3 id="协作">协作</h3>
<pre><code class="hljs language-bash">hermes kanban comment &lt;id&gt; --message &quot;客户端已做完，等待服务端&quot;  # 加备注
hermes kanban log &lt;id&gt;       # 查看 worker 运行日志
hermes kanban runs &lt;id&gt;      # 查看任务的运行历史（每次尝试、耗时、结果摘要）
</code></pre><h3 id="任务分解-高级">任务分解（高级）</h3>
<pre><code class="hljs language-bash">hermes kanban decompose &lt;id&gt;      # 自动拆成子任务，路由到不同 profiles
hermes kanban specify &lt;id&gt;        # 把草稿任务细化为具体规格（标题+body）
</code></pre><h3 id="通知订阅">通知订阅</h3>
<pre><code class="hljs language-bash">hermes kanban notify-subscribe &lt;task-id&gt; &lt;source&gt;   # 订阅任务完成通知
hermes kanban notify-list                            # 列出所有订阅
hermes kanban notify-unsubscribe &lt;task-id&gt; &lt;source&gt;  # 取消订阅
</code></pre><h3 id="swarm-编排模式">Swarm 编排模式</h3>
<p>Swarm 是 Kanban 的高级模式，创建一组 <strong>并行 Worker → Verifier 审查 → Synthesizer 合并</strong> 的任务结构：</p>
<pre><code class="hljs language-bash">hermes kanban swarm &quot;实现登录系统的完整前后端对接&quot; \
  --worker profile-a:登录界面:skill-vue,skill-ui \
  --worker profile-b:登录协议客户端:skill-ts,skill-net \
  --worker profile-c:登录接口服务端:skill-node,skill-api \
  --verifier profile-d \
  --synthesizer profile-e
</code></pre><p>执行时的结构：</p>
<pre><code>             &quot;实现登录系统&quot;
                   │
         Orchestrator 自动分解
                   │
    ┌──────────────┼──────────────┐
    │              │              │
 Worker A      Worker B      Worker C
(登录界面)    (协议客户端)   (服务端接口)
    │              │              │
    └──────────────┼──────────────┘
                   │
              Verifier D
           （审查三端一致性）
                   │
            Synthesizer E
          （合并结果，写回看板）
                   │
              任务完成 ✅
</code></pre><h3 id="清理">清理</h3>
<pre><code class="hljs language-bash">hermes kanban gc     # 清理：归档任务的工作区、旧事件、旧日志
</code></pre><h2 id="五-实际场景用法">五、实际场景用法</h2>
<h3 id="场景-石器时代项目">场景：石器时代项目</h3>
<pre><code class="hljs language-bash"># 1. 初始化
hermes kanban init
hermes kanban boards create sa-game
hermes kanban boards switch sa-game

# 2. 创建任务
hermes kanban create --title &quot;登录模块&quot; \
  --body &quot;客户端 LoginView
服务端 fid=71/72
对齐 Nacos sa-contract.yaml&quot;
hermes kanban create --title &quot;战斗系统&quot; \
  --body &quot;B_SEND/fid=14 客户端发送
B_RECV 服务端 BC/BA/BU 推送&quot;
hermes kanban create --title &quot;地图模块&quot; \
  --body &quot;MC_RECV/fid=37 地图数据
MapRenderer 渲染&quot;

# 3. 看板上现在 3 个任务，都是 Todo
hermes kanban stats
# → Todo: 3 | In Progress: 0 | Done: 0

# 4. 开始做登录模块
hermes kanban claim 1
# → 任务 1 变为 In Progress

# 5. 做完了
hermes kanban comment 1 --message &quot;客户端登录界面完成，等待服务端联调&quot;
hermes kanban complete 1
# → 任务 1 变为 Done
hermes kanban stats
# → Todo: 2 | In Progress: 0 | Done: 1
</code></pre><h2 id="六-局限性">六、局限性</h2>
<ol>
<li><strong>只派发给 Hermes worker</strong> — Kanban 只能派发给 Hermes 自己的 profiles，不能直接派发给 Claude Code 或其他 Agent</li>
<li><strong>SQLite 单机</strong> — kanban.db 是本地 SQLite 文件，不能直接跨机器共享</li>
<li><strong>跨机器方案</strong> — 需要把 kanban.db 放到 git 仓库或共享存储</li>
</ol>
<h2 id="七-常用命令速查">七、常用命令速查</h2>
<table>
<thead>
<tr>
<th>目的</th>
<th>命令</th>
</tr>
</thead>
<tbody><tr>
<td>初始化</td>
<td><code>hermes kanban init</code></td>
</tr>
<tr>
<td>新建看板</td>
<td><code>hermes kanban boards create &lt;name&gt;</code></td>
</tr>
<tr>
<td>切看板</td>
<td><code>hermes kanban boards switch &lt;name&gt;</code></td>
</tr>
<tr>
<td>创建任务</td>
<td><code>hermes kanban create --title &quot;T&quot; --body &quot;B&quot;</code></td>
</tr>
<tr>
<td>列任务</td>
<td><code>hermes kanban list</code></td>
</tr>
<tr>
<td>看统计</td>
<td><code>hermes kanban stats</code></td>
</tr>
<tr>
<td>看详情</td>
<td><code>hermes kanban show &lt;id&gt;</code></td>
</tr>
<tr>
<td>认领</td>
<td><code>hermes kanban claim &lt;id&gt;</code></td>
</tr>
<tr>
<td>指派</td>
<td><code>hermes kanban assign &lt;id&gt; --profile &lt;p&gt;</code></td>
</tr>
<tr>
<td>完成</td>
<td><code>hermes kanban complete &lt;id&gt;</code></td>
</tr>
<tr>
<td>阻塞</td>
<td><code>hermes kanban block &lt;id&gt;</code></td>
</tr>
<tr>
<td>加备注</td>
<td><code>hermes kanban comment &lt;id&gt; --message &quot;...&quot;</code></td>
</tr>
<tr>
<td>实时跟踪</td>
<td><code>hermes kanban tail &lt;id&gt;</code></td>
</tr>
<tr>
<td>建依赖</td>
<td><code>hermes kanban link &lt;child&gt; &lt;parent&gt;</code></td>
</tr>
<tr>
<td>Swarm</td>
<td><code>hermes kanban swarm &quot;目标&quot; --worker ... --verifier ... --synthesizer ...</code></td>
</tr>
</tbody></table>
]]></content:encoded>
      <pubDate>Thu, 25 Jun 2026 03:23:54 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/hermes-kanban</guid>
      <category>AI</category>
      <category>Hermes</category>
      <category>Kanban</category>
    </item>
    <item>
      <title><![CDATA[mihomo深入研究]]></title>
      <link>https://758192.xyz/post/mihomo-2</link>
      <description><![CDATA[mihomo的安装与配置]]></description>
      <content:encoded><![CDATA[<p><img src="https://blog.l3zc.com/2025/07/switch-to-pure-mihomo-kernel/cover_hu_1a93b6f26c22bbfe.webp" alt="" /></p><h1 id="tproxy-透明代理原理">TPROXY 透明代理原理</h1>
<h2 id="什么是-tproxy">什么是 TPROXY</h2>
<p>TPROXY（Transparent Proxy）是 Linux 内核原生的透明代理技术，属于 netfilter 框架的一部分。相比传统的 REDIRECT，TPROXY 在设计上更&quot;干净&quot;，也是对应用层最透明的方案。</p>
<h3 id="核心思路">核心思路</h3>
<p>TPROXY 不是「改目标地址」，而是给内核发一条指令：</p>
<blockquote>
<p>这个包别路由出去，直接交给本机的 7893 端口处理，同时保留所有原始信息。</p>
</blockquote>
<h2 id="跟-redirect-的对比">跟 REDIRECT 的对比</h2>
<h3 id="redirect-你之前用的方式">REDIRECT（你之前用的方式）</h3>
<pre><code>客户端 → 路由器(PREROUTING)
              │
              ▼
      iptables -j REDIRECT --to-ports 7892
              │
              │ 把目标IP:端口改了
              │ (例如: youtube.com:443 → 127.0.0.1:7892)
              ▼
      mihomo 收到连接
              │
              │ 需要用 SO_ORIGINAL_DST 从内核拿回真实目标
              │ (但拿回的是 IP，不知道原始域名)
              ▼
      DNS 污染时：拿到错误 IP → 连错服务器 → 失败
</code></pre><p><strong>本质：内核把包&quot;篡改&quot;了，mihomo 得费力去猜原始目标是什么。</strong></p>
<h3 id="tproxy-现在用的方式">TPROXY（现在用的方式）</h3>
<pre><code>客户端 → 路由器(PREROUTING)
              │
              ▼
      iptables -j TPROXY --on-port 7893 --tproxy-mark 1
              │
              │ 不打改包，只是打个标记(fwmark=1)
              │ 原始目标 IP:端口 原封不动
              ▼
      策略路由：标记 1 的包 → 路由表 100
                                │
                                ▼
                         route add local 0.0.0.0/0 dev lo
                         (所有标记包都交给本机回环接口处理)
                                │
                                ▼
      mihomo 收到连接，直接看到原始目标 IP:端口
      配合 sniffer 读取 TLS SNI → 拿到 www.youtube.com
      即使 IP 被污染，也能从域名识别出正确目标
</code></pre><p><strong>本质：内核不篡改包，只是&quot;拦截并本地投递&quot;，mihomo 看到的和客户端发送的完全一致。</strong></p>
<h2 id="三要素">三要素</h2>
<p>TPROXY 需要三个东西同时配合才能工作：</p>
<h3 id="1-iptables-mangle-表规则">1. iptables mangle 表规则</h3>
<pre><code class="hljs language-bash">iptables -t mangle -A PREROUTING -p tcp -j TPROXY --on-port 7893 --tproxy-mark 1
</code></pre><ul>
<li><code>-t mangle</code>：mangle 表在 PREROUTING 链处理，时机比 nat 表更早</li>
<li><code>--on-port 7893</code>：把匹配的包交给本机 7893 端口</li>
<li><code>--tproxy-mark 1</code>：给包打上标记 1，路由系统根据这个标记做策略路由</li>
</ul>
<h3 id="2-策略路由">2. 策略路由</h3>
<pre><code class="hljs language-bash">ip rule add fwmark 1 table 100
ip route add local 0.0.0.0/0 dev lo table 100
</code></pre><p>这两条的意思是：<strong>凡是打了标记 1 的包，查路由表 100。路由表 100 说：所有地址都是本机地址（local），走回环接口（lo）处理。</strong></p>
<p>没有策略路由的话，内核收到一个目标为 <code>8.8.8.8:443</code> 的包，会试图从 WAN 口发出去，而不是交给本地进程。</p>
<h3 id="3-mihomo-监听-tproxy-端口">3. mihomo 监听 tproxy 端口</h3>
<pre><code class="hljs language-yaml">tproxy-port: 7893
</code></pre><p>mihomo 需要用 IP_TRANSPARENT socket 选项来绑定，这要求：</p>
<ul>
<li>mihomo 以 root 运行（或者有 CAP_NET_ADMIN 权限）</li>
<li>这样才能接收目标不是本机的包</li>
</ul>
<h2 id="关键区别-为什么-tproxy-不怕-dns-污染">关键区别：为什么 TPROXY 不怕 DNS 污染</h2>
<h3 id="redirect-场景">REDIRECT 场景</h3>
<pre><code>客户端 DNS → 阿里 DoH → 69.171.235.22(Facebook)  ← DNS 被污染
客户端 TCP → 69.171.235.22:443
REDIRECT → 改目标为 127.0.0.1:7892
mihomo 拿到 127.0.0.1:7892，用 SO_ORIGINAL_DST 问内核
内核返回 69.171.235.22:443
mihomo 连 69.171.235.22:443 → Facebook 不认识 youtube SNI → 断
</code></pre><h3 id="tproxy-场景">TPROXY 场景</h3>
<pre><code>客户端 DNS → 阿里 DoH → 69.171.235.22(Facebook)  ← 同样污染
客户端 TCP → 69.171.235.22:443
TPROXY → 不打改包，打标记 1 → 策略路由 → 本机 7893
mihomo 直接看到 69.171.235.22:443（原始目标保留着）
mihomo sniffer 嗅探 TLS 握手 → SNI: www.youtube.com
mihomo 用域名规则 → DOMAIN-SUFFIX,youtube.com,🚀 节点选择 → 走代理
mihomo 自己重新解析 youtube.com（通过 Google DNS）→ 正确 IP
代理连到正确的 YouTube 服务器 → 成功
</code></pre><p><strong>即使 IP 被 DNS 污染，TPROXY 保留了完整包信息，sniffer 能从 TLS 层拿到真实域名。</strong></p>
<h2 id="支持-udp-redirect-做不到的">支持 UDP（REDIRECT 做不到的）</h2>
<p>REDIRECT 只能劫持 TCP，因为 UDP 没有连接概念，改了目标地址就没法还原了。</p>
<p>TPROXY 可以劫持 UDP：</p>
<pre><code class="hljs language-yaml">tproxy-port: 7893
</code></pre><p>iptables 加一条 UDP 规则：</p>
<pre><code class="hljs language-bash">iptables -t mangle -A PREROUTING -p udp -j TPROXY --on-port 7893 --tproxy-mark 1
</code></pre><p>mihomo 收到 UDP 包后，可以根据原始目标 IP 做 DNS 防污染、QUIC 代理等。</p>
<h2 id="数据流完整路径">数据流完整路径</h2>
<pre><code>┌─────────────────────────────────────────────────────────────────┐
│                        客户端 (192.168.1.215)                    │
│  浏览器 → youtube.com:443                                      │
└──────────────────────────┬──────────────────────────────────────┘
                           │ 包: src=192.168.1.215:54321
                           │     dst=69.171.235.22:443
                           ▼
┌─────────────────────────────────────────────────────────────────┐
│                   路由器 (i br-lan 进入)                         │
│                                                                 │
│  ① PREROUTING (mangle, 最先处理)                                │
│     └─ MIHEMO 链: 来源 IP=215, TCP → TPROXY --on-port 7893    │
│        包没改，但打上了 fwmark=1                                 │
│                                                                 │
│  ② 路由决策                                                    │
│     └─ fwmark=1 → 查路由表 100                                 │
│        路由表 100: local 0.0.0.0/0 dev lo                       │
│        → &quot;这是本机地址，从 lo 送本地进程&quot;                        │
│                                                                 │
│  ③ mihomo (监听 0.0.0.0:7893, IP_TRANSPARENT)                  │
│     收到包，看到原始目标 69.171.235.22:443                       │
│     └─ sniffer 嗅探 TLS ClientHello → SNI: www.youtube.com     │
│     └─ match DOMAIN-SUFFIX,youtube.com → 🚀 节点选择            │
│     └─ 连接 35.78.84.79:10541 (VLESS Reality) 走代理           │
│                                                                 │
│  ④ 出口 (FORWARD → POSTROUTING → pppoe-wan)                    │
│     代理流量正常路由                                              │
└─────────────────────────────────────────────────────────────────┘
</code></pre><h2 id="总结">总结</h2>
<table>
<thead>
<tr>
<th>特性</th>
<th>REDIRECT</th>
<th>TPROXY</th>
<th>TUN</th>
</tr>
</thead>
<tbody><tr>
<td>原理</td>
<td>改目标地址</td>
<td>标记 + 策略路由</td>
<td>虚拟网卡</td>
</tr>
<tr>
<td>TCP</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>UDP</td>
<td>✗</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>原始地址</td>
<td>需额外获取</td>
<td>自动保留</td>
<td>自动保留</td>
</tr>
<tr>
<td>性能</td>
<td>好</td>
<td>好</td>
<td>略低（用户态）</td>
</tr>
<tr>
<td>配置复杂度</td>
<td>低</td>
<td>中</td>
<td>低</td>
</tr>
<tr>
<td>适合场景</td>
<td>简单 TCP 代理</td>
<td>全面透明代理</td>
<td>全流量接管</td>
</tr>
</tbody></table>
]]></content:encoded>
      <pubDate>Thu, 18 Jun 2026 01:25:32 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/mihomo-2</guid>
      
      <category>mihomo</category>
    </item>
    <item>
      <title><![CDATA[openwrt配置肥猫云科学上网]]></title>
      <link>https://758192.xyz/post/mihomo</link>
      <description><![CDATA[openwrt安装肥猫云]]></description>
      <content:encoded><![CDATA[<p><img src="https://fatcatcloud.org/assets/images/logo.png" alt="" /></p><h2 id="背景">背景</h2>
<p>肥猫云在四月份以后改用了独立的客户端，取代了订阅模式，导致家里的每个设备都要安装客户端，太麻烦了。</p>
<p>官方推出了openwrt的版本，经过分析后，是一个netflow+mihomo的套壳项目。</p>
<h2 id="概述">概述</h2>
<p>肥猫云 Lite 原包 <code>luci-app-fcclient_3.0.7-202605210720_all.ipk</code> 是一个 OpenWrt 路由器上的套壳代理方案，由三个组件叠加而成：</p>
<pre><code>LuCI 管理界面 (Lua)
    ↕
netflow 后端 (Go binary)  ← 套壳层
    ↕
mihomo (Go binary)        ← 代理核心
</code></pre><h2 id="组件拆解">组件拆解</h2>
<h3 id="1-代理核心-mihomo">1. 代理核心：mihomo</h3>
<p><strong>版本:</strong> Mihomo Meta v1.19.27 (linux arm64, go1.26.4)</p>
<p>负责实际的代理功能。以子进程方式运行，由 netflow 后端启动和管理。</p>
<p>运行参数：</p>
<pre><code class="hljs language-bash">mihomo -d /etc/netflow/mihomo -f &lt;临时配置文件&gt;
</code></pre><ul>
<li><code>-d /etc/netflow/mihomo</code> — 工作目录（geoip/geosite 等数据库所在目录）</li>
<li><code>-f &lt;临时文件&gt;</code> — 配置文件由 netflow 动态生成，存放在 <code>/tmp/.nf_*</code></li>
</ul>
<p>关键特性：</p>
<ul>
<li>使用 geodata 模式（<code>geoip.dat</code> + <code>geosite.dat</code>）</li>
<li>支持 VLESS Reality、Shadowsocks、Trojan 等多种协议</li>
<li>自带 RESTful API（外部控制端口 9091）</li>
<li>TUN 模式支持（但默认关闭）</li>
</ul>
<h3 id="2-套壳层-netflow-后端">2. 套壳层：netflow 后端</h3>
<p><strong>位置:</strong> <code>/usr/bin/netflow</code> → 符号链接到 <code>netflow_aarch64</code>（Go binary，UPX 压缩）
<strong>端口:</strong> <code>127.0.0.1:9190</code>
<strong>技术:</strong> Go 语言，编译为静态链接二进制，UPX 压缩减少体积</p>
<h4 id="职责">职责</h4>
<table>
<thead>
<tr>
<th>功能</th>
<th>实现方式</th>
</tr>
</thead>
<tbody><tr>
<td>管理 mihomo</td>
<td>作为父进程启动/停止 mihomo，监控其运行状态</td>
</tr>
<tr>
<td>订阅更新</td>
<td>调用 v2board 面板 API 获取节点列表</td>
</tr>
<tr>
<td>配置生成</td>
<td>解密订阅数据 → 生成 mihomo 配置文件 → 写入临时文件</td>
</tr>
<tr>
<td>数据加密</td>
<td>使用 <code>/etc/netflow/.dev_salt</code> 做 AES 加密</td>
</tr>
<tr>
<td>iptables 管理</td>
<td>理论上负责设置透明代理规则，但实际未生效</td>
</tr>
</tbody></table>
<h4 id="配置存储">配置存储</h4>
<pre><code>UCI 配置 (/etc/config/netflow)
  ├── netflow.config      # 基本设置（端口、模式等）
  └── netflow.v2board     # 订阅登录信息（加密存储）

文件存储
  ├── /etc/netflow/config.yaml     # mihomo 配置文件（或临时文件）
  ├── /etc/netflow/mihomo/         # mihomo 工作目录
  │   ├── mihomo                   # mihomo 二进制
  │   ├── geoip.dat                # IP 地理数据库
  │   ├── geosite.dat              # 域名分类数据库
  │   └── config.yaml              # 启动后的配置文件
  ├── /etc/netflow/v2board/
  │   └── subscribe.enc            # 加密的订阅数据
  └── /etc/netflow/.dev_salt       # 设备专属加密盐
</code></pre><h4 id="加密机制">加密机制</h4>
<pre><code>安装时生成 .dev_salt（32 字节随机数 → 64 位 hex）
    ↓
UCI 中存储的密码/api_url → ENC:base64(AES(salt, 明文))
    ↓
订阅数据 → subscribe.enc → AES(salt, 节点JSON)
</code></pre><h3 id="3-管理界面-luci">3. 管理界面：LuCI</h3>
<p><strong>位置:</strong></p>
<ul>
<li>控制器: <code>/usr/lib/lua/luci/controller/netflow.lua</code></li>
<li>视图: <code>/usr/lib/lua/luci/view/netflow/main.htm</code></li>
<li>权限: <code>/usr/share/rpcd/acl.d/luci-app-fcclient.json</code></li>
</ul>
<p>负责在 OpenWrt 的 Web 管理界面提供操作面板，功能包括：</p>
<ul>
<li>输入/修改订阅账号</li>
<li>查看连接状态</li>
<li>切换代理模式</li>
<li>触发订阅更新</li>
</ul>
<p>RPC 权限文件定义了后端 API 的访问控制。</p>
<h2 id="数据流">数据流</h2>
<h3 id="订阅更新流程">订阅更新流程</h3>
<pre><code>用户点击&quot;更新订阅&quot;
    ↓
LuCI → RPC → netflow 后端 (127.0.0.1:9190)
    ↓
netflow 解密 UCI 中的 api_url / token
    ↓
调用 v2board 面板 API → 获取节点列表
    ↓
AES 加密 → 写入 subscribe.enc
    ↓
解密 subscribe.enc → 生成 mihomo config.yaml
    ↓
重启 mihomo 进程
</code></pre><h3 id="代理数据流">代理数据流</h3>
<pre><code>局域网设备
    ↓ (iptables REDIRECT / TPROXY / 手动设代理)
mihomo (7890 mixed / 7892 redir)
    ↓ (规则匹配: GEOIP / GEOSITE / DOMAIN-SUFFIX)
代理策略组 (手动 / url-test / fallback)
    ↓ (VLESS Reality 加密隧道)
节点服务器 (35.78.84.79)
    ↓
目标网站
</code></pre><h2 id="v2board-api-对接">v2board API 对接</h2>
<p>netflow 后端实现了 v2board 面板的客户端协议：</p>
<ul>
<li><code>api/v1/passport/auth/login</code> — 登录获取 token</li>
<li><code>api/v1/user/getSubscribe</code> — 获取订阅元信息</li>
<li><code>api/v1/client/subscribe</code> — 获取实际节点配置</li>
</ul>
<h2 id="关键设计缺陷">关键设计缺陷</h2>
<h3 id="1-iptables-规则未正确配置">1. iptables 规则未正确配置</h3>
<p>prerm 脚本中有 iptables 清理命令，证明 netflow 应该管理透明代理：</p>
<pre><code class="hljs language-bash">iptables -t nat -D PREROUTING -j NETFLOW
iptables -t nat -D PREROUTING -p dport 53 -j REDIRECT --to-ports 7874
</code></pre><p>但实际运行时 nat 表是空的。可能是：</p>
<ul>
<li>netflow 二进制的 UPX 压缩导致这段代码被省略了</li>
<li>或者此功能在当前版本已移除</li>
</ul>
<h3 id="2-订阅加密导致配置不透明">2. 订阅加密导致配置不透明</h3>
<p><code>subscribe.enc</code> 使用设备专属 salt 加密，导致：</p>
<ul>
<li>无法直接查看/修改节点配置</li>
<li>无法将订阅数据迁移到另一台设备</li>
<li>mihomo 的配置文件必须由 netflow 生成，无法直接编辑</li>
</ul>
<h3 id="3-节点域名依赖特殊-dns">3. 节点域名依赖特殊 DNS</h3>
<p>节点使用的域名（如 <code>a002-lite01.llguangli25n.com</code>）在公共 DNS 中不存在，只有通过 fcclient App 的 TUN/fake-ip 系统才能解析。路由器上的 mihomo 无法直接解析这些域名。</p>
<h2 id="关键发现">关键发现</h2>
<h3 id="订阅系统分析">订阅系统分析</h3>
<ul>
<li><strong>Mac App</strong> 使用新 API: <code>fcapi.apiv2.a047.com/api/v1/passport/auth/login</code></li>
<li><strong>路由器</strong> 使用旧 v2board API，返回过期节点</li>
<li>订阅元数据 API: <code>user/getSubscribe?auth_data=JWT</code> 返回套餐/UUID/订阅地址</li>
<li>实际节点配置服务器: <code>fcsblka.fcsubcn.cc:2096</code>（定制 TLS，无法从外部连接）</li>
</ul>
<h3 id="找到真实节点-ip">找到真实节点 IP</h3>
<ul>
<li>通过 Mac 的 <code>netstat</code> 观察到所有节点都连接到 <code>35.78.84.79</code></li>
<li>路由器 ping 该 IP 可达 (~41ms)</li>
</ul>
<h2 id="获取jwt-token">获取jwt token</h2>
<pre><code>完整的过程在这里：

# ============================================
# 第1步：登录获取 JWT令牌
# ============================================
curl -X POST &quot;https://fcapi.apiv2.a047.com/api/v1/passport/auth/login&quot; \
  -H &quot;User-Agent: fcclient/3.0.7&quot; \
  -H &quot;Content-Type: application/json&quot; \
  -d &#39;{&quot;email&quot;:&quot;xxxxxxxxx@gmail.com&quot;,&quot;password&quot;:&quot;xxxxxxx&quot;}&#39;

# 返回结果：
{
  &quot;status&quot;: &quot;success&quot;,
  &quot;data&quot;: {
    &quot;token&quot;: &quot;dW4h1Z87kQQ9vDHrMxxxxxxxxxxxx&quot;,
    &quot;auth_data&quot;: &quot;eyJ0eXAiOiJKV1QiLCJhxxxxxxxxx.eyJpZCI6MTkyOTg3LCJxxxxxxxxxzdmMGVkMGVhM2VkOWZmYWM0ZWU0NjgyZWFiOTI0NjYifQ.7WpSShJZjn2a3IvVxxxxxxxxiC79LMqLnO1xZw&quot;
  }
}

# ============================================
# 第2步：获取订阅元信息（套餐/UUID/流量/订阅地址）
# ============================================
# 用上一步返回的 auth_data 作为 query 参数
curl &quot;https://fcapi.apiv2.a047.com/api/v1/user/getSubscribe?auth_data=eyJ0eXAiOiJKV1QixxxxxxxJ9.eyJpZCI6MTkyOTg3LCJzZXNzxxxxxxxxGVkMGVhM2VkOWZmYWM0ZWU0xxxxxx0NjYifQ.7WpSShJZjn2a3IvVxxxxxxxxC79LMqLnO1xZw&quot; \
  -H &quot;User-Agent: fcclient/3.0.7&quot;

# 返回结果：
{
  &quot;status&quot;: &quot;success&quot;,
  &quot;data&quot;: {
    &quot;plan_id&quot;: 5,
    &quot;token&quot;: &quot;dW4h1Z87kQQ9vDHrMgzrmDBlGrDIo3Gm&quot;,
    &quot;expired_at&quot;: 1825999987,
    &quot;u&quot;: 394537826,
    &quot;d&quot;: 7870981628,
    &quot;transfer_enable&quot;: 64424509440,
    &quot;email&quot;: &quot;xxxxxxxxx@gmail.com&quot;,
    &quot;uuid&quot;: &quot;5xxxxx7-cxxx2-4xxe-89xxx7-67dbbxxxx2&quot;,
    &quot;plan&quot;: { &quot;name&quot;: &quot;肥猫小包&quot;, &quot;id&quot;: 5, &quot;transfer_enable&quot;: 60 },
    &quot;subscribe_url&quot;: &quot;https://fcsblka.fcsubcn.cc:2096/api/v1/client/subscribe?token=dW4h1Z87kQQ9vDHrMgzrmDBlGrDIo3Gm&quot;,
    &quot;reset_day&quot;: 24
  }
}
</code></pre><h2 id="最终方案">最终方案</h2>
<h3 id="架构">架构</h3>
<pre><code>去掉netflow，直接使用mihomo作为透明代理

局域网设备 → 路由器 (iptables 透明代理) → mihomo → 35.78.84.79 (VLESS Reality 节点) → 外网
</code></pre><h3 id="配置要点">配置要点</h3>
<ul>
<li><strong>60 个 VLESS Reality 节点</strong> (HK20/TW10/SG10/JP10/US10)，全部指向 <code>35.78.84.79</code></li>
<li><strong>策略组</strong>: 🚀 节点选择(手动) / 自动选择(url-test) / 故障转移(fallback)</li>
<li><strong>规则</strong>: .cn/GEOIP 直连，google/github/youtube 走代理，其余兜底代理</li>
<li><strong>Web 面板</strong>: <code>http://192.168.1.1/yacd/</code> (Yacd-meta)，API 密钥 <code>netflow_secret</code></li>
</ul>
<h2 id="部署的文件">部署的文件</h2>
<table>
<thead>
<tr>
<th>文件</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td><code>/etc/netflow/mihomo/config.yaml</code></td>
<td>mihomo 主配置 (60 节点 + 策略 + 规则)</td>
</tr>
<tr>
<td><code>/etc/init.d/mihomo</code></td>
<td>procd 服务管理脚本 (开机自启 + 崩溃重启)</td>
</tr>
<tr>
<td><code>/root/tproxy.sh</code></td>
<td>iptables 透明代理启停脚本 (start/stop/status)</td>
</tr>
<tr>
<td><code>/root/watchdog.sh</code></td>
<td>看门狗 (cron 每分钟执行，挂了自动重启，重启失败则关 iptables)</td>
</tr>
<tr>
<td><code>/etc/rc.local</code></td>
<td>开机启动 mihomo + 透明代理</td>
</tr>
<tr>
<td><code>/www/yacd/</code></td>
<td>Yacd-meta Web 面板 (可通过 <code>http://192.168.1.1/yacd/</code> 访问)</td>
</tr>
</tbody></table>
<h2 id="命令速查">命令速查</h2>
<pre><code class="hljs language-bash"># mihomo 服务管理
/etc/init.d/mihomo start|stop|restart|status
/etc/init.d/mihomo enable|disable  # 开机自启

# 透明代理
/root/tproxy.sh start|stop|status|restart

# 查看日志
logread -e mihomo
cat /tmp/netflow_mihomo.log

# Web 面板
http://192.168.1.1/yacd/   # 连接 192.168.1.1:9091 密钥 netflow_secret

# 添加规则 (sed 免 vi)
sed -i &#39;/DOMAIN-SUFFIX,google.com/i\  - DOMAIN-SUFFIX,baidu.com,DIRECT&#39; /etc/netflow/mihomo/config.yaml
/etc/init.d/mihomo restart
</code></pre><h2 id="容错机制">容错机制</h2>
<table>
<thead>
<tr>
<th>场景</th>
<th>结果</th>
</tr>
</thead>
<tbody><tr>
<td>mihomo 崩溃</td>
<td>procd 自动重启 + 看门狗兜底</td>
</tr>
<tr>
<td>mihomo 重启失败</td>
<td>看门狗自动关闭 iptables，网络恢复</td>
</tr>
<tr>
<td>DNS 失效</td>
<td>dnsmasq 直接响应，不依赖 mihomo DNS</td>
</tr>
</tbody></table>
<h2 id="待办-风险">待办/风险</h2>
<ul>
<li><code>35.78.84.79</code> 可能是动态 IP，失效后需重新获取</li>
<li>订阅数据无法直接获取，依赖 Mac 抓包找 IP</li>
<li>dnsmasq 上游配置 <code>127.0.0.1#7874</code> 如需调整</li>
</ul>
<h2 id="对比-我们最终的路由器方案">对比：我们最终的路由器方案</h2>
<table>
<thead>
<tr>
<th>方面</th>
<th>肥猫云原版</th>
<th>我们的方案</th>
</tr>
</thead>
<tbody><tr>
<td>mihomo 管理</td>
<td>netflow 后端生成临时配置</td>
<td>直接编辑固定配置文件</td>
</tr>
<tr>
<td>透明代理</td>
<td>依赖 netflow 设置 iptables</td>
<td>独立 tproxy.sh 脚本管理 TPROXY</td>
</tr>
<tr>
<td>规则管理</td>
<td>通过订阅数据固定生成</td>
<td>rule-provider / GEOSITE 自动更新</td>
</tr>
<tr>
<td>设备白名单</td>
<td>无内置支持</td>
<td>TPROXY 按源 IP 限制</td>
</tr>
<tr>
<td>日志管理</td>
<td>无独立配置</td>
<td>procd init 脚本托管</td>
</tr>
<tr>
<td>看门狗</td>
<td>无</td>
<td>cron 脚本监控+自动恢复</td>
</tr>
<tr>
<td>容错</td>
<td>mihomo 挂了 iptables 还劫持</td>
<td>看门狗自动关闭 TPROXY</td>
</tr>
<tr>
<td>DNS</td>
<td>无独立防污染</td>
<td>sniffer + force-dns-mapping</td>
</tr>
<tr>
<td>Web 面板</td>
<td>LuCI 界面</td>
<td>Yacd + external-controller</td>
</tr>
</tbody></table>
]]></content:encoded>
      <pubDate>Wed, 17 Jun 2026 18:39:05 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/mihomo</guid>
      
      <category>mihomo</category>
      <category>openwrt</category>
    </item>
    <item>
      <title><![CDATA[用AI手搓一个Blog]]></title>
      <link>https://758192.xyz/post/blog</link>
      <description><![CDATA[Claude+Open Desgin+CloudFlare]]></description>
      <content:encoded><![CDATA[<p><img src="https://storage.googleapis.com/zenn-user-upload/ad2226fa90cb-20251127.png" alt="" /></p><h1 id="my-edge-blog-项目文档">my-edge-blog 项目文档</h1>
<h2 id="概览">概览</h2>
<p>一个部署在 Cloudflare Workers 上的个人博客系统，纯服务端渲染（SSR），支持多主题切换、管理后台、Markdown 渲染、暗色模式等。<strong>共 5,495 行代码。</strong></p>
<hr>
<h2 id="技术栈">技术栈</h2>
<table>
<thead>
<tr>
<th>层级</th>
<th>技术</th>
</tr>
</thead>
<tbody><tr>
<td>框架</td>
<td>Hono v4 — 轻量 Web 框架，JSX 模板引擎</td>
</tr>
<tr>
<td>运行时</td>
<td>Cloudflare Workers — 边缘计算平台</td>
</tr>
<tr>
<td>数据库</td>
<td>Cloudflare D1 (SQLite) — 文章/设置存储</td>
</tr>
<tr>
<td>对象存储</td>
<td>Cloudflare R2 — 图片上传和管理</td>
</tr>
<tr>
<td>KV</td>
<td>Cloudflare KV — Admin Session 持久化</td>
</tr>
<tr>
<td>Markdown</td>
<td>marked + marked-highlight + highlight.js</td>
</tr>
<tr>
<td>部署</td>
<td>Wrangler CLI</td>
</tr>
<tr>
<td>类型</td>
<td>TypeScript (JSX: <code>react-jsx</code> + <code>hono/jsx</code>)</td>
</tr>
<tr>
<td>CSS</td>
<td>原生 CSS + CSS 变量实现主题/暗色</td>
</tr>
</tbody></table>
<hr>
<h2 id="完整功能清单">完整功能清单</h2>
<h3 id="前端-4-套主题">前端（4 套主题）</h3>
<table>
<thead>
<tr>
<th>功能</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>4 套独立主题</td>
<td>LoveIt (详细), PaperMod (简洁), Minimal (衬线留白), Tech (深色科技)</td>
</tr>
<tr>
<td>首页文章卡片</td>
<td>分页展示，支持置顶帖子</td>
</tr>
<tr>
<td>文章详情页</td>
<td>标题/日期/分类/标签/阅读时间/字数统计/浏览计数</td>
</tr>
<tr>
<td>Markdown 渲染</td>
<td>语法高亮 (highlight.js)、代码复制按钮、TOC 标题锚点</td>
</tr>
<tr>
<td>侧边栏目录 (TOC)</td>
<td>文章页左侧可折叠目录，手机端浮动按钮</td>
</tr>
<tr>
<td>搜索功能</td>
<td>全文搜索 + 关键词高亮 + 摘要回退</td>
</tr>
<tr>
<td>标签系统</td>
<td>标签列表页、按标签筛选</td>
</tr>
<tr>
<td>分类系统</td>
<td>分类列表页、按分类筛选</td>
</tr>
<tr>
<td>归档页</td>
<td>按年月分组，显示文章计数</td>
</tr>
<tr>
<td>关于页</td>
<td>Markdown 编辑器的自由内容</td>
</tr>
<tr>
<td>暗色模式</td>
<td>localStorage 持久化 + 系统偏好检测，图片暗调</td>
</tr>
<tr>
<td>阅读进度条</td>
<td>顶部彩色进度条</td>
</tr>
<tr>
<td>分享按钮</td>
<td>微博 / X (Twitter) 一键分享</td>
</tr>
<tr>
<td>上一篇/下一篇导航</td>
<td>文章底部相邻文章链接</td>
</tr>
<tr>
<td>RSS 订阅</td>
<td><code>/feed.xml</code> 含全文 <code>&lt;content:encoded&gt;</code></td>
</tr>
<tr>
<td>Sitemap</td>
<td><code>/sitemap.xml</code> 含分页、lastmod</td>
</tr>
<tr>
<td>robots.txt</td>
<td>动态生成，含正确域名 Sitemap URL</td>
</tr>
<tr>
<td>JSON-LD</td>
<td>Schema.org Article 类型结构化数据</td>
</tr>
<tr>
<td>Open Graph</td>
<td>OG title/description/url/image/type/site_name, article:published_time/modified_time, robots, Twitter cards</td>
</tr>
<tr>
<td>访问者统计</td>
<td>浏览量计数</td>
</tr>
<tr>
<td>无障碍</td>
<td>ARIA 标签、:focus-visible 全局样式、:prefers-reduced-motion、::selection 样式</td>
</tr>
<tr>
<td>无 404 破损</td>
<td>图片 onerror 隐藏、搜索内容为空回退</td>
</tr>
</tbody></table>
<h3 id="管理后台">管理后台</h3>
<table>
<thead>
<tr>
<th>功能</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>Session 认证</td>
<td>KV 持久化 session + HttpOnly cookie</td>
</tr>
<tr>
<td>登录速率限制</td>
<td>5 次/5 分钟，基于 IP</td>
</tr>
<tr>
<td>文章 CRUD</td>
<td>新建/编辑/删除/批量删除</td>
</tr>
<tr>
<td>Markdown 编辑器</td>
<td>工具栏、分屏预览、拖拽上传、字数+阅读时间统计</td>
</tr>
<tr>
<td>主题切换</td>
<td>4 套主题一键切换</td>
</tr>
<tr>
<td>站点设置</td>
<td>标题/描述/页脚/GitHub/邮箱/头像/RSS 标题等</td>
</tr>
<tr>
<td>图片上传 R2</td>
<td>5MB 限制 + 类型白名单 + 速率限制 (20次/60秒)</td>
</tr>
<tr>
<td>置顶帖子管理</td>
<td>添加/移除置顶，排序</td>
</tr>
<tr>
<td>社交链接管理</td>
<td>添加/编辑/删除</td>
</tr>
<tr>
<td>关于页编辑</td>
<td>Markdown 编辑器</td>
</tr>
<tr>
<td>数据导出</td>
<td>JSON 格式导出所有内容</td>
</tr>
</tbody></table>
<h3 id="安全措施">安全措施</h3>
<table>
<thead>
<tr>
<th>措施</th>
<th>实现</th>
</tr>
</thead>
<tbody><tr>
<td>XSS 防护</td>
<td>所有用户输入经 <code>e()</code> HTML 实体转义</td>
</tr>
<tr>
<td>安全头</td>
<td>X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy</td>
</tr>
<tr>
<td>CORS 控制</td>
<td>仅允许 github.io / localhost / 127.0.0.1</td>
</tr>
<tr>
<td>上传校验</td>
<td>文件类型白名单 + 大小限制</td>
</tr>
<tr>
<td>路径穿越</td>
<td><code>/assets/*</code> 过滤 <code>..</code> / <code>/</code> / <code>\0</code></td>
</tr>
<tr>
<td>CDN SRI</td>
<td>highlight.js 加载带 <code>integrity</code> + <code>crossorigin</code></td>
</tr>
<tr>
<td>认证</td>
<td>KV session + HttpOnly + SameSite=Lax + Secure cookie</td>
</tr>
</tbody></table>
<hr>
<h2 id="数据库表结构">数据库表结构</h2>
<pre><code class="hljs language-sql">-- 文章表
posts (id, slug, title, summary, content, cover_image, tags, category,
       published, created_at, updated_at, view_count)

-- 评论表（已建表，待开发）
comments (id, post_id, author, content, created_at)

-- 置顶帖子
pinned_posts (id, post_id, sort_order, created_at)

-- 站点设置
settings (key, value)

-- 社交链接
social_links (id, label, url, icon, sort_order, created_at)
</code></pre><hr>
<h2 id="源码结构">源码结构</h2>
<pre><code>my-edge-blog/
├── src/
│   ├── index.ts        (143行) 入口、认证路由、安全中间件
│   ├── routes.ts       (273行) 公开路由（首页/文章/搜索/RSS/sitemap/robots）
│   ├── admin.ts        (310行) 管理后台 CRUD + 主题/设置/上传
│   ├── db.ts           (392行) D1 查询封装 + 内存缓存层
│   ├── auth.ts         (19行) 共享认证模块
│   ├── marked.ts       (46行) Marked 配置 + 自定义渲染器
│   └── templates.tsx   (2147行) 所有 JSX 模板（4主题 Layout + Page）
├── public/
│   ├── common.css      (577行) 共享样式
│   ├── theme-loveit.css     (451行)
│   ├── theme-papermod.css   (354行)
│   ├── theme-minimal.css    (345行)
│   ├── theme-tech.css       (438行)
│   └── robots.txt
├── migrations/ (6 个 SQL 迁移文件)
├── schema.sql          (完整建表 SQL)
├── wrangler.jsonc      (Cloudflare Workers 配置)
├── tsconfig.json       (TypeScript 配置)
└── package.json        (依赖配置)
</code></pre><hr>
<h2 id="路由表">路由表</h2>
<table>
<thead>
<tr>
<th>路由</th>
<th>方法</th>
<th>功能</th>
</tr>
</thead>
<tbody><tr>
<td><code>GET /</code></td>
<td>public</td>
<td>首页（第1页）</td>
</tr>
<tr>
<td><code>GET /page/:page</code></td>
<td>public</td>
<td>分页</td>
</tr>
<tr>
<td><code>GET /post/:slug</code></td>
<td>public</td>
<td>文章详情</td>
</tr>
<tr>
<td><code>GET /tags</code></td>
<td>public</td>
<td>标签列表</td>
</tr>
<tr>
<td><code>GET /tag/:tag</code></td>
<td>public</td>
<td>按标签筛选（分页）</td>
</tr>
<tr>
<td><code>GET /category/:category</code></td>
<td>public</td>
<td>按分类筛选（分页）</td>
</tr>
<tr>
<td><code>GET /about</code></td>
<td>public</td>
<td>关于页</td>
</tr>
<tr>
<td><code>GET /search?q=</code></td>
<td>public</td>
<td>搜索</td>
</tr>
<tr>
<td><code>GET /archives</code></td>
<td>public</td>
<td>归档页</td>
</tr>
<tr>
<td><code>GET /feed.xml</code></td>
<td>public</td>
<td>RSS</td>
</tr>
<tr>
<td><code>GET /sitemap.xml</code></td>
<td>public</td>
<td>Sitemap</td>
</tr>
<tr>
<td><code>GET /robots.txt</code></td>
<td>public</td>
<td>Robots</td>
</tr>
<tr>
<td><code>GET /assets/*</code></td>
<td>public</td>
<td>R2 图片代理</td>
</tr>
<tr>
<td><code>GET /admin</code></td>
<td>auth</td>
<td>后台首页</td>
</tr>
<tr>
<td><code>GET /admin/login</code></td>
<td>auth</td>
<td>登录页</td>
</tr>
<tr>
<td><code>POST /admin/login</code></td>
<td>auth</td>
<td>登录提交</td>
</tr>
<tr>
<td><code>POST /admin/logout</code></td>
<td>auth</td>
<td>登出</td>
</tr>
<tr>
<td><code>GET/POST /admin/new</code></td>
<td>auth</td>
<td>新建文章</td>
</tr>
<tr>
<td><code>GET/POST /admin/edit/:id</code></td>
<td>auth</td>
<td>编辑文章</td>
</tr>
<tr>
<td><code>POST /admin/delete/:id</code></td>
<td>auth</td>
<td>删除文章</td>
</tr>
<tr>
<td><code>POST /admin/bulk-delete</code></td>
<td>auth</td>
<td>批量删除</td>
</tr>
<tr>
<td><code>POST /admin/upload</code></td>
<td>auth</td>
<td>图片上传</td>
</tr>
<tr>
<td><code>GET/POST /admin/theme</code></td>
<td>auth</td>
<td>主题管理</td>
</tr>
<tr>
<td><code>GET/POST /admin/pinned</code></td>
<td>auth</td>
<td>置顶管理</td>
</tr>
<tr>
<td><code>GET/POST /admin/settings</code></td>
<td>auth</td>
<td>站点设置</td>
</tr>
<tr>
<td><code>GET/POST /admin/about</code></td>
<td>auth</td>
<td>关于页编辑</td>
</tr>
<tr>
<td><code>GET/POST /admin/social</code></td>
<td>auth</td>
<td>社交链接管理</td>
</tr>
<tr>
<td><code>GET /admin/export</code></td>
<td>auth</td>
<td>数据导出</td>
</tr>
</tbody></table>
<hr>
<h2 id="部署文档-从头手搓">部署文档（从头手搓）</h2>
<h3 id="前置条件">前置条件</h3>
<pre><code class="hljs language-bash"># 1. 安装 Node.js 18+
# 2. 安装 Wrangler CLI
npm install -g wrangler
# 3. 登录 Cloudflare
wrangler login
</code></pre><h3 id="项目初始化">项目初始化</h3>
<pre><code class="hljs language-bash"># 1. 创建项目目录
mkdir my-edge-blog &amp;&amp; cd my-edge-blog

# 2. 初始化项目
npm init -y
npm install hono marked marked-highlight highlight.js
npm install -D wrangler @types/node

# 3. 配置 tsconfig.json
{
  &quot;compilerOptions&quot;: {
    &quot;jsx&quot;: &quot;react-jsx&quot;,
    &quot;jsxImportSource&quot;: &quot;hono/jsx&quot;,
    &quot;target&quot;: &quot;ESNext&quot;,
    &quot;module&quot;: &quot;ESNext&quot;,
    &quot;moduleResolution&quot;: &quot;Bundler&quot;,
    &quot;strict&quot;: true,
    &quot;skipLibCheck&quot;: true,
    &quot;lib&quot;: [&quot;ESNext&quot;]
  }
}
</code></pre><h3 id="创建-cloudflare-资源">创建 Cloudflare 资源</h3>
<pre><code class="hljs language-bash"># 1. 创建 D1 数据库
wrangler d1 create notion-d1

# 2. 创建 R2 存储桶
wrangler r2 bucket create notion-r2

# 3. 创建 KV namespace
wrangler kv:namespace create ADMIN_KV

# 4. 设置管理员密码
wrangler secret put ADMIN_PASSWORD
</code></pre><h3 id="配置-wrangler-jsonc">配置 wrangler.jsonc</h3>
<p>将 <code>d1_databases</code>、<code>r2_buckets</code>、<code>kv_namespaces</code> 中的 ID 替换为上一步创建的值。</p>
<h3 id="数据库初始化">数据库初始化</h3>
<pre><code class="hljs language-bash">wrangler d1 execute notion-d1 --file schema.sql
# 再依次执行所有 migrations/*.sql
</code></pre><h3 id="本地开发">本地开发</h3>
<pre><code class="hljs language-bash">npm run dev
# 启动 http://localhost:8787
# 连接生产资源: npx wrangler dev --remote
</code></pre><h3 id="部署">部署</h3>
<pre><code class="hljs language-bash">npm run deploy
# = wrangler deploy --minify
</code></pre><hr>
<h2 id="项目亮点">项目亮点</h2>
<ul>
<li><strong>零外部 Frontend 框架</strong> — 纯 Hono JSX SSR</li>
<li><strong>零 CSS 框架</strong> — 原生 CSS + 自定义属性</li>
<li><strong>全站 SSR</strong> — 首屏极速</li>
<li><strong>多主题架构</strong> — 通过 <code>Layout()</code> 分发函数，新增主题只需加一个函数</li>
<li><strong>内存缓存层</strong> — 60s TTL 减少 D1 查询次数</li>
<li><strong>边缘部署</strong> — Cloudflare Workers 全球 300+ 节点</li>
</ul>
]]></content:encoded>
      <pubDate>Fri, 12 Jun 2026 09:57:12 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/blog</guid>
      <category>linux</category>
      <category>AI</category>
      <category>blog</category>
      <category>Hono</category>
      <category>Cloudflare</category>
    </item>
    <item>
      <title><![CDATA[git教程]]></title>
      <link>https://758192.xyz/post/git</link>
      <description><![CDATA[记录一些git的知识]]></description>
      <content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676758975296/5b0c9a21-bff6-46a9-b3e6-c51f202151c1.png" alt="" /></p><h1 id="git-新手教程">Git 新手教程</h1>
<hr>
<h2 id="一-基础概念">一、基础概念</h2>
<h3 id="git-是什么">Git 是什么？</h3>
<p>Git 是<strong>分布式版本控制系统</strong>。每次提交（commit）就像游戏存档，随时可以回档。</p>
<h3 id="三个区域">三个区域</h3>
<pre><code>工作区 (Working Directory)    →    暂存区 (Staging Area)    →    仓库 (Repository)
   你正在编辑的文件              git add 之后               git commit 之后
</code></pre><h3 id="文件状态">文件状态</h3>
<table>
<thead>
<tr>
<th>状态</th>
<th>含义</th>
</tr>
</thead>
<tbody><tr>
<td>untracked</td>
<td>Git 不跟踪的新文件</td>
</tr>
<tr>
<td>modified</td>
<td>已跟踪但被修改了</td>
</tr>
<tr>
<td>staged</td>
<td>已 add，等待 commit</td>
</tr>
<tr>
<td>committed</td>
<td>已提交到本地仓库</td>
</tr>
</tbody></table>
<hr>
<h2 id="二-安装与初始配置">二、安装与初始配置</h2>
<pre><code class="hljs language-bash"># 安装（Mac 推荐 brew）
brew install git

# 必做的全局配置
git config --global user.name &quot;你的名字&quot;
git config --global user.email &quot;你的邮箱&quot;

# 查看配置
git config --list

# 设置默认分支名（推荐 main 而非 master）
git config --global init.defaultBranch main
</code></pre><hr>
<h2 id="三-常用命令速查">三、常用命令速查</h2>
<h3 id="创建仓库">🏗️ 创建仓库</h3>
<pre><code class="hljs language-bash"># 从零开始
git init

# 克隆远程仓库
git clone https://github.com/user/repo.git

# 克隆到指定目录
git clone https://github.com/user/repo.git my-folder
</code></pre><h3 id="日常三步曲-add-commit-push">📝 日常三步曲：add → commit → push</h3>
<pre><code class="hljs language-bash"># 1. 查看当前状态
git status

# 2. 把修改加入暂存区
git add file.py              # 添加单个文件
git add .                    # 添加所有修改

# 3. 提交
git commit -m &quot;描述你改了什么&quot;

# 4. 推送到远程
git push

# 一句话搞定（已跟踪文件的修改）
git commit -am &quot;修复登录bug&quot;
</code></pre><h3 id="拉取更新-git-fetch-完全指南">📥 拉取更新 (git fetch 完全指南)</h3>
<p>核心区别：</p>
<ul>
<li><code>git pull</code> = <code>git fetch</code> + <code>git merge</code>（一步到位）</li>
<li><code>git fetch</code> = <strong>只下载</strong>远程最新数据，<strong>不会自动合并</strong></li>
<li>先用 fetch 看远程有什么变化，再决定怎么合并——更安全可控</li>
</ul>
<pre><code class="hljs language-bash"># 最常用
git pull                       # 拉取并自动合并（一步到位）

# 更安全的做法：先看再合
git fetch                      # 只下载，不合并
git log --oneline main..origin/main  # 看看远程有哪些新提交
git merge origin/main          # 确认没问题后再合并
</code></pre><h4 id="基础用法">基础用法</h4>
<pre><code class="hljs language-bash"># 从默认远程（origin）拉取
git fetch

# 从指定远程拉取
git fetch origin
git fetch upstream             # 如果有多个远程

# 从所有远程拉取
git fetch --all
</code></pre><h4 id="拉取特定分支">拉取特定分支</h4>
<pre><code class="hljs language-bash"># 拉取远程的某个分支
git fetch origin main          # 只拉取 main 分支
git fetch origin feature/login # 拉取指定功能分支

# 拉取后查看远程分支
git branch -r                  # 查看所有远程分支
# origin/main
# origin/feature/login

# 基于远程分支创建本地分支
git switch -c login origin/feature/login
</code></pre><h4 id="清理远程分支信息">清理远程分支信息</h4>
<pre><code class="hljs language-bash"># 远程已删除的分支，本地还残留在 remote 列表里
git branch -r                  # 可能看到 origin/old-feature

# 清理已不存在的远程分支
git fetch --prune
# 或简写
git fetch -p

# 同时拉取并清理
git fetch --all --prune

# 查看清理效果
git branch -r                  # 已删除的远程分支不再显示
</code></pre><h4 id="安全-fetch-的技巧">安全 fetch 的技巧</h4>
<pre><code class="hljs language-bash"># 先 fetch 看看远程情况
git fetch origin
git status                     # 提示：Your branch is behind &#39;origin/main&#39; by 3 commits

# 查看远程新提交的内容（不合并就不会冲突）
git log --oneline main..origin/main
# 或看 diff
git diff main origin/main

# 确认可以合并后再操作
git merge origin/main          # 快进合并（fast-forward）

# 如果不想 merge，也可以 rebase
git rebase origin/main
</code></pre><h4 id="强制覆盖本地-谨慎使用">强制覆盖本地（谨慎使用）</h4>
<pre><code class="hljs language-bash"># 场景：本地已经改乱了，想完全重置为远程版本
git fetch origin
git reset --hard origin/main  # ⚠️ 会丢弃所有本地修改！
</code></pre><h4 id="多远程协同">多远程协同</h4>
<pre><code class="hljs language-bash"># 查看所有远程
git remote -v
# origin    https://github.com/你自己/repo.git (fetch)
# upstream  https://github.com/原作者/repo.git (fetch)

# 从不同远程拉取
git fetch upstream            # 拉取原作者的更新
git log --oneline main..upstream/main  # 和原作者有哪些差异
git merge upstream/main       # 合并到本地
</code></pre><blockquote>
<p>💡 <strong>最佳实践：</strong> 养成先 <code>git fetch</code> 再决定合并方式的习惯，而不是直接用 <code>git pull</code>。fetch 让你有机会在合并前检查远程的改动，避免被意外的合并冲突打个措手不及。</p>
</blockquote>
<h3 id="分支操作">🔀 分支操作</h3>
<pre><code class="hljs language-bash"># 查看分支
git branch                   # 本地分支
git branch -a                # 包含远程分支

# 创建并切换分支
git checkout -b feature-login
# 或新版语法
git switch -c feature-login

# 切换分支
git checkout main
# 或
git switch main

# 合并分支（先切到目标分支）
git switch main
git merge feature-login

# 删除分支
git branch -d feature-login  # 已合并的
git branch -D feature-login  # 强制删除
</code></pre><h3 id="查看历史-git-log-完全指南">🔍 查看历史 (git log 完全指南)</h3>
<pre><code class="hljs language-bash"># 最常用
git log
git log --oneline            # 简洁版（一行一条）
git log --oneline --graph    # 带 ASCII 分支图
</code></pre><h4 id="格式化输出">格式化输出</h4>
<pre><code class="hljs language-bash"># 自定义格式
git log --format=&quot;%h - %an: %s&quot;
# %h = 短 hash, %an = 作者, %s = 标题, %ad = 日期

# 内置漂亮格式
git log --pretty=format:&quot;%C(yellow)%h%Creset %C(cyan)%ad%Creset %s&quot; --date=short

# 显示分支拓扑图（必学！）
git log --oneline --graph --all --decorate
</code></pre><h4 id="按条件过滤">按条件过滤</h4>
<pre><code class="hljs language-bash"># 按作者
git log --author=&quot;张三&quot;
git log --committer=&quot;李四&quot;

# 按时间
git log --since=&quot;2025-01-01&quot;
git log --until=&quot;2025-06-01&quot;
git log --since=&quot;2 weeks ago&quot;
git log --since=&quot;yesterday&quot;

# 按提交信息
git log --grep=&quot;修复&quot;
git log --grep=&quot;feat&quot; --grep=&quot;fix&quot; --all-match  # 同时匹配多个

# 按文件
git log -- app/models/user.rb      # 只看某个文件的历史
git log -p app/models/user.rb      # 同时看每个版本的 diff
</code></pre><h4 id="查看变更内容">查看变更内容</h4>
<pre><code class="hljs language-bash">git log -p                     # 每次提交的完整 diff
git log --stat                 # 统计改了多少文件，多少行
git log --name-only            # 只看改了哪些文件
git log --name-status          # 文件及变更类型（A/M/D）
</code></pre><h4 id="限制输出数量">限制输出数量</h4>
<pre><code class="hljs language-bash">git log -5                     # 只看最近 5 条
git log -n 10                  # 同上
git log --max-count=20

# 只看某个范围内的提交
git log main..feature          # feature 有但 main 没有的提交
git log --since=&quot;2025-01-01&quot; --until=&quot;2025-03-01&quot; -10
</code></pre><h4 id="分支对比">分支对比</h4>
<pre><code class="hljs language-bash"># 查看两个分支的差异提交
git log main..feature          # feature 有而 main 没有
git log --oneline --left-right main...feature  # 两侧对比

# 查看分支的合并关系
git log --oneline --graph --merges
</code></pre><h4 id="高级用法">高级用法</h4>
<pre><code class="hljs language-bash"># 搜索包含特定字符串的提交
git log -S &quot;console.log&quot;          # 新增或删除该字符串的提交
git log -G &quot;console.log&quot;          # 匹配正则的提交（比 -S 更广）

# 查看某个函数的修改历史
git log -L :functionName:file.py

# 查看所有分支的提交（不只是当前分支）
git log --all --oneline

# 只看合并提交
git log --merges
git log --no-merges             # 排除合并提交

# 自定义漂亮输出（推荐配置别名）
git log --graph --pretty=format:&#39;%C(yellow)%h%Creset %C(blue)%d%Creset %s %Cgreen(%cr) %C(cyan)&lt;%an&gt;%Creset&#39; --all
</code></pre><blockquote>
<p>💡 <strong>建议配置别名：</strong> <code>git config --global alias.lg &quot;log --graph --pretty=format:&#39;%C(yellow)%h%Creset %C(blue)%d%Creset %s %Cgreen(%cr) %C(cyan)&lt;%an&gt;%Creset&#39; --all&quot;</code>，之后用 <code>git lg</code> 即可享受漂亮的日志展示。</p>
</blockquote>
<pre><code class="hljs language-bash"># 查看谁改了什么（不是 log，但常一起用）
git blame file.py
</code></pre><h3 id="撤销操作">↩️ 撤销操作</h3>
<pre><code class="hljs language-bash"># 撤销工作区修改（还没 add）
git restore file.py
# 或旧语法
git checkout -- file.py

# 撤销暂存（已 add，还没 commit）
git restore --staged file.py
# 或旧语法
git reset HEAD file.py

# 撤销最近一次提交（保留修改）
git reset --soft HEAD~1

# 撤销最近一次提交（丢弃修改）⚠️ 危险
git reset --hard HEAD~1

# 修改最近一次提交信息
git commit --amend -m &quot;新的提交信息&quot;
</code></pre><h3 id="标签">🏷️ 标签</h3>
<pre><code class="hljs language-bash">git tag v1.0                 # 轻量标签
git tag -a v1.0 -m &quot;版本1.0&quot; # 附注标签
git push origin v1.0         # 推送标签
</code></pre><hr>
<h2 id="四-场景实战">四、场景实战</h2>
<h3 id="场景-1-第一次参与项目">场景 1：第一次参与项目</h3>
<pre><code class="hljs language-bash"># 1. 克隆仓库
git clone https://github.com/team/project.git
cd project

# 2. 创建自己的功能分支
git switch -c feature/my-feature

# 3. 写代码...然后提交
git add .
git commit -m &quot;添加用户注册功能&quot;

# 4. 推送到远程
git push -u origin feature/my-feature

# 5. 在 GitHub/GitLab 上创建 Pull Request (PR)
</code></pre><h3 id="场景-2-正在开发-同事已经合了代码">场景 2：正在开发，同事已经合了代码</h3>
<pre><code class="hljs language-bash"># 方法一：rebase（保持线性历史，推荐）
git fetch origin
git rebase origin/main

# 方法二：merge（保留合并记录）
git fetch origin
git merge origin/main
</code></pre><h3 id="场景-3-写了一半突然要修紧急-bug">场景 3：写了一半突然要修紧急 bug</h3>
<pre><code class="hljs language-bash"># 方案一：stash（临时存放）
git stash                    # 保存当前修改
git switch -c hotfix/bug-123 # 切到新分支修 bug
# ...修完...
git commit -am &quot;修复 #123&quot;
git switch feature/my-feature # 回来继续
git stash pop                 # 恢复之前的修改

# 方案二：worktree（另一个目录工作）
git worktree add ../hotfix hotfix/bug-123
cd ../hotfix
# ...修完...
git commit -am &quot;修复 #123&quot;
</code></pre><h3 id="场景-4-提交信息写错了">场景 4：提交信息写错了</h3>
<pre><code class="hljs language-bash"># 改最近一条
git commit --amend -m &quot;正确的提交信息&quot;

# 已经 push 了？需要强制推送（慎用）
git push --force-with-lease
</code></pre><h3 id="场景-5-不小心把不该提交的文件-push-了">场景 5：不小心把不该提交的文件 push 了</h3>
<pre><code class="hljs language-bash"># 从仓库删除但保留本地文件
git rm --cached secret.key
git commit -m &quot;移除敏感文件&quot;
git push

# ⚠️ 敏感信息（密码、密钥）已推送到远程的，必须立即轮换！
# Git 历史中仍可看到，彻底清理需用 git filter-branch 或 BFG
</code></pre><h3 id="场景-6-合并冲突">场景 6：合并冲突</h3>
<pre><code class="hljs language-bash">git merge feature-login
# 出现冲突时：
# 1. 打开冲突文件，找到 &lt;&lt;&lt;&lt;&lt;&lt;&lt; ======= &gt;&gt;&gt;&gt;&gt;&gt;&gt; 标记
# 2. 手动选择保留哪部分代码
# 3. 保存后
git add .
git commit -m &quot;解决合并冲突&quot;
</code></pre><p>冲突标记示例：</p>
<pre><code class="hljs language-python"># &lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD (当前分支)
name = &quot;Alice&quot;
# =======
name = &quot;Bob&quot;
# &gt;&gt;&gt;&gt;&gt;&gt;&gt; feature-login (要合并的分支)
</code></pre><h3 id="场景-7-回退到某个历史版本">场景 7：回退到某个历史版本</h3>
<pre><code class="hljs language-bash"># 查看历史
git log --oneline
# a1b2c3d 修复登录bug
# e4f5g6h 添加注册功能
# i7j8k9l 初始提交

# 回退（保留修改在工作区）
git reset --soft a1b2c3d

# 回退（彻底丢弃）⚠️
git reset --hard a1b2c3d

# 更安全的做法：用 revert 创建一个反向提交
git revert e4f5g6h
</code></pre><hr>
<h2 id="五-团队分工模式">五、团队分工模式</h2>
<h3 id="模式-1-集中式-centralized-workflow">模式 1：集中式（Centralized Workflow）</h3>
<p>最简单，适合小团队（2-5人）。</p>
<pre><code>所有人 → main 分支 → push/pull
</code></pre><p><strong>规则：</strong></p>
<ul>
<li>只有一个 main 分支</li>
<li>pull → 改代码 → push</li>
<li>冲突时先 pull 再 push</li>
</ul>
<p><strong>问题：</strong> 容易互相覆盖，不推荐超过 3 人使用。</p>
<hr>
<h3 id="模式-2-feature-branch-功能分支模式-最常用">模式 2：Feature Branch（功能分支模式）⭐ 最常用</h3>
<pre><code>main ────────────────────────────── merge ──
  └── feature-A ── merge ──┘
  └── feature-B ──────────── merge ──┘
</code></pre><p><strong>规则：</strong></p>
<ul>
<li>main 分支永远可部署</li>
<li>每个功能/任务开新分支</li>
<li>完成后通过 PR/MR 合入 main</li>
<li>合并前需要 Code Review</li>
</ul>
<p><strong>命名规范：</strong></p>
<pre><code>feature/用户注册
feature/payment
bugfix/登录失败
hotfix/生产环境崩溃
chore/更新依赖
</code></pre><hr>
<h3 id="模式-3-git-flow">模式 3：Git Flow</h3>
<p>适合有明确发布周期的项目（如 App 发版）。</p>
<pre><code>main       ────────────────────── v1.0 ──── v2.0 ──
develop    ────────────────────────────────────────
  └── feature/A ── merge to develop ──┘
  └── release/1.0 ── merge to main + develop ─┘
  └── hotfix/xxx ── merge to main + develop ─┘
</code></pre><p><strong>分支说明：</strong></p>
<table>
<thead>
<tr>
<th>分支</th>
<th>用途</th>
<th>合并到</th>
</tr>
</thead>
<tbody><tr>
<td>main</td>
<td>生产版本</td>
<td>-</td>
</tr>
<tr>
<td>develop</td>
<td>开发集成分支</td>
<td>main（通过 release）</td>
</tr>
<tr>
<td>feature/*</td>
<td>新功能</td>
<td>develop</td>
</tr>
<tr>
<td>release/*</td>
<td>准备发版</td>
<td>main + develop</td>
</tr>
<tr>
<td>hotfix/*</td>
<td>紧急修复</td>
<td>main + develop</td>
</tr>
</tbody></table>
<hr>
<h3 id="模式-4-github-flow-trunk-based">模式 4：GitHub Flow / Trunk-Based</h3>
<p>适合持续部署的 Web 项目，最轻量。</p>
<pre><code>main ─────────────────────────────────
  └── feature ── PR + review ── merge ── 立即部署
</code></pre><p><strong>规则：</strong></p>
<ul>
<li>main 始终可部署</li>
<li>功能分支开发 → PR → Review → 合并 → 自动部署</li>
<li>没有 release 分支，持续集成</li>
</ul>
<hr>
<h3 id="模式-5-forking-workflow">模式 5：Forking Workflow</h3>
<p>适合开源项目，贡献者没有主仓库写权限。</p>
<pre><code>主仓库 (upstream)
  ↑ PR
贡献者的 Fork (origin)
  └── feature ── push to origin ── PR to upstream
</code></pre><pre><code class="hljs language-bash"># 1. Fork 仓库（GitHub 上点按钮）
# 2. 克隆自己的 fork
git clone https://github.com/你/repo.git

# 3. 添加上游仓库
git remote add upstream https://github.com/原作者/repo.git

# 4. 同步上游更新
git fetch upstream
git merge upstream/main

# 5. 推送到自己的 fork
git push origin feature/xxx

# 6. 在 GitHub 上创建 PR
</code></pre><hr>
<h2 id="六-工作中常见情况">六、工作中常见情况</h2>
<h3 id="1-代码审查-code-review">1. 代码审查 (Code Review)</h3>
<pre><code class="hljs language-bash"># 提交 PR 前先同步最新代码
git fetch origin
git rebase origin/main

# 如果 PR 评审后需要修改
# 在原分支继续改，然后
git add .
git commit -m &quot;根据 review 修改&quot;
git push

# 或者用 amend 追加到上一个提交（保持 PR 干净）
git add .
git commit --amend --no-edit
git push --force-with-lease
</code></pre><h3 id="2-ci-cd-流水线">2. CI/CD 流水线</h3>
<pre><code>push → 触发 CI → 跑测试 → 通过才能 merge
</code></pre><p>常见 CI：GitHub Actions、GitLab CI、Jenkins</p>
<h3 id="3-gitignore-文件">3. .gitignore 文件</h3>
<pre><code class="hljs language-bash"># 忽略不需要跟踪的文件
node_modules/
dist/
.env
*.log
.DS_Store
__pycache__/
</code></pre><h3 id="4-ssh-key-配置-免密码推送">4. SSH Key 配置（免密码推送）</h3>
<pre><code class="hljs language-bash"># 生成 SSH Key
ssh-keygen -t ed25519 -C &quot;your@email.com&quot;

# 复制公钥
cat ~/.ssh/id_ed25519.pub
# 粘贴到 GitHub → Settings → SSH Keys

# 测试连接
ssh -T git@github.com

# 仓库使用 SSH URL
git remote set-url origin git@github.com:user/repo.git
</code></pre><h3 id="5-多人协作的礼仪">5. 多人协作的礼仪</h3>
<table>
<thead>
<tr>
<th>做 ✅</th>
<th>不做 ❌</th>
</tr>
</thead>
<tbody><tr>
<td>频繁 pull 最新代码</td>
<td>长时间不同步然后大冲突</td>
</tr>
<tr>
<td>小步提交，信息清晰</td>
<td>一次提交堆一堆改动</td>
</tr>
<tr>
<td>写有意义的 commit message</td>
<td>&quot;fix&quot;、&quot;update&quot;、&quot;wip&quot;</td>
</tr>
<tr>
<td>合并前跑测试</td>
<td>直接 push 到 main</td>
</tr>
<tr>
<td>及时删除已合并的分支</td>
<td>分支堆积如山</td>
</tr>
</tbody></table>
<h3 id="6-commit-message-规范-angular-规范">6. Commit Message 规范（Angular 规范）</h3>
<pre><code>&lt;type&gt;(&lt;scope&gt;): &lt;subject&gt;

&lt;body&gt;

&lt;footer&gt;
</code></pre><p><strong>type 类型：</strong></p>
<table>
<thead>
<tr>
<th>type</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>feat</td>
<td>新功能</td>
</tr>
<tr>
<td>fix</td>
<td>修复 bug</td>
</tr>
<tr>
<td>docs</td>
<td>文档</td>
</tr>
<tr>
<td>style</td>
<td>格式（不影响逻辑）</td>
</tr>
<tr>
<td>refactor</td>
<td>重构</td>
</tr>
<tr>
<td>test</td>
<td>测试</td>
</tr>
<tr>
<td>chore</td>
<td>构建/工具</td>
</tr>
</tbody></table>
<p>示例：</p>
<pre><code>feat(auth): 添加 OAuth2 登录支持

实现 GitHub 和 Google OAuth2 登录流程，
支持自动创建账号和关联已有账号。

Closes #123
</code></pre><hr>
<h2 id="七-速查脑图">七、速查脑图</h2>
<pre><code>git init / clone
    │
    ├── git add . ─── git commit -m &quot;msg&quot; ─── git push
    │                                              │
    │                         git pull ←────────────┘
    │
    ├── git branch / switch / merge
    │
    ├── git stash ─── git stash pop
    │
    ├── git log / diff / status
    │
    ├── git restore / reset / revert
    │
    └── git remote / fetch / pull
</code></pre><hr>
<h2 id="八-推荐资源">八、推荐资源</h2>
<ul>
<li><strong>交互式学习</strong>：<a href="https://learngitbranching.js.org/">Learn Git Branching</a>（可视化理解分支）</li>
<li><strong>官方文档</strong>：<a href="https://git-scm.com/book/zh/v2">git-scm.com</a></li>
<li><strong>速查表</strong>：<a href="https://training.github.com/downloads/zh/github-git-cheat-sheet/">GitHub Git Cheat Sheet</a></li>
</ul>
]]></content:encoded>
      <pubDate>Fri, 12 Jun 2026 02:31:35 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/git</guid>
      <category>linux</category>
      <category>git</category>
    </item>
    <item>
      <title><![CDATA[石器时代 8.5 原版游戏代码结构分析报告]]></title>
      <link>https://758192.xyz/post/server-code</link>
      <description><![CDATA[8.5原版游戏代码结构分析]]></description>
      <content:encoded><![CDATA[<p><img src="https://p2.itc.cn/q_70/images01/20231028/8d5e23b55a0241aea7994accdb828a07.png" alt="" /></p><hr>
<p>石器时代 8.5 原版游戏代码结构分析报告
一、项目总体结构
stoneage/
├── client-8.5/           # 客户端源码 (Visual Studio 项目, C++)
├── server-8.5/           # 服务端源码 (Linux/C, gcc 编译)
│   ├── gmsv/             # 游戏主服务端
│   └── saac/             # 账号/数据中心服务端
├── 客户端lua文件/         # 客户端 Lua 脚本
├── 服务器端lua文件/       # 服务端 Lua 脚本
├── setup.cf              # 服务端主配置文件
├── acserv.cf             # 账号服务端配置
├── CSA.sql               # 数据库建表 SQL
└── sql.cf                # SQL 配置
二、客户端代码结构 (client-8.5/client_source_code)
2.1 核心目录
目录	用途	关键文件
system/	核心游戏系统 (57个源文件)	gamemain.cpp, netmain.cpp, login.cpp, map.cpp, battleproc.cpp, menu.cpp, pc.cpp, character.cpp, chat.cpp
systeminc/	核心头文件 (58个头文件)	pc.h, character.h, map.h, battleproc.h, menu.h, version.h, netmain.h
oft/	动画/渲染系统	oft.cpp(动画管理), work.cpp(工作函数), pat_dat.cpp
ohta/	高层任务处理	ohta.cpp, ohta_proc.cpp
wgs/	网络加密通信层	message.cpp(消息格式), descrypt.cpp(加密解密), tea.cpp(TEA加密), Ping.cpp
newproto/	协议层	protocol.cpp/h(516行,220+协议定义), autil.cpp/h(协议工具)
mylua/	客户端 Lua 引擎	winlua.cpp, sa.cpp, lssproto.cpp, ServerList.cpp
other/	辅助工具	trade.cpp(交易), ItemsMall.cpp(商城), GetMacAddress.h, md5_encrypt.cpp
sdk/	外部 SDK	(DirectX等)
curl/	HTTP 库	libcurl
openssl/	加密库	MD5等
detours/	Hook 库	Microsoft Detours
2.2 客户端核心数据结构 (pc.h)
玩家角色 (PC) 结构体 — 这是最核心的数据结构:
PC {
    // 基础属性
    graNo, faceGraNo       // 图形编号
    id, dir                 // ID, 方向
    hp, maxHp, mp, maxMp    // 生命值, 魔法值
    vital, str, tgh, dex    // 体力, 力量, 韧性, 敏捷
    exp, maxExp, level      // 经验, 等级
    atk, def, quick, charm, luck  // 攻防速魅幸
    earth, water, fire, wind     // 四元素属性
    gold                     // 金币
    // 物品系统
    item[MAX_ITEM]           // 道具栏 (5装备位+15背包×3页)
    itempool[MAX_ITEM]       // 寄放道具
    // 宠物系统
    battlePetNo              // 战斗出战宠物
    selectPetNo[5]           // 选择的5只宠物
    mailPetNo                // 邮件宠物
    // 社交系统
    familyName               // 家族名
    channel                  // 频道
    trade_confirm            // 交易确认状态
    // 家族系统
    familyleader             // 家族职务
    familySprite             // 家族精灵(庄园)
    big4fm                   // 四大庄园标识
    // 职业系统 (7.0+)
    profession_class         // 职业类型(战士/法师/猎人)
    profession_level         // 职业等级
    profession_skill_point   // 技能点
    // 其他系统
    ridePetNo, ridePetName   // 骑宠
    transmigration           // 转生次数
    titleNo                  // 称号编号
    status, etcFlag          // 状态/标志位
}
宠物 (PET) 结构体:
PET {
    graNo, hp, maxHp, mp, maxMp
    exp, maxExp, level
    atk, def, quick, ai
    earth, water, fire, wind   // 四元素
    maxSkill, trn(转生数), fusion(融合标志)
    name, freeName, useFlag
    item[MAX_PET_ITEM]          // 宠物装备(头/翼/牙/身/背/爪/脚)
}
装备栏位枚举:
装备: HEAD, BODY, ARM, DECORATION1, DECORATION2,
      BELT, SHIELD, SHOES, GLOVE  (共9个栏位)
宠物装备: HEAD, WING, TOOTH, PLATE, BACK, CLAW, FOOT (7个栏位)
2.3 客户端核心文件功能
文件	行数	功能
gamemain.cpp	1484	游戏主循环,帧率控制,状态机管理
login.cpp	21687	最大文件 — 登录流程,角色创建/选择/删除,服务器选择
menu.cpp	22835	第二大文件 — 所有UI菜单(状态/道具/宠物/技能/交易/银行/邮件等)
map.cpp	6157	地图渲染,移动,碰撞检测,视野管理
pc.cpp	1681	玩家数据管理,属性初始化,宠物/道具/技能管理
battleproc.cpp	1172	战斗流程控制,遇敌,战斗动画
character.cpp	4051	角色对象管理(包括NPC/玩家/宠物的显示)
chat.cpp	1567	聊天系统(多频道,聊天历史,屏蔽词)
netmain.cpp	661	网络连接管理,Socket操作
field.cpp	-	大地图渲染(地面物件)
pattern.cpp	-	角色动作帧管理
save.cpp	-	存档系统
三、服务端代码结构 (server-8.5/gmsv)
3.1 核心模块
目录/文件	文件数	功能
battle/	10	战斗系统(battle.c 11328行!, battle_command.c 1251行, battle_ai.c, battle_item.c, battle_magic.c, pet_skill.c, profession_skill.c)
char/	25	角色系统(char.c 11543行!, char_base.c 4559行, char_walk.c, char_talk.c, char_item.c, char_party.c, trade.c 24个源文件, pet.c, pet_event.c, family.c, skill.c, title.c, encounter.c, enemy.c, chatroom.c, addressbook.c)
item/	5	物品系统(item.c 2502行, item_event.c, item_gen.c)
magic/	5	魔法系统(magic.c 916行, magic_base.c, magic_field.c)
npc/	77	NPC系统(77个NPC类型!)
map/	5	地图系统(map_deal.c, map_util.c, readmap.c, map_warppoint.c)
lua/	193	LuaJIT 引擎完整源码
mylua/	25	服务端 Lua 绑定层
npc_lua/	18	NPC Lua 接口(npc_lua_battle.c, npc_lua_char.c, npc_lua_item.c, npc_lua_map.c, etc.)
include/	152	所有头文件
3.2 服务端核心文件
文件	行数	功能
lssproto_serv.c	3894	协议处理核心 — 解码客户端消息,分发到各处理函数
char.c	11543	角色管理主文件(登录,登出,行走,物品使用,交易,家族等)
char_base.c	4559	角色基础数据管理(骑宠表296条!)
battle.c	11328	战斗引擎(回合制,伤害计算,AI,状态效果等)
battle_command.c	1251	战斗指令解析(攻击/防御/捕捉/逃跑/宠物/物品等)
item.c	2502	物品数据管理(属性,类型,装备效果)
magic.c	916	魔法使用逻辑(回复/属性变化/状态/复活/攻击魔法)
main.c	-	服务端入口,主循环
net.c	-	网络层(epoll)
epollnet.c	-	epoll 网络模型
callfromcli.c	-	客户端消息处理入口
callfromac.c	-	账号服务器消息处理入口
configfile.c	-	配置文件解析
3.3 服务端核心数据结构
角色(Char) 结构体 — 对应客户端PC,包含更丰富的服务端逻辑字段:
Char {
    // 基础数据: id, name, hp, mp, str, tgh, dex, etc.
    // 位置: floor, x, y, dir
    // 战斗: battleindex, battlemode
    // 家族: fmindex, fmrank, fmsprite
    // 职业: profession_class, profession_level
    // NPC特有: whichtype, npcworkint[10], npcarg
}
战斗(BATTLE) 结构体:
BATTLE {
    type (P_vs_E, P_vs_P, E_vs_E, WATCH, DP_BATTLE, BOSS_BATTLE)
    mode (NONE, INIT, BATTLE, FINISH, STOP, WATCHBC...)
    flg (状态标志)
    entry[BATTLE_ENTRY_MAX]    // 最多10(或12)个参战单位
}
四、协议设计和网络通信
4.1 协议架构
协议层由三部分组成:</p>
<ol>
<li>WGS层 (wgs/): 底层通信 — 消息格式化(message.cpp),TEA加密(tea.cpp),DES加密(descrypt.cpp)</li>
<li>LSS层 (lssproto): RPC协议层 — 客户端lssproto_cli.cpp + 服务端lssproto_serv.c</li>
<li>新协议层 (newproto/): 增强协议 — protocol.cpp/h中定义的 SaDispatchMessage
4.2 协议列表 (220+ 条协议)
按功能分类:
移动/地图类:
编号	协议	方向
0-1	W/W2	S→C</li>
</ol>
<p>2	XYD	C→S
3-4	EV	C↔S
42-43	CA/CD	S→C
37-39	MC/M/M	S→C/C→S/S→C
70	SP	C→S
战斗类:
编号	协议	方向
12-13	RS/RD	S→C
14-15	B	C↔S
16	SKD	C→S
54-55	KS	C↔S
93-94	FM	C↔S
97	BM	C→S
107	PETST	C↔S
103-104	CS	C↔S
物品/装备类:
编号	协议	方向
22	I	S→C
23	MI	C→S
24	SI	S→C
17	ID	C→S
18	PI	C→S
19-20	DI/DG	C→S
21	DP	C→S
127	PET_ITEM	C→S
角色/社交类:
编号	协议	方向
25-26	MSG	C↔S
27	PMSG	C→S
28	PME	S→C
29-33	AB/ABI/DAB/AAB	C↔S
34	L	C→S
35-36	TK	C↔S
40-41	C	C↔S
44	R	S→C
登录/角色管理类:
编号	协议	方向
71-72	CLIENTLOGIN	C↔S
73-74	CREATENEWCHAR	C↔S
75-76	CHARDELETE	C↔S
77-78	CHARLOGIN	C↔S
79-80	CHARLIST	C↔S
81-82	CHARLOGOUT	C↔S
魔法/技能类:
编号	协议	方向
50-51	HL	C↔S
52-53	PR	C↔S
56	AC	C→S
57	MU	C→S
58-59	PS	C↔S
101	NC	S→C
110-111	BATTLESKILL	C↔S
扩展系统类:
编号	协议	方向
95	WO	S→C
112-113	CHATROOM	C↔S
116-117	STREET_VENDOR	C↔S
120-121	JOBDAILY	C↔S
122-123	TEACHER_SYSTEM	C↔S
126	FIREWORK	S→C
128	MOVE_SCREEN	S→C
131-132	THEATER	C↔S
133-134	MAGICCARD	S→C
139-140	PKLIST	C↔S
141	SIGNDAY	C→S
200	DENGON	S→C
201-202	SAMENU	C↔S
208-209	SHOPOK	C↔S
210-211	FAMILYBADGE	C↔S
212-213	CHARTITLE	C↔S
218-219	VB	C↔S
220	RIDEQUERY	C→S
221-222	PETSKINS	C↔S
4.3 通信机制</p>
<ul>
<li>传输层: TCP Socket (非阻塞, epoll)</li>
<li>加密: TEA加密 + DES加密 + 个人密钥(PersonalKey)</li>
<li>消息格式: &amp;;[PID];[参数计数];[参数1];[参数2];...&amp; (8字节对齐)</li>
<li>连接模式: WGS中转服务 → 游戏服务器直连</li>
<li>账号验证: SAAC (StoneAge Account Center) 独立服务, MySQL存储
五、NPC 系统 (77个NPC类型)
NPC类型	文件
商店类	npc_itemshop.c, npc_petshop.c, npc_petskillshop.c, npc_vipshop.c, npc_newvipshop.c, npc_simpleshop.c, npc_poolitemshop.c, npc_itemchange.c
传送类	npc_warp.c, npc_warpman.c, npc_transerman.c, npc_bus.c, npc_ship.c, npc_airplane.c
家族类	npc_familyman.c, npc_fmpkman.c, npc_fmpkcallman.c, npc_fmwarpman.c, npc_fmhealer.c, npc_fmletter.c, npc_fmdengon.c, npc_fmchallenge.c, npc_manorsman.c
娱乐类	npc_gamblemaster.c, npc_gambleroulette.c, npc_gamblebank.c, npc_quiz.c, npc_janken.c, npc_magiccard.c, npc_luckyman.c
功能类	npc_healer.c, npc_savepoint.c, npc_bankman.c, npc_exchangeman.c, npc_makepair.c, npc_riderman.c, npc_doorman.c
战斗类	npc_npcenemy.c, npc_autopk.c, npc_duelranking.c
宠物类	npc_petmaker.c, npc_petracemaster.c, npc_petracepet.c, npc_petfusion.c, npc_freepetskillshop.c
社交类	npc_signboard.c, npc_storyteller.c, npc_mic.c, npc_msg.c, npc_dengon.c, npc_charm.c, npc_bodylan.c
系统类	npc_sysinfo.c, npc_timeman.c, npc_scheduleman.c, npc_checkman.c, npc_roomadminnew.c
导师类	npc_transmigration.c
摆摊类	npc_pauctionman.c
日常类	npc_welfare.c, npc_dayaction.c
六、核心游戏功能特性总结
6.1 角色系统</li>
<li>属性体系: HP/MP/体力/力量/韧性/敏捷/攻/防/速/魅/幸</li>
<li>四元素: 地/水/火/风(相互克制)</li>
<li>转生系统: 最高支持6转,每次转生属性重置并成长</li>
<li>职业系统 (7.0+): 战士/法师/猎人三大职业,26级职业等级上限</li>
<li>称号系统: 图形称号 + 文字称号</li>
<li>装备栏位: 头/身/臂/装饰×2/腰带/盾/鞋/手套 = 9个
6.2 宠物系统</li>
<li>携带: 最多5只宠物</li>
<li>战斗: 宠物可出战(前后排)</li>
<li>骑乘: 296种骑宠组合表,骑宠有等级和转生要求</li>
<li>融合/进化: 宠物融合系统(人龙进化)</li>
<li>宠物装备: 7个装备栏位(头/翼/牙/身/背/爪/脚)</li>
<li>宠物技能: 大量被动/主动技能</li>
<li>宠物祝福: buff系统</li>
<li>宠物皮肤: 皮肤更换系统
6.3 战斗系统</li>
<li>模式: 遇敌制(步数触发),回合制</li>
<li>类型: PVE/PVP/观战/DP赛/BOSS战</li>
<li>阵容: 标准5v5,可扩展至6v6或40人</li>
<li>指令: 攻击/防御/捕捉/逃跑/道具/技能/宠物出退</li>
<li>宠物技能: 50+种技能(连续攻击/蓄力攻击/守护/抢夺/状态变化等)</li>
<li>职业技能: 战士/法师/猎人各有独特技能树</li>
<li>魔法: 回复/属性变化/状态变化/复活/攻击魔法/变身/召唤龙</li>
<li>AI: 自动战斗AI系统</li>
<li>观战: 可观看他人战斗</li>
<li>异常状态: 中毒/麻痹/睡眠/石化/混乱/醉酒/沉默
6.4 物品系统</li>
<li>类型: 拳/斧/棍/矛/弓/盾/头盔/铠甲/手镯/脚链/项链/戒指/腰带/耳环/鼻环/护身符/回旋镖/投石索/投掷石/料理/金属/宝石/材料/宠物装备等</li>
<li>属性: 攻击/防御/敏捷/HP/MP/幸运/魅力/回避/元素</li>
<li>堆叠: 可堆叠物品</li>
<li>耐久: 物品有损坏和最大损坏度</li>
<li>精炼: 精炼系统</li>
<li>强化: 物品强化</li>
<li>凿孔/镶嵌: 宝石镶嵌系统</li>
<li>法宝: 特殊道具系统
6.5 社交系统</li>
<li>组队: 最多5人(或8人)组队</li>
<li>家族/公会: 1000个家族,100人上限,族长/长老/成员职务,频道系统(5频道)</li>
<li>名片/好友: 多页名片册,在线状态显示</li>
<li>交易: 双方确认的交易系统,支持物品/宠物/金币</li>
<li>邮件: 普通邮件+宠物邮件</li>
<li>摆摊: 玩家间交易</li>
<li>聊天室: 频道聊天
6.6 多频道系统</li>
<li>队伍频道/密语频道/家族频道/职业频道/世界频道/星球频道/聊天室/对话储存
6.7 地图系统</li>
<li>格式: Tile-based, 包含 tile/parts/event/hitMap 四层</li>
<li>云层效果: 地图云雾效果</li>
<li>特殊动画: 环境动画(水中生物/定点动画/随机动画)</li>
<li>寻路: 网格式寻路,碰撞检测</li>
<li>视野: 按屏幕可见范围渲染</li>
<li>天空岛: 特殊地图类型
6.8 家族/庄园系统</li>
<li>十大庄园: 庄园争夺战</li>
<li>家族PK: 家族间战斗</li>
<li>庄园规则: 家族贡献/税收</li>
<li>家族徽章: 视觉化家族标识</li>
<li>家族频道: 家族内部通信
6.9 扩展系统 (8.0-8.5新增)</li>
<li>天使的召唤: 特殊任务系统</li>
<li>导师系统: 老玩家带新玩家</li>
<li>讨伐魔军: PvE活动系统</li>
<li>百人无双: 大型战斗</li>
<li>每日活动: 每日任务</li>
<li>魔法牌: 卡牌小游戏</li>
<li>剧场: 剧情演出功能</li>
<li>排行榜: 各类排名NPC</li>
<li>签到系统: 每日签到</li>
<li>公告系统: 服务器公告</li>
<li>商城: 道具商城
6.10 AI/挂机系统</li>
<li>自动战斗AI</li>
<li>自动遇敌</li>
<li>自动喊话
6.11 Lua 脚本系统</li>
<li>客户端Lua: 界面定制/窗口管理/标题管理/地图逻辑</li>
<li>服务端Lua: NPC逻辑/战斗逻辑/角色操作/物品操作/地图操作/SQL操作</li>
<li>使用 LuaJIT 引擎(高性能JIT编译)</li>
<li>Lua绑定层: 25个绑定模块,覆盖游戏所有系统
6.12 安全系统</li>
<li>TEA + DES + 个人密钥 加密</li>
<li>VMProtect SDK 反调试</li>
<li>MAC 地址验证</li>
<li>封包大小检查</li>
<li>IP 限制和同IP登录限制</li>
<li>VMP (VMProtect) 保护
七、服务端配置系统 (setup.cf)
关键配置项:</li>
<li>网络: 端口19065, fd数1000, 角色数800, 宠物数30000, NPC数45000, 物品数50000, 战斗数500</li>
<li>战斗: 战斗速度2000ms, 回合延迟200ms, 经验倍率</li>
<li>骑宠: 等级要求140, 转生要求</li>
<li>安全: 封包大小检查(登录前300/登录后800), 同IP限制</li>
<li>数据: SAAC账号服务端端口10001, MySQL数据库存储</li>
<li>活动: 自动PK/六合彩/幸运星等活动配置</li>
<li>VIP: VIP战斗经验倍率/VIP显示控制</li>
</ul>
<hr>
<p>总结: 石器时代8.5是一个功能非常丰富的2D回合制MMORPG,客户端约3万行C++代码,服务端约4-5万行C代码。核心系统包括: 角色/宠物/战斗/物品/魔法/社交/家族/职业等,支持220+条协议通信,77种NPC类型,大量Lua脚本扩展。整个系统从4.0到8.5经历了多次大版本迭代,功能层层叠加。</p>
]]></content:encoded>
      <pubDate>Fri, 12 Jun 2026 00:34:09 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/server-code</guid>
      <category>石器时代</category>
      <category>stoneage</category>
    </item>
    <item>
      <title><![CDATA[石器时代客户端重构 — 协议]]></title>
      <link>https://758192.xyz/post/xieyi</link>
      <description><![CDATA[石器时代客户端重构 — 协议

Context

原版 C++ 有 64 个核心系统、150+ 协议。当前 Cocos 客户端已实现 85 个模块，28 个协议。分 3 批推进。

已完成（不在本计划中）

| 改动 | 状态 |
|------|------|
| SafeArea 组件 + Widget 对齐 | ✅ |
| Canvas Widget alignFlag]]></description>
      <content:encoded><![CDATA[<p><img src="https://p3.itc.cn/q_70/images01/20231028/97355f13e8504ab398d2dbbba49976f7.jpeg" alt="" /></p><h1 id="石器时代客户端重构-协议">石器时代客户端重构 — 协议</h1>
<h2 id="context">Context</h2>
<p>原版 C++ 有 64 个核心系统、150+ 协议。当前 Cocos 客户端已实现 85 个模块，28 个协议。分 3 批推进。</p>
<h3 id="已完成-不在本计划中">已完成（不在本计划中）</h3>
<table>
<thead>
<tr>
<th>改动</th>
<th>状态</th>
</tr>
</thead>
<tbody><tr>
<td>SafeArea 组件 + Widget 对齐</td>
<td>✅</td>
</tr>
<tr>
<td>Canvas Widget _alignFlags 修复（45→15）</td>
<td>✅</td>
</tr>
<tr>
<td>移动系统重写（速度向量匹配原版 C++）</td>
<td>✅</td>
</tr>
<tr>
<td>A* 二叉堆优化</td>
<td>✅</td>
</tr>
<tr>
<td>MapRenderer 脏标记</td>
<td>✅</td>
</tr>
<tr>
<td>CharacterView 平滑渲染（像素坐标）</td>
<td>✅</td>
</tr>
</tbody></table>
<hr>
<h2 id="第一批-p0-战斗可玩-核心协议-1-周">第一批：P0 — 战斗可玩 + 核心协议（1 周）</h2>
<h3 id="b1-1-battleview-3-个-todo">B1-1: BattleView 3 个 TODO</h3>
<p><strong>目标</strong>: 战斗中道具/宠物/技能可用</p>
<p><strong>涉及</strong>: BattleView.ts:286/298/310</p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>showItemSelect()</code>: 遍历 inventory 中 consumable 物品，生成选择按钮</li>
<li><code>showPetSelect()</code>: 从 battle.allyPets 生成选择按钮</li>
<li><code>showSkillSelect()</code>: 从 SkillTable 查询宠物可用技能</li>
</ul>
<p><strong>文件</strong>: <code>BattleView.ts</code></p>
<hr>
<h3 id="b1-2-gameapp-3-个-todo">B1-2: GameApp 3 个 TODO</h3>
<p><strong>目标</strong>: MainMenu skill 按钮连线、帮助/设置内容</p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>skill: () =&gt; { this.skillView?.toggle(); }</code></li>
<li>帮助/设置: dialogView 显示实际内容</li>
</ul>
<p><strong>文件</strong>: <code>GameApp.ts</code></p>
<hr>
<h3 id="b1-3-progressbar-组件">B1-3: ProgressBar 组件</h3>
<p><strong>目标</strong>: StatusView 的 HP/MP/EXP 条用 ProgressBar</p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>makeBar()</code> 改为 <code>cc.ProgressBar</code>，保留 Graphics 作为背景轨道</li>
</ul>
<p><strong>文件</strong>: <code>StatusView.ts</code></p>
<hr>
<h3 id="b1-4-协议-58-59-宠物技能-ps">B1-4: 协议 58-59 — 宠物技能（PS）</h3>
<p><strong>目标</strong>: 战斗中使用宠物技能</p>
<p><strong>协议</strong>: <code>PS_SEND(havepetindex, havepetskill, toindex, data)</code> → <code>PS_RECV(result, havepetindex, havepetskill, toindex)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>LssProto.ts</code>: 添加 <code>sendPetSkill()</code> 方法</li>
<li><code>GameClient.ts</code>: 添加 <code>petSkill()</code> 方法</li>
<li><code>Battle.ts</code>: 扩展 <code>sendPetSkill()</code> 发送协议</li>
<li><code>BattleView.ts</code>: showSkillSelect() 连接真实协议</li>
</ul>
<p><strong>文件</strong>: <code>LssProto.ts</code>, <code>GameClient.ts</code>, <code>Battle.ts</code>, <code>BattleView.ts</code></p>
<hr>
<h3 id="b1-5-协议-57-魔法使用-mu">B1-5: 协议 57 — 魔法使用（MU）</h3>
<p><strong>目标</strong>: 战斗/地图中使用魔法</p>
<p><strong>协议</strong>: <code>MU_SEND(x, y, array, toindex)</code> → 无 recv（结果通过 B/EF 体现）</p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>LssProto.ts</code>: 添加 <code>sendMagicUse()</code> 方法</li>
<li><code>GameClient.ts</code>: 添加 <code>magicUse()</code> 方法</li>
<li><code>Battle.ts</code>: 扩展魔法攻击指令</li>
</ul>
<p><strong>文件</strong>: <code>LssProto.ts</code>, <code>GameClient.ts</code>, <code>Battle.ts</code></p>
<hr>
<h2 id="第二批-p1-引擎优化-经济系统-2-周">第二批：P1 — 引擎优化 + 经济系统（2 周）</h2>
<h3 id="b2-1-tween-缓动系统">B2-1: tween 缓动系统</h3>
<p><strong>目标</strong>: 面板打开/关闭动画，按钮点击反馈</p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>GameApp.ts</code> 添加 <code>showView()/hideView()</code> 辅助方法</li>
<li>全部 34 个 View 的 <code>toggle()</code> 包裹 tween</li>
</ul>
<p><strong>文件</strong>: <code>GameApp.ts</code> + 全部 View</p>
<hr>
<h3 id="b2-2-scrollview-layout-组件">B2-2: ScrollView + Layout 组件</h3>
<p><strong>目标</strong>: 聊天/道具/宠物列表滚动，装备槽位自动排列</p>
<p><strong>方案</strong>:</p>
<ul>
<li>ChatView: 消息容器挂载 ScrollView + ScrollBar</li>
<li>InventoryView: 装备面板改用 Layout VERTICAL</li>
<li>PetView: 宠物列表改用 Layout</li>
<li>MainMenu: 菜单项改用 Layout</li>
<li>BattleView: 命令面板改用 Layout HORIZONTAL</li>
</ul>
<p><strong>文件</strong>: <code>ChatView.ts</code>, <code>InventoryView.ts</code>, <code>PetView.ts</code>, <code>MainMenu.ts</code>, <code>BattleView.ts</code></p>
<hr>
<h3 id="b2-3-richtext-聊天格式化">B2-3: RichText 聊天格式化</h3>
<p><strong>目标</strong>: 彩色文字、@提及高亮</p>
<p><strong>方案</strong>:</p>
<ul>
<li>ChatView <code>refreshMessages()</code> 中 Label 替换为 RichText</li>
<li>ChatSystem 消息增加格式化信息</li>
</ul>
<p><strong>文件</strong>: <code>ChatView.ts</code>, <code>game/ChatSystem.ts</code></p>
<hr>
<h3 id="b2-4-协议-116-117-摆摊系统-street-vendor">B2-4: 协议 116-117 — 摆摊系统（Street Vendor）</h3>
<p><strong>目标</strong>: 玩家间摆摊交易，20 物品栏</p>
<p><strong>协议</strong>: <code>STREET_VENDOR_SEND(data)</code> → <code>STREET_VENDOR_RECV(data)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li>新建 <code>game/StreetVendorSystem.ts</code> — 摊位状态管理</li>
<li>新建 <code>cocos/StreetVendorView.ts</code> — 摊位 UI（商品列表 + 价格 + 购买）</li>
<li><code>LssProto.ts</code>: 添加摆摊协议 send/recv</li>
<li><code>GameClient.ts</code>: 集成摆摊操作</li>
<li><code>GameApp.ts</code>: 添加到 UI 管理</li>
</ul>
<p><strong>文件</strong>: 新建 2 + 修改 4</p>
<hr>
<h3 id="b2-5-协议-208-209-商城系统-cash-shop">B2-5: 协议 208-209 — 商城系统（Cash Shop）</h3>
<p><strong>目标</strong>: 彩币购物车，多页商品浏览</p>
<p><strong>协议</strong>: <code>SHOPOK_SEND(data)</code> → <code>SHOPOK_RECV(data)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li>新建 <code>game/CashShopSystem.ts</code> — 商品数据 + 购物车</li>
<li>新建 <code>cocos/CashShopView.ts</code> — 商品列表 + 购物车 + 结算</li>
<li><code>LssProto.ts</code>: 添加商城协议</li>
<li><code>GameClient.ts</code>: 集成商城操作</li>
</ul>
<p><strong>文件</strong>: 新建 2 + 修改 3</p>
<hr>
<h3 id="b2-6-协议-107-宠物选择确认-petst">B2-6: 协议 107 — 宠物选择确认（PETST）</h3>
<p><strong>目标</strong>: 服务器确认宠物出场选择</p>
<p><strong>协议</strong>: <code>PETST_RECV(petarray, result)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>LoginFlow.ts</code>: 添加 PETST_RECV 处理器</li>
<li><code>GameState.ts</code>: 更新宠物出场状态</li>
<li><code>Battle.ts</code>: 同步宠物选择结果</li>
</ul>
<p><strong>文件</strong>: <code>LoginFlow.ts</code>, <code>GameState.ts</code>, <code>Battle.ts</code></p>
<hr>
<h3 id="b2-7-协议-127-宠物装备-pet_item_equip">B2-7: 协议 127 — 宠物装备（PET_ITEM_EQUIP）</h3>
<p><strong>目标</strong>: 宠物穿戴装备</p>
<p><strong>协议</strong>: <code>PET_ITEM_EQUIP_SEND(data)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>LssProto.ts</code>: 添加 <code>sendPetItemEquip()</code> 方法</li>
<li><code>PetSystem.ts</code>: 扩展装备槽位管理</li>
<li><code>PetView.ts</code>: 添加装备操作 UI</li>
</ul>
<p><strong>文件</strong>: <code>LssProto.ts</code>, <code>PetSystem.ts</code>, <code>PetView.ts</code></p>
<hr>
<h3 id="b2-8-协议-65-宠物改名-kn">B2-8: 协议 65 — 宠物改名（KN）</h3>
<p><strong>目标</strong>: 宠物改名</p>
<p><strong>协议</strong>: <code>KN_SEND(havepetindex, data)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>LssProto.ts</code>: 添加 <code>sendPetRename()</code> 方法</li>
<li><code>PetView.ts</code>: 添加改名输入框</li>
</ul>
<p><strong>文件</strong>: <code>LssProto.ts</code>, <code>PetView.ts</code></p>
<hr>
<h2 id="第三批-p2-完整复刻-引擎升级-2-3-周">第三批：P2 — 完整复刻 + 引擎升级（2-3 周）</h2>
<h3 id="b3-1-协议-60-62-称号系统-st-dt-ft">B3-1: 协议 60-62 — 称号系统（ST/DT/FT）</h3>
<p><strong>目标</strong>: 设置/删除/查询称号</p>
<p><strong>协议</strong>:</p>
<ul>
<li><code>ST_SEND(titleindex)</code> — 设置称号</li>
<li><code>DT_SEND(titleindex)</code> — 删除称号</li>
<li><code>FT_SEND(data)</code> — 查询称号列表</li>
</ul>
<p><strong>方案</strong>:</p>
<ul>
<li><code>LssProto.ts</code>: 添加 3 个 send 方法</li>
<li><code>TitleSystem.ts</code>: 扩展协议交互</li>
<li><code>TitleView.ts</code>: 连接真实协议</li>
</ul>
<p><strong>文件</strong>: <code>LssProto.ts</code>, <code>TitleSystem.ts</code>, <code>TitleView.ts</code></p>
<hr>
<h3 id="b3-2-协议-120-121-任务日志-jobdaily">B3-2: 协议 120-121 — 任务日志（JOBDAILY）</h3>
<p><strong>目标</strong>: 任务日志记录与查询</p>
<p><strong>协议</strong>: <code>JOBDAILY_SEND(data)</code> → <code>JOBDAILY_RECV(data)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>LssProto.ts</code>: 添加任务日志协议</li>
<li><code>QuestSystem.ts</code>: 扩展日志记录</li>
<li><code>QuestView.ts</code>: 添加日志标签页</li>
</ul>
<p><strong>文件</strong>: <code>LssProto.ts</code>, <code>QuestSystem.ts</code>, <code>QuestView.ts</code></p>
<hr>
<h3 id="b3-3-协议-122-123-师徒系统-teacher">B3-3: 协议 122-123 — 师徒系统（TEACHER）</h3>
<p><strong>目标</strong>: 师徒关系管理</p>
<p><strong>协议</strong>: <code>TEACHER_SYSTEM_SEND(data)</code> → <code>TEACHER_SYSTEM_RECV(data)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li>新建 <code>game/TeacherSystem.ts</code> — 关系管理</li>
<li>新建 <code>cocos/TeacherView.ts</code> — 师徒 UI</li>
<li><code>LssProto.ts</code>: 添加师徒协议</li>
</ul>
<p><strong>文件</strong>: 新建 2 + 修改 2</p>
<hr>
<h3 id="b3-4-协议-210-211-家族纹章-familybadge">B3-4: 协议 210-211 — 家族纹章（FAMILYBADGE）</h3>
<p><strong>目标</strong>: 家族纹章展示</p>
<p><strong>协议</strong>: <code>FAMILYBADGE_SEND(data)</code> → <code>FAMILYBADGE_RECV(data)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>LssProto.ts</code>: 添加纹章协议</li>
<li><code>GuildSystem.ts</code>: 扩展纹章数据</li>
<li><code>GuildView.ts</code>: 添加纹章展示</li>
</ul>
<p><strong>文件</strong>: <code>LssProto.ts</code>, <code>GuildSystem.ts</code>, <code>GuildView.ts</code></p>
<hr>
<h3 id="b3-5-协议-212-213-角色称号-chartitle">B3-5: 协议 212-213 — 角色称号（CHARTITLE）</h3>
<p><strong>目标</strong>: 角色称号显示</p>
<p><strong>协议</strong>: <code>CHARTITLE_SEND(data)</code> → <code>CHARTITLE_RECV(data)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>LssProto.ts</code>: 添加称号协议</li>
<li><code>CharacterView.ts</code>: 称号标签展示</li>
</ul>
<p><strong>文件</strong>: <code>LssProto.ts</code>, <code>CharacterView.ts</code></p>
<hr>
<h3 id="b3-6-协议-218-219-宠物祝福-vb">B3-6: 协议 218-219 — 宠物祝福（VB）</h3>
<p><strong>目标</strong>: 宠物属性祝福</p>
<p><strong>协议</strong>: <code>VB_SEND(data)</code> → <code>VB_RECV(data)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>LssProto.ts</code>: 添加祝福协议</li>
<li><code>PetSystem.ts</code>: 扩展祝福属性</li>
<li><code>PetView.ts</code>: 祝福操作 UI</li>
</ul>
<p><strong>文件</strong>: <code>LssProto.ts</code>, <code>PetSystem.ts</code>, <code>PetView.ts</code></p>
<hr>
<h3 id="b3-7-协议-220-骑宠查询-ridequery">B3-7: 协议 220 — 骑宠查询（RIDEQUERY）</h3>
<p><strong>目标</strong>: 查询可骑乘宠物</p>
<p><strong>协议</strong>: <code>RIDEQUERY_SEND(data)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>LssProto.ts</code>: 添加查询方法</li>
<li><code>RideSystem.ts</code>: 扩展查询逻辑</li>
</ul>
<p><strong>文件</strong>: <code>LssProto.ts</code>, <code>RideSystem.ts</code></p>
<hr>
<h3 id="b3-8-协议-221-222-宠物皮肤-petskins">B3-8: 协议 221-222 — 宠物皮肤（PETSKINS）</h3>
<p><strong>目标</strong>: 宠物皮肤切换</p>
<p><strong>协议</strong>: <code>PETSKINS_SEND(data)</code> → <code>PETSKINS_RECV(data)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>LssProto.ts</code>: 添加皮肤协议</li>
<li><code>PetSystem.ts</code>: 扩展皮肤数据</li>
<li><code>PetView.ts</code>: 皮肤选择 UI</li>
</ul>
<p><strong>文件</strong>: <code>LssProto.ts</code>, <code>PetSystem.ts</code>, <code>PetView.ts</code></p>
<hr>
<h3 id="b3-9-协议-141-签到系统-signday">B3-9: 协议 141 — 签到系统（SIGNDAY）</h3>
<p><strong>目标</strong>: 月历签到奖励</p>
<p><strong>协议</strong>: <code>SIGNDAY_SEND(data)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li>新建 <code>game/SignInSystem.ts</code> — 签到记录</li>
<li>新建 <code>cocos/SignInView.ts</code> — 月历 UI</li>
<li><code>LssProto.ts</code>: 添加签到协议</li>
</ul>
<p><strong>文件</strong>: 新建 2 + 修改 1</p>
<hr>
<h3 id="b3-10-协议-138-百人斩-hundredkill">B3-10: 协议 138 — 百人斩（HUNDREDKILL）</h3>
<p><strong>目标</strong>: 100 人挑战模式</p>
<p><strong>协议</strong>: <code>HUNDREDKILL_RECV(data)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>LssProto.ts</code>: 添加接收处理</li>
<li><code>Battle.ts</code>: 扩展百人斩状态</li>
<li><code>BattleView.ts</code>: 百人斩 UI</li>
</ul>
<p><strong>文件</strong>: <code>LssProto.ts</code>, <code>Battle.ts</code>, <code>BattleView.ts</code></p>
<hr>
<h3 id="b3-11-协议-139-140-pk-列表-pklist">B3-11: 协议 139-140 — PK 列表（PKLIST）</h3>
<p><strong>目标</strong>: PK 排行榜</p>
<p><strong>协议</strong>: <code>PKLIST_SEND(data)</code> → <code>PKLIST_RECV(data)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>LssProto.ts</code>: 添加 PK 协议</li>
<li><code>RankingView.ts</code>: 添加 PK 排行标签</li>
</ul>
<p><strong>文件</strong>: <code>LssProto.ts</code>, <code>RankingView.ts</code></p>
<hr>
<h3 id="b3-12-协议-200-公告系统-dengon">B3-12: 协议 200 — 公告系统（DENGON）</h3>
<p><strong>目标</strong>: 服务器公告显示</p>
<p><strong>协议</strong>: <code>DENGON_RECV(data)</code></p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>LoginFlow.ts</code>: 添加公告接收处理</li>
<li>新建公告显示逻辑（滚动文字或弹窗）</li>
</ul>
<p><strong>文件</strong>: <code>LoginFlow.ts</code></p>
<hr>
<h3 id="b3-13-animation-组件">B3-13: Animation 组件</h3>
<p><strong>目标</strong>: 角色动作平滑切换</p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>CharacterView.ts</code> 用 tween 做 sprite 透明度交叉淡入淡出</li>
</ul>
<p><strong>文件</strong>: <code>CharacterView.ts</code></p>
<hr>
<h3 id="b3-14-particlesystem2d">B3-14: ParticleSystem2D</h3>
<p><strong>目标</strong>: 特效升级</p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>BattleAnim.ts</code> 伤害数字升级</li>
<li><code>WeatherSystem.ts</code> / <code>MapEffects.ts</code> 接入引擎粒子</li>
</ul>
<p><strong>文件</strong>: <code>BattleAnim.ts</code>, <code>WeatherSystem.ts</code>, <code>MapEffects.ts</code></p>
<hr>
<h3 id="b3-15-audiosource">B3-15: AudioSource</h3>
<p><strong>目标</strong>: 音频现代化</p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>SoundSystem.ts</code> 改用 <code>AudioSource</code> 组件</li>
</ul>
<p><strong>文件</strong>: <code>SoundSystem.ts</code></p>
<hr>
<h2 id="协议实现进度">协议实现进度</h2>
<pre><code>已实现: ████████████████░░░░░░░░░░░░░░ 28/98 (29%)

第一批后: ████████████████████████░░░░░░ 33/98 (34%)
├── +5: PS, MU, PETST, PET_ITEM, KN

第二批后: ██████████████████████████████░ 41/98 (42%)
├── +8: STREET_VENDOR, SHOPOK, + 已有扩展

第三批后: ████████████████████████████████ 56/98 (57%)
├── +15: ST/DT/FT, JOBDAILY, TEACHER, FAMILYBADGE,
│        CHARTITLE, VB, RIDEQUERY, PETSKINS,
│        SIGNDAY, HUNDREDKILL, PKLIST, DENGON
</code></pre><h2 id="执行顺序">执行顺序</h2>
<pre><code>Session 1: P0 — BattleView TODO + GameApp TODO + ProgressBar + PS + MU（1 周）
Session 2: P1-A — tween + ScrollView + Layout + RichText（1 周）
Session 3: P1-B — 摆摊 + 商城 + 宠物选择 + 宠物装备 + 改名（1 周）
Session 4: P2-A — 称号 + 任务日志 + 师徒 + 纹章 + 祝福 + 骑宠查询 + 皮肤（1-2 周）
Session 5: P2-B — 签到 + 百人斩 + PK + 公告 + Animation + Particle + Audio（1 周）
</code></pre><h2 id="完成度预估">完成度预估</h2>
<pre><code>当前:     ████████████████████░░░░░░░░░░ 75%

第一批后: ██████████████████████████░░░░ 85%  ← 可玩 MVP
第二批后: █████████████████████████████░ 95%  ← 功能完整
第三批后: ██████████████████████████████ 100% ← 完整复刻
</code></pre>]]></content:encoded>
      <pubDate>Fri, 12 Jun 2026 00:05:04 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/xieyi</guid>
      <category>石器时代</category>
      
    </item>
    <item>
      <title><![CDATA[石器时代客户端重构 — 完整实施方案]]></title>
      <link>https://758192.xyz/post/rebuild</link>
      <description><![CDATA[客户端重构方案]]></description>
      <content:encoded><![CDATA[<h1 id="石器时代客户端重构-完整实施方案">石器时代客户端重构 — 完整实施方案</h1>
<h2 id="context">Context</h2>
<p>原版 C++ 客户端有 64 个核心系统，当前 Cocos 客户端已实现 85 个模块（85/86 完成）。核心游戏循环（登录→移动→战斗→升级）已跑通，但缺少 18 个原版系统，协议只实现 ~20%。分 3 批推进。</p>
<h3 id="已完成-不在本计划中">已完成（不在本计划中）</h3>
<table>
<thead>
<tr>
<th>改动</th>
<th>状态</th>
</tr>
</thead>
<tbody><tr>
<td>SafeArea 组件 + Widget 对齐</td>
<td>✅</td>
</tr>
<tr>
<td>Canvas Widget _alignFlags 修复（45→15）</td>
<td>✅</td>
</tr>
<tr>
<td>移动系统重写（速度向量匹配原版 C++）</td>
<td>✅</td>
</tr>
<tr>
<td>A* 二叉堆优化</td>
<td>✅</td>
</tr>
<tr>
<td>MapRenderer 脏标记</td>
<td>✅</td>
</tr>
<tr>
<td>CharacterView 平滑渲染（像素坐标）</td>
<td>✅</td>
</tr>
</tbody></table>
<hr>
<h2 id="第一批-p0-战斗可玩-引擎规范化-1-周">第一批：P0 — 战斗可玩 + 引擎规范化（1 周）</h2>
<h3 id="b1-1-battleview-3-个-todo-战斗核心">B1-1: BattleView 3 个 TODO（战斗核心）</h3>
<p><strong>目标</strong>: 战斗中道具/宠物/技能可用</p>
<p><strong>涉及</strong>: BattleView.ts:286/298/310</p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>showItemSelect()</code>: 遍历 <code>this.equipSystem.inventory</code> 中的 consumable 物品，生成选择按钮</li>
<li><code>showPetSelect()</code>: 从 <code>this.battle.allyPets</code> 生成选择按钮</li>
<li><code>showSkillSelect()</code>: 从 SkillTable 查询宠物可用技能</li>
</ul>
<p><strong>文件</strong>: <code>BattleView.ts</code></p>
<hr>
<h3 id="b1-2-gameapp-3-个-todo-一行代码修复">B1-2: GameApp 3 个 TODO（一行代码修复）</h3>
<p><strong>目标</strong>: MainMenu skill 按钮连线、帮助/设置内容</p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>skill: () =&gt; { this.skillView?.toggle(); }</code>（SkillView 已初始化在 line 727）</li>
<li>帮助: <code>this.dialogView.show(&#39;帮助&#39;, &#39;实际帮助内容...&#39;)</code>（加载 DataStore 中的帮助文本）</li>
<li>设置: 创建 SettingsView 或接入 dialogView</li>
</ul>
<p><strong>文件</strong>: <code>GameApp.ts</code></p>
<hr>
<h3 id="b1-3-progressbar-组件-替代-graphics-进度条">B1-3: ProgressBar 组件 — 替代 Graphics 进度条</h3>
<p><strong>目标</strong>: StatusView 的 HP/MP/EXP 条用 ProgressBar</p>
<p><strong>方案</strong>:</p>
<ul>
<li>StatusView 中 <code>makeBar()</code> 方法改为创建 ProgressBar:<pre><code class="hljs language-typescript">const progressBar = barNode.addComponent(cc.ProgressBar);
progressBar.barMode = cc.ProgressBar.BarMode.HORIZONTAL;
progressBar.fillRange = 1;
// 刷新时: progressBar.progress = hp / maxHp
</code></pre></li>
<li>保留 Graphics 作为背景轨道，ProgressBar 作为填充层</li>
</ul>
<p><strong>文件</strong>: <code>StatusView.ts</code></p>
<hr>
<h2 id="第二批-p1-引擎优化-核心经济系统-2-周">第二批：P1 — 引擎优化 + 核心经济系统（2 周）</h2>
<h3 id="b2-1-tween-缓动系统-ui-面板切换动画">B2-1: tween 缓动系统 — UI 面板切换动画</h3>
<p><strong>目标</strong>: 面板打开/关闭滑入滑出，按钮点击反馈缩放</p>
<p><strong>涉及视图</strong>: 全部 34 个面板</p>
<p><strong>方案</strong>:</p>
<ul>
<li>所有面板的 <code>toggle()</code> / <code>show()</code> / <code>hide()</code> 方法中，用 <code>cc.tween</code> 替代直接设置 <code>active</code></li>
<li>示例 (InventoryView):<pre><code class="hljs language-typescript">toggleEquip(): void {
  cc.tween(this.node)
    .to(0.2, { scale: cc.v2(1.05, 1.05) })
    .to(0.1, { scale: cc.v2(1, 1) }, { easing: &#39;quadOut&#39; })
    .start();
  // ... 现有逻辑
}
</code></pre></li>
<li>BottomToolbar 按钮的 TOUCH_START/TOUCH_END 用 tween 做缩放反馈</li>
</ul>
<p><strong>文件</strong>: <code>assets/cocos/GameApp.ts</code> + 所有 View</p>
<hr>
<h3 id="b2-2-scrollview-layout-组件-长列表滚动-自动排列">B2-2: ScrollView + Layout 组件 — 长列表滚动 + 自动排列</h3>
<p><strong>目标</strong>: 聊天/道具/宠物列表支持滚动，装备槽位自动排列</p>
<p><strong>方案</strong>:</p>
<ul>
<li>ChatView: 消息容器挂载 <code>ScrollView</code> + <code>ScrollBar</code>，<code>inertia</code> 开启</li>
<li>InventoryView: 道具列表挂载 ScrollView，装备面板改用 Layout VERTICAL</li>
<li>PetView: 宠物列表改用 Layout + ScrollView</li>
<li>MainMenu: 菜单项改用 Layout</li>
<li>BattleView: 命令面板改用 Layout HORIZONTAL</li>
</ul>
<p><strong>文件</strong>: <code>ChatView.ts</code>, <code>InventoryView.ts</code>, <code>PetView.ts</code>, <code>MainMenu.ts</code>, <code>BattleView.ts</code></p>
<hr>
<h3 id="b2-3-richtext-组件-聊天消息格式化">B2-3: RichText 组件 — 聊天消息格式化</h3>
<p><strong>目标</strong>: 聊天消息中显示彩色稀有度文字、@提及高亮</p>
<p><strong>方案</strong>:</p>
<ul>
<li>ChatView 的 <code>refreshMessages()</code> 中，Label 替换为 RichText</li>
<li>构造 RichText 标签字符串: <code>&lt;color=#ff0000&gt;@玩家:&lt;/color&gt; 你好</code></li>
</ul>
<p><strong>文件</strong>: <code>ChatView.ts</code>, <code>game/ChatSystem.ts</code></p>
<hr>
<h3 id="b2-4-商人摆摊系统-street-vendor">B2-4: 商人摆摊系统（Street Vendor）</h3>
<p><strong>目标</strong>: 玩家间摆摊交易，20 物品栏</p>
<p><strong>原版参考</strong>: <code>systeminc/field.h</code> (Show_Sell_Item, Show_Vendor_Item)，20 个物品上限</p>
<p><strong>方案</strong>:</p>
<ul>
<li>新建 <code>StreetVendorView.ts</code> — 摊位 UI（商品列表 + 价格 + 购买按钮）</li>
<li>新建 <code>game/StreetVendorSystem.ts</code> — 摊位状态管理</li>
<li>协议: <code>STREET_VENDOR</code> 系列协议（创建/浏览/购买/关闭）</li>
<li>集成到 <code>GameApp.ts</code> + <code>GameClient.ts</code></li>
</ul>
<p><strong>文件</strong>: 新建 2 个文件 + 修改 3 个文件</p>
<hr>
<h3 id="b2-5-商城系统-cash-shop">B2-5: 商城系统（Cash Shop）</h3>
<p><strong>目标</strong>: 彩币购物车，多页商品浏览</p>
<p><strong>原版参考</strong>: <code>system/shop.cpp</code> — 5 页商品文件，购物车 15 件，MD5 校验</p>
<p><strong>方案</strong>:</p>
<ul>
<li>新建 <code>CashShopView.ts</code> — 商品列表 + 购物车 + 结算</li>
<li>新建 <code>game/CashShopSystem.ts</code> — 商品数据 + 购物车状态</li>
<li>协议: 商品列表请求/购买确认/余额查询</li>
</ul>
<p><strong>文件</strong>: 新建 2 个文件 + 修改 2 个文件</p>
<hr>
<h3 id="b2-6-宠物图鉴系统-pet-album">B2-6: 宠物图鉴系统（Pet Album）</h3>
<p><strong>目标</strong>: 570 种宠物收集册，8 个/页</p>
<p><strong>原版参考</strong>: <code>systeminc/menu.h</code> (PET_ALBUM, MAX_PET_KIND=570)</p>
<p><strong>方案</strong>:</p>
<ul>
<li>新建 <code>PetAlbumView.ts</code> — 分页网格显示，已收集/未收集状态</li>
<li>新建 <code>game/PetAlbumSystem.ts</code> — 收集记录 + 解锁条件</li>
<li>复用 <code>DataStore.enemyBase</code> 数据</li>
</ul>
<p><strong>文件</strong>: 新建 2 个文件 + 修改 1 个文件</p>
<hr>
<h2 id="第三批-p2-完整复刻-引擎升级-2-3-周">第三批：P2 — 完整复刻 + 引擎升级（2-3 周）</h2>
<h3 id="b3-1-拍卖行系统-auction">B3-1: 拍卖行系统（Auction）</h3>
<p><strong>目标</strong>: NPC 拍卖，出价/一口价/查看</p>
<p><strong>原版参考</strong>: <code>systeminc/lssproto_cli.h</code> — EDEN_AUCTION 协议</p>
<p><strong>方案</strong>:</p>
<ul>
<li>新建 <code>AuctionView.ts</code> — 拍卖列表 + 出价界面</li>
<li>新建 <code>game/AuctionSystem.ts</code> — 拍卖状态管理</li>
</ul>
<hr>
<h3 id="b3-2-签到系统-sign-in">B3-2: 签到系统（Sign-In）</h3>
<p><strong>目标</strong>: 月历签到奖励</p>
<p><strong>原版参考</strong>: <code>systeminc/CharSignDay.h</code> — 30 天月历 UI</p>
<p><strong>方案</strong>:</p>
<ul>
<li>新建 <code>SignInView.ts</code> — 月历网格 + 领取按钮</li>
<li>新建 <code>game/SignInSystem.ts</code> — 签到记录</li>
</ul>
<hr>
<h3 id="b3-3-转盘抽奖系统-turntable">B3-3: 转盘抽奖系统（Turntable）</h3>
<p><strong>目标</strong>: 10 格转盘动画 + 奖品</p>
<p><strong>原版参考</strong>: <code>systeminc/Turntable.h</code> — 指针旋转 + 速度控制</p>
<p><strong>方案</strong>:</p>
<ul>
<li>新建 <code>TurntableView.ts</code> — Canvas 绘制转盘 + tween 旋转动画</li>
<li>新建 <code>game/TurntableSystem.ts</code> — 奖品配置 + 结果处理</li>
</ul>
<hr>
<h3 id="b3-4-法宝合成系统-magic-item">B3-4: 法宝合成系统（Magic Item）</h3>
<p><strong>目标</strong>: 3 格合成界面 + 光环效果</p>
<p><strong>原版参考</strong>: <code>systeminc/magicitem.h</code> — 3-slot combination</p>
<p><strong>方案</strong>:</p>
<ul>
<li>新建 <code>MagicItemView.ts</code> — 合成槽 + 结果预览</li>
<li>复用 <code>ItemCrafting.ts</code> 合成逻辑</li>
</ul>
<hr>
<h3 id="b3-5-师徒系统-teacher">B3-5: 师徒系统（Teacher）</h3>
<p><strong>目标</strong>: 师徒关系 + 专属 UI</p>
<p><strong>原版参考</strong>: <code>systeminc/lssproto_cli.h</code> — TEACHER_SYSTEM 协议</p>
<p><strong>方案</strong>:</p>
<ul>
<li>新建 <code>TeacherView.ts</code> — 师徒列表 + 任务进度</li>
<li>新建 <code>game/TeacherSystem.ts</code> — 关系管理</li>
</ul>
<hr>
<h3 id="b3-6-家族进阶功能">B3-6: 家族进阶功能</h3>
<p><strong>目标</strong>: 家族纹章 + 庄园挑战 + 家族银行扩展</p>
<p><strong>原版参考</strong>: <code>systeminc/pc.h</code> — FAMILYBADGE, MANOR 系统</p>
<p><strong>方案</strong>:</p>
<ul>
<li>扩展 <code>GuildView.ts</code> — 纹章展示 + 庄园入口</li>
<li>扩展 <code>GuildSystem.ts</code> — 庄园挑战逻辑</li>
</ul>
<hr>
<h3 id="b3-7-animation-组件-角色-ui-平滑过渡">B3-7: Animation 组件 — 角色/UI 平滑过渡</h3>
<p><strong>目标</strong>: 角色动作间平滑切换</p>
<p><strong>方案</strong>:</p>
<ul>
<li><code>CharacterView.ts</code> 用 tween 做 sprite 透明度交叉淡入淡出</li>
<li>后续如需完整动画系统再引入 Animation Clip</li>
</ul>
<hr>
<h3 id="b3-8-particlesystem2d-特效升级">B3-8: ParticleSystem2D — 特效升级</h3>
<p><strong>方案</strong>:</p>
<ul>
<li><code>BattleAnim.ts</code> 伤害数字升级为 ParticleSystem2D</li>
<li><code>WeatherSystem.ts</code> / <code>MapEffects.ts</code> 接入引擎粒子</li>
</ul>
<hr>
<h3 id="b3-9-audiosource-音频现代化">B3-9: AudioSource — 音频现代化</h3>
<p><strong>方案</strong>:</p>
<ul>
<li><code>SoundSystem.ts</code> 改用 <code>AudioSource</code> 组件</li>
<li>统一 BGM/SFX 管理</li>
</ul>
<hr>
<h2 id="关键文件清单">关键文件清单</h2>
<table>
<thead>
<tr>
<th>优先级</th>
<th>改动文件</th>
<th>改动内容</th>
</tr>
</thead>
<tbody><tr>
<td><strong>P0</strong></td>
<td><code>BattleView.ts</code></td>
<td>3 个 TODO 实现（道具/宠物/技能）</td>
</tr>
<tr>
<td><strong>P0</strong></td>
<td><code>GameApp.ts</code></td>
<td>3 个 TODO 修复（技能/帮助/设置）</td>
</tr>
<tr>
<td><strong>P0</strong></td>
<td><code>StatusView.ts</code></td>
<td>ProgressBar 替代 Graphics 条</td>
</tr>
<tr>
<td><strong>P1</strong></td>
<td><code>GameApp.ts</code> + 所有 View</td>
<td>toggle/show/hide 加 tween 动画</td>
</tr>
<tr>
<td><strong>P1</strong></td>
<td><code>ChatView.ts</code>, <code>InventoryView.ts</code>, <code>PetView.ts</code></td>
<td>ScrollView + Layout</td>
</tr>
<tr>
<td><strong>P1</strong></td>
<td><code>ChatView.ts</code>, <code>game/ChatSystem.ts</code></td>
<td>RichText 聊天格式化</td>
</tr>
<tr>
<td><strong>P1</strong></td>
<td>新建 <code>StreetVendorView.ts</code>, <code>StreetVendorSystem.ts</code></td>
<td>商人摆摊</td>
</tr>
<tr>
<td><strong>P1</strong></td>
<td>新建 <code>CashShopView.ts</code>, <code>CashShopSystem.ts</code></td>
<td>商城</td>
</tr>
<tr>
<td><strong>P1</strong></td>
<td>新建 <code>PetAlbumView.ts</code>, <code>PetAlbumSystem.ts</code></td>
<td>宠物图鉴</td>
</tr>
<tr>
<td><strong>P2</strong></td>
<td>新建 <code>AuctionView.ts</code>, <code>AuctionSystem.ts</code></td>
<td>拍卖行</td>
</tr>
<tr>
<td><strong>P2</strong></td>
<td>新建 <code>SignInView.ts</code>, <code>SignInSystem.ts</code></td>
<td>签到</td>
</tr>
<tr>
<td><strong>P2</strong></td>
<td>新建 <code>TurntableView.ts</code>, <code>TurntableSystem.ts</code></td>
<td>转盘</td>
</tr>
<tr>
<td><strong>P2</strong></td>
<td>新建 <code>MagicItemView.ts</code></td>
<td>法宝合成</td>
</tr>
<tr>
<td><strong>P2</strong></td>
<td>新建 <code>TeacherView.ts</code>, <code>TeacherSystem.ts</code></td>
<td>师徒</td>
</tr>
<tr>
<td><strong>P2</strong></td>
<td>扩展 <code>GuildView.ts</code>, <code>GuildSystem.ts</code></td>
<td>家族进阶</td>
</tr>
<tr>
<td><strong>P2</strong></td>
<td><code>CharacterView.ts</code></td>
<td>tween 透明度过渡</td>
</tr>
<tr>
<td><strong>P2</strong></td>
<td><code>SoundSystem.ts</code></td>
<td>AudioSource 接入</td>
</tr>
<tr>
<td><strong>P2</strong></td>
<td><code>BattleAnim.ts</code>, <code>WeatherSystem.ts</code></td>
<td>ParticleSystem2D</td>
</tr>
</tbody></table>
<h2 id="执行顺序与并行度">执行顺序与并行度</h2>
<pre><code>Session 1: P0 — BattleView TODO + GameApp TODO + ProgressBar（1 周）
  └── 验证: 战斗中道具/宠物/技能可用，进度条正确显示

Session 2: P1-A — tween + ScrollView + Layout + RichText（1 周）
  └── 验证: 面板切换有动画，列表可滚动，聊天彩色文字

Session 3: P1-B — 商人摆摊 + 商城 + 宠物图鉴（1 周，可并行）
  └── 验证: 摆摊交易可用，商城浏览购买，图鉴收集

Session 4: P2-A — 拍卖行 + 签到 + 转盘 + 法宝 + 师徒（1-2 周）
  └── 验证: 各系统独立可用

Session 5: P2-B — 家族进阶 + Animation + Particle + Audio（1 周）
  └── 验证: 引擎组件全部接入
</code></pre><h2 id="完成度预估">完成度预估</h2>
<pre><code>当前: ████████████████████░░░░░░░░░░ 75%

第一批后: ██████████████████████████░░░░ 85%  ← 可玩 MVP
第二批后: █████████████████████████████░ 95%  ← 功能完整
第三批后: ██████████████████████████████ 100% ← 完整复刻
</code></pre>]]></content:encoded>
      <pubDate>Thu, 11 Jun 2026 23:30:52 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/rebuild</guid>
      <category>石器时代</category>
      
    </item>
    <item>
      <title><![CDATA[石器时代重构-客户端对比]]></title>
      <link>https://758192.xyz/post/diff</link>
      <description><![CDATA[客户端 vs Cocos Creator 引擎功能差距分析

Context

用户需要知道当前 TypeScript 客户端还有多少 Cocos Creator 引擎功能尚未使用。以下对比将引擎提供的 API 与客户端实际实现进行对照。
 
一、客户端已实现的功能

核心基础设施 (100% 完成)
| 类别 | 已实现 | 文件数 |
|------|--------|-]]></description>
      <content:encoded><![CDATA[<h1 id="客户端-vs-cocos-creator-引擎功能差距分析">客户端 vs Cocos Creator 引擎功能差距分析</h1>
<h2 id="context">Context</h2>
<p>用户需要知道当前 TypeScript 客户端还有多少 Cocos Creator 引擎功能尚未使用。以下对比将引擎提供的 API 与客户端实际实现进行对照。</p>
<hr>
<h2 id="一-客户端已实现的功能">一、客户端已实现的功能</h2>
<h3 id="核心基础设施-100-完成">核心基础设施 (100% 完成)</h3>
<table>
<thead>
<tr>
<th>类别</th>
<th>已实现</th>
<th>文件数</th>
</tr>
</thead>
<tbody><tr>
<td>Core (二进制/数据加载)</td>
<td>7/7</td>
<td>BinaryReader, AdrnLoader, MapLoader, PaletteLoader, RdDecoder, SpriteLoader</td>
</tr>
<tr>
<td>Data Tables (CSV 数据表)</td>
<td>16/16</td>
<td>Item, Enemy, Magic, Skill, Profession, Encounter, Mission, Group, Effect, Atom 等</td>
</tr>
<tr>
<td>Rendering (等距渲染)</td>
<td>3/3</td>
<td>MapRenderer, IsometricRenderer, BitmapCache</td>
</tr>
<tr>
<td>Networking (网络协议)</td>
<td>8/8</td>
<td>WebSocketClient, TeaCipher, LoginFlow, GameClient, Protocol 等</td>
</tr>
<tr>
<td>Game Systems (游戏逻辑)</td>
<td>32/32</td>
<td>Battle, PetSystem, Equipment, Party, Friend, Trading, Quest, Guild, Mail, Buff, Sound, Weather, WarpEffect, MiniGame, TouchController 等</td>
</tr>
</tbody></table>
<h3 id="cocos-视图-94-完成-7-个-todo">Cocos 视图 (94% 完成 — 7 个 TODO)</h3>
<table>
<thead>
<tr>
<th>文件</th>
<th>TODO 项目</th>
<th>状态</th>
</tr>
</thead>
<tbody><tr>
<td>GameApp.ts:694</td>
<td>MainMenu 中 skill 按钮未连接到 SkillView</td>
<td>空函数</td>
</tr>
<tr>
<td>GameApp.ts:696</td>
<td>帮助对话框显示 &quot;TODO: 帮助内容&quot;</td>
<td>占位文本</td>
</tr>
<tr>
<td>GameApp.ts:697</td>
<td>设置对话框显示 &quot;TODO: 系统设置&quot;</td>
<td>占位文本</td>
</tr>
<tr>
<td>GameApp.ts:826</td>
<td>BottomToolbar 装备按钮复用 InventoryView</td>
<td>无独立 EquipmentView</td>
</tr>
<tr>
<td>BattleView.ts:286</td>
<td>战斗中使用道具</td>
<td>&quot;待实现&quot;</td>
</tr>
<tr>
<td>BattleView.ts:298</td>
<td>战斗中切换宠物</td>
<td>&quot;待实现&quot;</td>
</tr>
<tr>
<td>BattleView.ts:310</td>
<td>战斗中宠物技能</td>
<td>&quot;待实现&quot;</td>
</tr>
</tbody></table>
<hr>
<h2 id="二-引擎有但客户端未使用的功能">二、引擎有但客户端未使用的功能</h2>
<h3 id="1-音频系统-部分使用">1. 音频系统 — 部分使用</h3>
<p><strong>引擎提供</strong>: <code>AudioSource</code> 组件、<code>AudioClip</code>、<code>AudioManager</code>（中央音频控制器，支持音量/音调控制）</p>
<p><strong>客户端现状</strong>: <code>game/SoundSystem.ts</code> 使用原生 <code>HTMLAudioElement</code>，未使用引擎的 AudioSource/AudioManager</p>
<p><strong>差距</strong>: 无法使用引擎的音频管理器特性（批量播放、音量混音、音频池）</p>
<h3 id="2-动画系统-完全未使用">2. 动画系统 — 完全未使用</h3>
<p><strong>引擎提供</strong>: <code>Animation</code> 组件、<code>AnimationClip</code>、曲线动画、Animation Graph (Marionette)、CrossFade、CubicSplineValue</p>
<p><strong>客户端现状</strong>: 角色动画通过手动切换 sprite frame 实现（CharacterView 中帧索引递增）</p>
<p><strong>差距</strong>:</p>
<ul>
<li>无法制作平滑的角色过渡动画（跑动↔待机↔受伤）</li>
<li>无法制作 UI 动画（菜单弹出、按钮缩放、面板滑动）</li>
<li>无法制作战斗特效动画（伤害数字弹出、状态图标闪烁）</li>
<li>无法使用曲线插值（缓入缓出）</li>
</ul>
<h3 id="3-ui-布局组件-完全未使用">3. UI 布局组件 — 完全未使用</h3>
<p><strong>引擎提供</strong>: Layout（水平/垂直/网格/自适应缩放）、ScrollView、PageView、Toggle/ToggleContainer、Slider、ProgressBar、EditBox、RichText、Button（4 态转换）</p>
<p><strong>客户端现状</strong>: 所有 UI 手动定位 + 手动拖拽（DragHelper）。InventoryView/PetView 等面板没有使用 Layout 或 ScrollView。</p>
<p><strong>差距</strong>:</p>
<ul>
<li>道具列表、宠物列表、聊天消息等长列表无法滚动</li>
<li>装备槽位无法自动排列（Layout 可自动处理）</li>
<li>等级进度条、经验条等手动用 Graphics 绘制，应改用 ProgressBar 组件</li>
<li>聊天输入框手动实现，应使用 EditBox</li>
<li>技能/职业树展示无法自动排列</li>
</ul>
<h3 id="4-粒子系统-部分使用">4. 粒子系统 — 部分使用</h3>
<p><strong>引擎提供</strong>: <code>ParticleSystem2D</code>（2D 粒子）、<code>ParticleSystem</code>（3D 粒子）、<code>MotionStreak</code>（拖尾效果）</p>
<p><strong>客户端现状</strong>: <code>game/WeatherSystem.ts</code> 和 <code>game/MapEffects.ts</code> 标记了&quot;粒子天气&quot;和&quot;粒子地图效果&quot;，但实际实现需查看具体代码。<code>game/WarpEffect.ts</code> 有转场动画效果。</p>
<p><strong>差距</strong>:</p>
<ul>
<li>战斗伤害数字/治疗数字目前可能是手动 DOM 动画，可用 ParticleSystem2D 做华丽效果</li>
<li>角色移动轨迹、技能释放效果可用 MotionStreak</li>
<li>天气效果（雨/雪/雾）可用引擎粒子系统</li>
</ul>
<h3 id="5-物理系统-完全未使用">5. 物理系统 — 完全未使用</h3>
<p><strong>引擎提供</strong>: <code>RigidBody2D</code>、<code>BoxCollider2D</code>、<code>CircleCollider2D</code>、<code>PolygonCollider2D</code>、9 种 Joint（Hinge/Distance/Spring/Mouse/Slider/Fixed/Relative/Wheel）</p>
<p><strong>客户端现状</strong>: 碰撞检测完全手动（GroundItemRenderer.hitTest、坐标距离判断）</p>
<p><strong>差距</strong>: 对 2D 等距 RPG 游戏来说物理引擎非必需，碰撞检测手动实现足够。此项<strong>可以跳过</strong>。</p>
<h3 id="6-资源加载系统-部分使用">6. 资源加载系统 — 部分使用</h3>
<p><strong>引擎提供</strong>: <code>Bundle</code> 系统、<code>resources.load()</code>、依赖管理、资源池、预加载/释放</p>
<p><strong>客户端现状</strong>: 手动 <code>fetchBinary()</code> + 自定义 <code>SpriteStore</code> 缓存。已实现 Range 请求优化。</p>
<p><strong>差距</strong>: 引擎的资源管线（下载→解析→缓存→释放）更完善，但客户端的自定义方案已能工作。此项<strong>可跳过</strong>。</p>
<h3 id="7-shader-material-完全未使用">7. Shader/Material — 完全未使用</h3>
<p><strong>引擎提供</strong>: Material、Pass、ProgramLibrary、RenderPipeline、ToneMapping</p>
<p><strong>客户端现状</strong>: 无自定义 shader，纯 sprite rendering</p>
<p><strong>差距</strong>: 如需高级视觉效果（屏幕特效、角色发光、水面波纹）需使用，但当前阶段非必需。<strong>可跳过</strong>。</p>
<h3 id="8-视频播放-未使用">8. 视频播放 — 未使用</h3>
<p><strong>引擎提供</strong>: <code>VideoPlayer</code> 组件、<code>VideoClip</code></p>
<p><strong>客户端现状</strong>: 无视频功能</p>
<p><strong>差距</strong>: 如有过场动画/宣传片需求才需要。<strong>非必需</strong>。</p>
<h3 id="9-webview-未使用">9. WebView — 未使用</h3>
<p><strong>引擎提供</strong>: <code>WebView</code> 组件</p>
<p><strong>客户端现状</strong>: 无 WebView</p>
<p><strong>差距</strong>: 如有用户协议/客服/外部链接内嵌才需要。<strong>非必需</strong>。</p>
<h3 id="10-骨骼动画-完全未使用">10. 骨骼动画 — 完全未使用</h3>
<p><strong>引擎提供</strong>: <code>Skeleton</code> 组件（Spine 运行时）、<code>ArmatureDisplay</code>（DragonBones）</p>
<p><strong>客户端现状</strong>: 所有角色/敌人用静态 sprite frame + 帧索引动画</p>
<p><strong>差距</strong>: 引擎已内置 Spine/DragonBones 支持。如果后续美术资源升级为骨骼动画（平滑动作），可以直接使用。<strong>长期有价值，当前可跳过</strong>。</p>
<h3 id="11-输入系统-部分使用">11. 输入系统 — 部分使用</h3>
<p><strong>引擎提供</strong>: <code>Input</code> 组件、<code>SystemEvent</code>（触摸/键盘/鼠标/手柄抽象）</p>
<p><strong>客户端现状</strong>: 使用 <code>cc.systemEvent</code>（SystemEvent）处理键盘，手动监听 touch/mouse 事件</p>
<p><strong>差距</strong>: 引擎的 Input 系统提供了按键映射、多触控追踪等能力。客户端的手动实现基本等价，但无法利用引擎的按键绑定系统。<strong>可跳过或逐步迁移</strong>。</p>
<h3 id="12-tween-缓动系统-完全未使用">12.  tween/缓动系统 — 完全未使用</h3>
<p><strong>引擎提供</strong>: <code>tween</code> API（.to/.by/.set/.call/.delay）、48 种缓动函数（quad/cubic/quint/sine/expo/circ/elastic/bounce）</p>
<p><strong>客户端现状</strong>: 无缓动动画，UI 切换全部瞬间完成</p>
<p><strong>差距</strong>:</p>
<ul>
<li>面板打开/关闭的滑入滑出动画</li>
<li>按钮点击反馈动画</li>
<li>伤害数字弹跳动画</li>
<li>角色移动插值</li>
</ul>
<h3 id="13-富文本-未使用">13. 富文本 — 未使用</h3>
<p><strong>引擎提供</strong>: <code>RichText</code> 组件（HTML-like 标签格式化文本）</p>
<p><strong>客户端现状</strong>: 聊天消息使用纯文本 Label</p>
<p><strong>差距</strong>: 聊天中@提及高亮、彩色稀有度文字、链接点击等需要用 RichText。<strong>值得实现</strong>。</p>
<h3 id="14-调试工具-部分使用">14. 调试工具 — 部分使用</h3>
<p><strong>引擎提供</strong>: <code>Profiler</code> 组件（帧率/渲染计数器）、<code>debug-view</code></p>
<p><strong>客户端现状</strong>: 大量 console.log 调试，无引擎 Profiler</p>
<p><strong>差距</strong>: 可启用引擎 Profiler 监控性能。当前阶段可跳过。</p>
<h3 id="15-安全区域-未使用">15. 安全区域 — 未使用</h3>
<p><strong>引擎提供</strong>: <code>SafeArea</code> 组件</p>
<p><strong>客户端现状</strong>: 手动计算（通过 cc.view.getSafeAreaRect()）</p>
<p><strong>差距</strong>: 引擎的 SafeArea 组件可以直接挂在节点上自动收缩到安全区域内，比手动计算更安全。<strong>建议实现</strong>。</p>
<h3 id="16-tmx-tiled-地图-未使用">16. TMX/Tiled 地图 — 未使用</h3>
<p><strong>引擎提供</strong>: <code>TiledMap</code>、<code>TiledLayer</code>、<code>TiledObjectGroup</code></p>
<p><strong>客户端现状</strong>: 自定义 <code>.dat</code> 格式地图</p>
<p><strong>差距</strong>: 引擎已支持标准 Tiled 编辑器格式，但当前自定义格式已能工作。<strong>如后续改用 Tiled 编辑器可考虑</strong>。</p>
<hr>
<h2 id="三-差距优先级排序">三、差距优先级排序</h2>
<h3 id="p0-立即需要-直接影响玩家体验">P0 — 立即需要（直接影响玩家体验）</h3>
<ol>
<li><strong>tween 缓动系统</strong> — UI 面板切换、按钮交互、战斗特效需要动画</li>
<li><strong>Layout 组件</strong> — 列表类 UI（道具/宠物/技能）需要自动排列</li>
<li><strong>ScrollView 组件</strong> — 聊天消息、道具列表需要滚动</li>
<li><strong>RichText 组件</strong> — 聊天消息格式化（稀有度颜色、@提及高亮）</li>
<li><strong>SafeArea 组件</strong> — 灵动岛/刘海遮挡问题</li>
</ol>
<h3 id="p1-近期需要">P1 — 近期需要</h3>
<ol start="6">
<li><strong>Animation 组件</strong> — 角色待机/跑动平滑过渡，UI 动效</li>
<li><strong>ProgressBar 组件</strong> — HP/MP/经验条用 ProgressBar 替代 Graphics</li>
<li><strong>EditBox 组件</strong> — 聊天输入框、好友搜索等</li>
</ol>
<h3 id="p2-长期优化">P2 — 长期优化</h3>
<ol start="9">
<li><strong>ParticleSystem2D</strong> — 战斗特效、天气效果</li>
<li><strong>Spine/DragonBones</strong> — 骨骼动画（美术升级时）</li>
<li><strong>AudioSource/AudioManager</strong> — 音频管理现代化</li>
</ol>
<h3 id="p3-非必需">P3 — 非必需</h3>
<ol start="12">
<li><strong>物理系统</strong> — 2D RPG 不需要</li>
<li><strong>VideoPlayer/WebView</strong> — 视需求添加</li>
<li><strong>TMX/Tiled</strong> — 已有自定义格式工作正常</li>
<li><strong>Shader/Material</strong> — 后期优化时考虑</li>
<li><strong>Profiler</strong> — 性能分析用</li>
</ol>
<hr>
<h2 id="四-关键文件对照">四、关键文件对照</h2>
<table>
<thead>
<tr>
<th>引擎组件</th>
<th>客户端替代方案</th>
<th>差距影响</th>
</tr>
</thead>
<tbody><tr>
<td>tween API</td>
<td>无</td>
<td>P0 — UI 体验粗糙</td>
</tr>
<tr>
<td>Layout</td>
<td>手动 setPosition</td>
<td>P0 — 列表无法自适应</td>
</tr>
<tr>
<td>ScrollView</td>
<td>无</td>
<td>P0 — 长列表溢出屏幕</td>
</tr>
<tr>
<td>RichText</td>
<td>Label 纯文本</td>
<td>P1 — 聊天无法格式化</td>
</tr>
<tr>
<td>SafeArea</td>
<td>手动计算 margin</td>
<td>P0 — 灵动岛遮挡</td>
</tr>
<tr>
<td>Animation</td>
<td>手动帧切换</td>
<td>P1 — 无平滑过渡</td>
</tr>
<tr>
<td>ProgressBar</td>
<td>Graphics 手动绘制</td>
<td>P1 — 重复造轮子</td>
</tr>
<tr>
<td>EditBox</td>
<td>手动 input 监听</td>
<td>P1 — 输入体验不一致</td>
</tr>
<tr>
<td>ParticleSystem2D</td>
<td>WeatherSystem.ts 占位</td>
<td>P2 — 特效质量</td>
</tr>
<tr>
<td>AudioSource</td>
<td>HTMLAudioElement</td>
<td>P2 — 音频管理简陋</td>
</tr>
<tr>
<td>Spine Skeleton</td>
<td>静态 sprite</td>
<td>P2 — 动画质量</td>
</tr>
</tbody></table>
]]></content:encoded>
      <pubDate>Thu, 11 Jun 2026 15:44:05 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/diff</guid>
      <category>石器时代</category>
      
    </item>
    <item>
      <title><![CDATA[石器时代重构-6.11-missionb]]></title>
      <link>https://758192.xyz/post/sa611-mission-b</link>
      <description><![CDATA[重构日记6.11]]></description>
      <content:encoded><![CDATA[<h1 id="session-b-任务清单">Session-B 任务清单</h1>
<p><strong>分支</strong>: <code>claude-session-b/skill-pet-system</code>
<strong>负责范围</strong>: Phase 2 技能系统 + Phase 4 宠物系统完善</p>
<hr>
<h2 id="phase-2-技能系统-p0">Phase 2: 技能系统（P0）</h2>
<h3 id="2-1-玩家技能ui">2.1 玩家技能UI</h3>
<p><strong>文件</strong>: 新建 <code>assets/cocos/SkillView.ts</code>, 修改 <code>assets/cocos/GameApp.ts</code></p>
<h4 id="2-1-1-技能列表窗口">2.1.1 技能列表窗口</h4>
<ul>
<li><input disabled="" type="checkbox"> 新建 <code>SkillView.ts</code> — 技能查看/学习窗口</li>
<li><input disabled="" type="checkbox"> 窗口结构: 标题栏(可拖拽) + 分隔线 + 技能列表 + 技能详情</li>
<li><input disabled="" type="checkbox"> 已学技能列表: 显示名称、等级、描述、当前效果</li>
<li><input disabled="" type="checkbox"> 可学习技能列表: 在NPC处显示可学习的技能</li>
<li><input disabled="" type="checkbox"> 技能升级按钮: 发送 <code>sendSkillUpgrade(ws, skillId)</code> 协议</li>
<li><input disabled="" type="checkbox"> 参考现有 View 模式（InventoryView/PetView 的风格）</li>
</ul>
<p><strong>数据结构参考</strong> (<code>assets/game/ProfessionSystem.ts</code> 已有):</p>
<pre><code class="hljs language-typescript">interface Skill {
  id: number;
  name: string;
  level: number;
  maxLevel: number;
  description: string;
  effect: string;
  cost: number;  // 学习/升级消耗
}
</code></pre><h4 id="2-1-2-技能快捷键栏">2.1.2 技能快捷键栏</h4>
<ul>
<li><input disabled="" type="checkbox"> 在 <code>BottomToolbar.ts</code> 中添加技能快捷键区域</li>
<li><input disabled="" type="checkbox"> 支持配置最多4个技能快捷键</li>
<li><input disabled="" type="checkbox"> 战斗中点击快捷键直接使用技能</li>
</ul>
<h3 id="2-2-宠物技能ui">2.2 宠物技能UI</h3>
<p><strong>文件</strong>: 新建 <code>assets/cocos/PetSkillView.ts</code>, 修改 <code>assets/cocos/PetView.ts</code></p>
<h4 id="2-2-1-宠物技能列表">2.2.1 宠物技能列表</h4>
<ul>
<li><input disabled="" type="checkbox"> 新建 <code>PetSkillView.ts</code> — 宠物技能查看窗口</li>
<li><input disabled="" type="checkbox"> 在 <code>PetView</code> 的宠物详情页添加&quot;技能&quot;按钮</li>
<li><input disabled="" type="checkbox"> 技能列表: 显示每个技能的名称、类型、描述、威力</li>
<li><input disabled="" type="checkbox"> 技能类型分类: 攻击型/防御型/特殊型</li>
</ul>
<p><strong>原版宠物技能类型参考</strong> (<code>stoneage/client-8.5/.../pet_skillinfo.h</code>):</p>
<pre><code>PETSKILL_NORMALATTACK(1)  PETSKILL_NORMALGUARD(2)   PETSKILL_GUARDBREAK(3)
PETSKILL_CONTINUATIONATTACK(10-13)  PETSKILL_GUARDIAN(20)  PETSKILL_CHARGE(30-31)
PETSKILL_MIGHTY(40-41)  PETSKILL_POWERBALANCE(50-52)  PETSKILL_POISON_ATTACK(60-61)
PETSKILL_STONE(80)  PETSKILL_CONFUSION_ATTACK(90)  PETSKILL_DRUNK_ATTACK(100)
PETSKILL_SLEEP_ATTACK(110)  PETSKILL_EARTHROUND(120)  PETSKILL_Abduct(130)
PETSKILL_STEAL(140)  PETSKILL_NOGUARD(150-152)  PETSKILL_MERGE(200-201)
PETSKILL_ALCHEMIST(202)  PETSKILL_INSLAY(572)  PETSKILL_FIXITEM(540/664)
PETSKILL_INTENSIFY(650)  PETSKILL_UPINSLAY(651)  PETSKILL_CALLBUS(668)
</code></pre><h4 id="2-2-2-宠物技能学习">2.2.2 宠物技能学习</h4>
<ul>
<li><input disabled="" type="checkbox"> 在NPC处学习宠物技能的交互窗口</li>
<li><input disabled="" type="checkbox"> 技能遗忘确认对话框</li>
<li><input disabled="" type="checkbox"> 发送对应 WN 协议响应</li>
</ul>
<hr>
<h2 id="phase-4-宠物系统完善-p1">Phase 4: 宠物系统完善（P1）</h2>
<h3 id="4-1-宠物完整操作">4.1 宠物完整操作</h3>
<p><strong>文件</strong>: <code>assets/cocos/PetView.ts</code></p>
<h4 id="4-1-1-宠物改名">4.1.1 宠物改名</h4>
<ul>
<li><input disabled="" type="checkbox"> 在宠物详情页添加&quot;改名&quot;按钮</li>
<li><input disabled="" type="checkbox"> 弹出输入框（使用 Cocos Label + 键盘输入处理）</li>
<li><input disabled="" type="checkbox"> 发送 <code>KN</code> 协议: <code>old_lssproto_KN_send(fd, havepetindex, data)</code></li>
<li><input disabled="" type="checkbox"> 更新宠物显示名称</li>
</ul>
<h4 id="4-1-2-宠物属性加点">4.1.2 宠物属性加点</h4>
<ul>
<li><input disabled="" type="checkbox"> 升级后显示可分配属性点数量</li>
<li><input disabled="" type="checkbox"> 加点面板: HP / 攻击 / 防御 / 敏捷 四个选项</li>
<li><input disabled="" type="checkbox"> 每个属性显示当前值和可加点数</li>
<li><input disabled="" type="checkbox"> 发送对应协议分配属性点</li>
</ul>
<h4 id="4-1-3-宠物合成">4.1.3 宠物合成</h4>
<ul>
<li><input disabled="" type="checkbox"> 新建宠物合成选择窗口</li>
<li><input disabled="" type="checkbox"> 选择两只宠物进行合成</li>
<li><input disabled="" type="checkbox"> 显示合成结果预览（可能的后代属性范围）</li>
<li><input disabled="" type="checkbox"> 确认合成按钮</li>
</ul>
<h3 id="4-2-骑乘系统">4.2 骑乘系统</h3>
<p><strong>文件</strong>: 新建 <code>assets/cocos/RideView.ts</code>（<code>RideSystem.ts</code> 已有数据层）</p>
<h4 id="4-2-1-骑乘按钮">4.2.1 骑乘按钮</h4>
<ul>
<li><input disabled="" type="checkbox"> 新建 <code>RideView.ts</code> — 骑乘状态管理</li>
<li><input disabled="" type="checkbox"> 在 <code>BottomToolbar</code> 或 <code>StatusView</code> 中添加骑乘按钮</li>
<li><input disabled="" type="checkbox"> 显示当前骑乘状态（骑乘中/下马状态）</li>
<li><input disabled="" type="checkbox"> 切换骑乘/下马状态</li>
<li><input disabled="" type="checkbox"> 骑乘时角色外观变化（使用 RideSystem 中的数据）</li>
<li><input disabled="" type="checkbox"> 发送对应协议切换状态</li>
</ul>
<hr>
<h2 id="技术规范">技术规范</h2>
<ol>
<li><strong>Layer</strong>: 所有 <code>new cc.Node()</code> 创建的子节点必须 <code>node.layer = 1 &lt;&lt; 25</code></li>
<li><strong>UITransform</strong>: 所有 UI 子节点必须 <code>addComponent(UITransform)</code></li>
<li><strong>拖拽</strong>: 所有弹窗窗口添加 <code>titleBar</code> + <code>makeDraggable()</code></li>
<li><strong>代码风格</strong>: 遵循 <code>COCOS_STYLE_GUIDE.md</code> — 动态创建UI节点，不使用预制体</li>
<li><strong>无注释</strong>: 命名即文档，只在非显而易见处写注释</li>
</ol>
<h2 id="依赖关系">依赖关系</h2>
<ul>
<li>Phase 2.1 需要 <code>GameApp.ts</code> 中注册 SkillView（需要 session-a 先完成 BottomToolbar 修改）</li>
<li>Phase 4.1 依赖 <code>PetView.ts</code> 的基础结构（已存在）</li>
<li>与 session-a 无直接代码冲突，可并行开发</li>
</ul>
<h2 id="commit-格式">Commit 格式</h2>
<pre><code>[session-b] feat: 简短描述
</code></pre>]]></content:encoded>
      <pubDate>Thu, 11 Jun 2026 14:04:09 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/sa611-mission-b</guid>
      <category>石器时代</category>
      
    </item>
    <item>
      <title><![CDATA[石器时代重构-6.10]]></title>
      <link>https://758192.xyz/post/sa610-mission-1</link>
      <description><![CDATA[重构日记6.10]]></description>
      <content:encoded><![CDATA[<p><strong>分支</strong>: <code>claude-session-a/battle-skill-item-pet-system</code>
<strong>负责范围</strong>: Phase 1 战斗系统 + Phase 3 物品交互</p>
<hr>
<h2 id="phase-1-战斗系统完善-p0">Phase 1: 战斗系统完善（P0）</h2>
<h3 id="1-1-完整战斗指令ui">1.1 完整战斗指令UI</h3>
<p><strong>文件</strong>: <code>assets/cocos/BattleView.ts</code>, <code>assets/game/Battle.ts</code>, <code>assets/net/ProtocolParser.ts</code></p>
<h4 id="1-1-1-战斗指令面板重构">1.1.1 战斗指令面板重构</h4>
<ul>
<li><input disabled="" type="checkbox"> 将现有3个按钮（攻击/防御/逃跑）扩展为6个：攻击、防御、道具、宠物、技能、逃跑</li>
<li><input disabled="" type="checkbox"> 点击&quot;攻击&quot;后弹出敌方目标选择面板（列出所有敌方角色，带HP信息）</li>
<li><input disabled="" type="checkbox"> 点击&quot;道具&quot;后弹出背包道具选择面板（显示可用道具列表）</li>
<li><input disabled="" type="checkbox"> 点击&quot;宠物&quot;后弹出宠物选择面板（显示我方宠物列表，可切换出战宠物）</li>
<li><input disabled="" type="checkbox"> 点击&quot;技能&quot;后弹出宠物技能选择面板（显示当前宠物的技能列表）</li>
<li><input disabled="" type="checkbox"> 每个子面板需要有&quot;返回&quot;按钮回到主指令面板</li>
</ul>
<p><strong>协议发送</strong>:</p>
<ul>
<li>攻击: <code>BattleAction.ATTACK|targetBid|0|0|</code></li>
<li>防御: <code>BattleAction.DEFEND|0|0|0|</code></li>
<li>道具: <code>BattleAction.ITEM|targetBid|0|itemSlot|</code></li>
<li>宠物: <code>BattleAction.PET_ATTACK|targetBid|skillId|0|</code></li>
<li>技能: <code>BattleAction.SKILL|targetBid|skillId|0|</code></li>
<li>逃跑: <code>BattleAction.ESCAPE|0|0|0|</code></li>
</ul>
<h4 id="1-1-2-战斗角色展示">1.1.2 战斗角色展示</h4>
<ul>
<li><input disabled="" type="checkbox"> 敌方角色区域（右上）: 显示每个敌人的名称、等级、HP条</li>
<li><input disabled="" type="checkbox"> 我方角色区域（左下）: 显示玩家名称、HP/MP条 + 出战宠物名称、HP条</li>
<li><input disabled="" type="checkbox"> HP条使用不同颜色: HP满=绿色, HP低=红色</li>
<li><input disabled="" type="checkbox"> 角色死亡时显示灰色/删除线标记</li>
</ul>
<h4 id="1-1-3-战斗日志完善">1.1.3 战斗日志完善</h4>
<ul>
<li><input disabled="" type="checkbox"> 多行滚动日志（最多20行，显示最近8行）</li>
<li><input disabled="" type="checkbox"> 不同颜色区分消息类型:<ul>
<li>普通消息: 白色</li>
<li>伤害: 红色</li>
<li>治疗: 绿色</li>
<li>状态变化: 紫色</li>
<li>系统提示: 黄色</li>
</ul>
</li>
<li><input disabled="" type="checkbox"> 回合开始时显示 <code>--- 第 N 回合 ---</code></li>
</ul>
<h4 id="1-1-4-战斗协议完善">1.1.4 战斗协议完善</h4>
<ul>
<li><input disabled="" type="checkbox"> <code>ProtocolParser.ts</code> 中完善 <code>parseBattleCommand</code> 的 BC/BP/BA/BU 解析</li>
<li><input disabled="" type="checkbox"> <code>Battle.ts</code> 中增加 <code>sendItem</code>, <code>sendPetSwitch</code>, <code>sendPetSkill</code> 方法</li>
<li><input disabled="" type="checkbox"> 处理战斗中的 HP 实时更新（从 BA 协议解析）</li>
</ul>
<h3 id="1-2-战斗动画与特效">1.2 战斗动画与特效</h3>
<p><strong>文件</strong>: 新建 <code>assets/cocos/BattleAnim.ts</code>, 修改 <code>BattleView.ts</code></p>
<h4 id="1-2-1-伤害数字弹出">1.2.1 伤害数字弹出</h4>
<ul>
<li><input disabled="" type="checkbox"> 创建 floating text 动画节点</li>
<li><input disabled="" type="checkbox"> 攻击命中时在被攻击者位置弹出红色伤害数字</li>
<li><input disabled="" type="checkbox"> 治疗时弹出绿色治疗数字</li>
<li><input disabled="" type="checkbox"> MISS 时弹出灰色 &quot;MISS&quot; 文字</li>
</ul>
<h4 id="1-2-2-状态效果显示">1.2.2 状态效果显示</h4>
<ul>
<li><input disabled="" type="checkbox"> 中毒/睡眠/混乱/眩晕 状态图标显示在角色旁边</li>
<li><input disabled="" type="checkbox"> 状态生效/解除时在日志中显示对应颜色的文字</li>
</ul>
<hr>
<h2 id="phase-3-物品交互完善-p1">Phase 3: 物品交互完善（P1）</h2>
<h3 id="3-1-地面物品拾取-丢弃">3.1 地面物品拾取/丢弃</h3>
<p><strong>文件</strong>: <code>assets/cocos/MapRenderer.ts</code>, <code>assets/cocos/InputController.ts</code>, <code>assets/cocos/GameApp.ts</code></p>
<h4 id="3-1-1-地面物品渲染">3.1.1 地面物品渲染</h4>
<ul>
<li><input disabled="" type="checkbox"> 在 <code>GameApp.ts</code> 中处理 <code>CA</code> 协议返回的 <code>ItemObjData</code> 和 <code>GoldObjData</code></li>
<li><input disabled="" type="checkbox"> 在地图上绘制物品图标（使用 <code>adrnIndex</code> 中的 sprite）</li>
<li><input disabled="" type="checkbox"> 物品名称悬浮提示（鼠标悬停/触摸时显示）</li>
<li><input disabled="" type="checkbox"> 金币用特殊图标显示</li>
</ul>
<h4 id="3-1-2-拾取交互">3.1.2 拾取交互</h4>
<ul>
<li><input disabled="" type="checkbox"> 点击地面物品弹出拾取确认窗口</li>
<li><input disabled="" type="checkbox"> 发送 <code>PI</code> 协议拾取: <code>sendPickItem(ws, x, y, dir)</code></li>
<li><input disabled="" type="checkbox"> 发送 <code>DI</code> 协议丢弃: <code>sendDropItem(ws, x, y, itemIndex)</code></li>
<li><input disabled="" type="checkbox"> 发送 <code>DG</code> 协议丢弃金币: 需要新建 <code>sendDropGold</code> 函数</li>
</ul>
<h3 id="3-2-物品详情">3.2 物品详情</h3>
<p><strong>文件</strong>: <code>assets/cocos/InventoryView.ts</code></p>
<h4 id="3-2-1-物品属性面板">3.2.1 物品属性面板</h4>
<ul>
<li><input disabled="" type="checkbox"> 点击背包中的物品弹出详情面板</li>
<li><input disabled="" type="checkbox"> 显示: 名称、类型、等级、耐久度、属性、描述</li>
<li><input disabled="" type="checkbox"> 操作按钮: 使用（消耗品）/ 装备（装备品）/ 丢弃</li>
<li><input disabled="" type="checkbox"> 装备后更新 EquipmentSystem 状态</li>
</ul>
<h4 id="3-2-2-物品堆叠">3.2.2 物品堆叠</h4>
<ul>
<li><input disabled="" type="checkbox"> 同类物品合并显示（名称+数量）</li>
<li><input disabled="" type="checkbox"> 拆分堆叠功能（输入拆分数量）</li>
</ul>
<h3 id="3-3-银行-仓库">3.3 银行/仓库</h3>
<p><strong>文件</strong>: 新建 <code>assets/cocos/BankView.ts</code>（<code>ItemBank.ts</code> 已有数据层）</p>
<ul>
<li><input disabled="" type="checkbox"> 银行窗口UI（标题栏可拖拽）</li>
<li><input disabled="" type="checkbox"> 左侧: 银行存款列表</li>
<li><input disabled="" type="checkbox"> 右侧: 背包物品列表（可双击存入）</li>
<li><input disabled="" type="checkbox"> 存款/取款按钮</li>
<li><input disabled="" type="checkbox"> 与 <code>GameClient</code> 连接发送对应协议</li>
</ul>
<hr>
<h2 id="技术规范">技术规范</h2>
<ol>
<li><strong>Layer</strong>: 所有 <code>new cc.Node()</code> 创建的子节点必须 <code>node.layer = 1 &lt;&lt; 25</code></li>
<li><strong>UITransform</strong>: 所有 UI 子节点必须 <code>addComponent(UITransform)</code></li>
<li><strong>拖拽</strong>: 所有弹窗窗口添加 <code>titleBar</code> + <code>makeDraggable()</code></li>
<li><strong>协议</strong>: 保持 <code>|</code> 分隔字段格式</li>
<li><strong>无注释</strong>: 命名即文档，只在非显而易见处写注释</li>
</ol>
<h2 id="commit-格式">Commit 格式</h2>
<pre><code>[session-a] feat: 简短描述
</code></pre>]]></content:encoded>
      <pubDate>Thu, 11 Jun 2026 14:02:38 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/sa610-mission-1</guid>
      <category>石器时代</category>
      
    </item>
    <item>
      <title><![CDATA[石器时代重构-6.11]]></title>
      <link>https://758192.xyz/post/sa611</link>
      <description><![CDATA[重构日记6.11]]></description>
      <content:encoded><![CDATA[<h1 id="开发进度报告-2026-06-11">开发进度报告 - 2026-06-11</h1>
<h2 id="全局状态">全局状态</h2>
<h3 id="分支与-worktree-设置">分支与 Worktree 设置</h3>
<p>三个 session 现在各自拥有独立的 worktree 目录：</p>
<table>
<thead>
<tr>
<th>Session</th>
<th>Worktree 目录</th>
<th>分支</th>
<th>当前进度</th>
</tr>
</thead>
<tbody><tr>
<td>session-a</td>
<td><code>~/Projects/sa-session-a/</code></td>
<td><code>claude-session-a/battle-skill-item-pet-system</code></td>
<td>Phase 1 ✅ + Phase 3 ✅</td>
</tr>
<tr>
<td>session-b</td>
<td><code>~/Projects/sa-session-b/</code></td>
<td><code>claude-session-b/skill-pet-system</code></td>
<td>Phase 2 + Phase 4</td>
</tr>
<tr>
<td>session-c</td>
<td><code>~/Projects/sa-session-c/</code></td>
<td><code>claude-session-c/social-world-interact</code></td>
<td>Phase 5 + Phase 6</td>
</tr>
</tbody></table>
<p>⚠️ <strong>注意</strong>: 三个分支目前指向同一个 commit (<code>b5459ae</code>)。后续各自提交的代码会逐步分离。</p>
<h3 id="如何同步代码">如何同步代码</h3>
<p>当 session-a 提交了新代码后，session-b/c 可以通过以下方式同步：</p>
<pre><code class="hljs language-bash"># 在 session-b 或 session-c 的 worktree 目录下
git fetch origin
git merge origin/claude-session-a/battle-skill-item-pet-system
</code></pre><p>合并时如果有冲突，用 <code>--ours</code> / <code>--theirs</code> 解决即可。</p>
<hr>
<h2 id="session-a-已完成">Session-A 已完成</h2>
<h3 id="phase-1-核心战斗系统">Phase 1: 核心战斗系统 ✅</h3>
<p><strong>新增文件</strong>:</p>
<ul>
<li><code>assets/cocos/BattleView.ts</code> — 完整战斗UI（攻击/防御/道具/宠物/技能/逃跑）</li>
<li><code>assets/cocos/BattleCharaRenderer.ts</code> — 战斗角色渲染（HP条/状态标记）</li>
</ul>
<p><strong>修改文件</strong>:</p>
<ul>
<li><code>assets/net/LssProto.ts</code> — 新增 BU_RECV(15) 协议、sendUseItem/sendPetTurn/sendPetSkill</li>
<li><code>assets/net/ProtocolParser.ts</code> — 完善 BC/BP/BU 协议解析</li>
<li><code>assets/game/Battle.ts</code> — 完善战斗状态机、解析服务端战斗数据</li>
<li><code>assets/cocos/GameApp.ts</code> — 集成 BattleView、B键切换战斗面板</li>
</ul>
<h3 id="phase-3-物品交互系统">Phase 3: 物品交互系统 ✅</h3>
<p><strong>新增文件</strong>:</p>
<ul>
<li><code>assets/cocos/GroundItemRenderer.ts</code> — 地面物品渲染（CA协议解析后的ItemObjData/GoldObjData可视化）</li>
<li><code>assets/cocos/GroundItemPickupView.ts</code> — 地面物品拾取/丢弃确认弹窗</li>
<li><code>assets/cocos/BankView.ts</code> — 银行/仓库窗口（个人+家族仓库，金币存取）</li>
</ul>
<p><strong>修改文件</strong>:</p>
<ul>
<li><code>assets/cocos/InventoryView.ts</code> — 添加物品详情面板、使用/装备/丢弃/拆分按钮</li>
<li><code>assets/cocos/InputController.ts</code> — 添加 getGroundItemHit 回调，点击地面物品检测</li>
<li><code>assets/cocos/GameApp.ts</code> — 集成地面物品点击/拾取/丢弃逻辑、N键打开银行</li>
<li><code>assets/net/LssProto.ts</code> — 新增 DG_RECV(20) 协议、sendDropGold</li>
</ul>
<hr>
<h2 id="session-b-待完成">Session-B 待完成</h2>
<h3 id="phase-2-技能系统">Phase 2: 技能系统</h3>
<p><strong>目标文件</strong>:</p>
<ul>
<li><code>assets/cocos/SkillView.ts</code> — 已有骨架，需完善玩家技能列表/升级UI</li>
<li><code>assets/cocos/PetSkillView.ts</code> — 新建，宠物技能查看/学习</li>
<li><code>assets/cocos/PetView.ts</code> — 添加&quot;技能&quot;标签页入口</li>
<li><code>assets/game/SkillSystem.ts</code> — 已有数据层，确认技能定义完整性</li>
<li><code>assets/net/LssProto.ts</code> — 确认 SK(技能升级) 协议实现</li>
</ul>
<p><strong>功能清单</strong>:</p>
<ul>
<li><input disabled="" type="checkbox"> 技能列表窗口（已学技能 + 可学习技能）</li>
<li><input disabled="" type="checkbox"> 技能升级按钮 + 确认</li>
<li><input disabled="" type="checkbox"> 宠物技能列表（40+种技能类型）</li>
<li><input disabled="" type="checkbox"> 技能描述面板</li>
<li><input disabled="" type="checkbox"> 战斗中技能快捷选择</li>
</ul>
<h3 id="phase-4-宠物系统完善">Phase 4: 宠物系统完善</h3>
<p><strong>目标文件</strong>:</p>
<ul>
<li><code>assets/cocos/PetView.ts</code> — 添加改名/属性加点/合成功能</li>
<li><code>assets/cocos/RideView.ts</code> — 已有骨架，需完善骑乘UI</li>
<li><code>assets/game/PetSystem.ts</code> — 确认属性加点数据结构</li>
<li><code>assets/net/LssProto.ts</code> — 确认 KN(改名)/宠物合成 协议</li>
</ul>
<p><strong>功能清单</strong>:</p>
<ul>
<li><input disabled="" type="checkbox"> 宠物改名（输入新名称 → KN协议）</li>
<li><input disabled="" type="checkbox"> 宠物属性加点（HP/攻击/防御/敏捷）</li>
<li><input disabled="" type="checkbox"> 宠物合成（选两只宠物 → 合成结果预览）</li>
<li><input disabled="" type="checkbox"> 骑乘/下马切换按钮</li>
</ul>
<hr>
<h2 id="session-c-待完成">Session-C 待完成</h2>
<h3 id="phase-5-社交系统">Phase 5: 社交系统</h3>
<p><strong>目标文件</strong>:</p>
<ul>
<li><code>assets/cocos/PartyView.ts</code> — 已有骨架，需完善组队UI</li>
<li><code>assets/cocos/FriendView.ts</code> — 已有骨架，需完善好友UI</li>
<li><code>assets/cocos/PlayerPopupMenu.ts</code> — 已有骨架，玩家右键菜单</li>
<li><code>assets/cocos/TradingView.ts</code> — 完善双边交易流程</li>
<li><code>assets/game/PartySystem.ts</code> / <code>assets/game/FriendSystem.ts</code> / <code>assets/game/Trading.ts</code> — 确认数据层</li>
</ul>
<p><strong>功能清单</strong>:</p>
<ul>
<li><input disabled="" type="checkbox"> 组队邀请/确认/退出</li>
<li><input disabled="" type="checkbox"> 队员列表/HP状态/队长标记</li>
<li><input disabled="" type="checkbox"> 好友添加/删除/在线状态</li>
<li><input disabled="" type="checkbox"> 私聊窗口（双击好友打开）</li>
<li><input disabled="" type="checkbox"> 交易物品选择 + 金币设置</li>
<li><input disabled="" type="checkbox"> 双方确认流程（锁定→确认→执行）</li>
</ul>
<h3 id="phase-6-地图与世界交互">Phase 6: 地图与世界交互</h3>
<p><strong>目标文件</strong>:</p>
<ul>
<li><code>assets/cocos/DialogView.ts</code> — 完善NPC对话</li>
<li><code>assets/cocos/NpcWindow.ts</code> — 已有，解析WN协议动态窗口</li>
<li><code>assets/cocos/InputController.ts</code> — 添加点击其他玩家检测</li>
<li><code>assets/cocos/CharacterView.ts</code> — 玩家信息展示</li>
<li><code>assets/cocos/BottomToolbar.ts</code> — 已有骨架，底部快捷栏</li>
</ul>
<p><strong>功能清单</strong>:</p>
<ul>
<li><input disabled="" type="checkbox"> WN协议窗口解析（按钮/列表/输入框/多页）</li>
<li><input disabled="" type="checkbox"> 靠近NPC按交互键触发对话</li>
<li><input disabled="" type="checkbox"> 地图切换/传送点处理</li>
<li><input disabled="" type="checkbox"> 点击其他玩家弹出信息面板（名称/等级/称号/家族）</li>
<li><input disabled="" type="checkbox"> 玩家交互菜单（组队/交易/私聊）</li>
</ul>
<hr>
<h2 id="phase-7-界面与系统功能-未分配">Phase 7: 界面与系统功能（未分配）</h2>
<ul>
<li><input disabled="" type="checkbox"> MainMenu.ts — 主菜单（人物/道具/宠物/任务/家族/技能/帮助/设置）</li>
<li><input disabled="" type="checkbox"> TitleView.ts — 称号查看/切换</li>
<li><input disabled="" type="checkbox"> RankingView.ts — 排行榜</li>
<li><input disabled="" type="checkbox"> DragHelper.ts — 窗口位置持久化（localStorage）</li>
<li><input disabled="" type="checkbox"> SettingsView.ts — 系统设置（音效/画质/屏蔽）</li>
</ul>
<hr>
<h2 id="文件归属参考">文件归属参考</h2>
<p>各 session 负责的文件范围，避免冲突：</p>
<table>
<thead>
<tr>
<th>Session</th>
<th>负责文件</th>
</tr>
</thead>
<tbody><tr>
<td>session-a</td>
<td>BattleView, BattleCharaRenderer, GroundItemRenderer, GroundItemPickupView, BankView, InventoryView(详情部分), InputController(地面物品部分), LssProto(物品相关)</td>
</tr>
<tr>
<td>session-b</td>
<td>SkillView, PetSkillView, PetView(改名/加点/合成), RideView, SkillSystem, LssProto(技能相关)</td>
</tr>
<tr>
<td>session-c</td>
<td>PartyView, FriendView, PlayerPopupMenu, TradingView(交易流程), DialogView, NpcWindow, CharacterView(玩家交互), BottomToolbar, LssProto(社交相关)</td>
</tr>
</tbody></table>
<hr>
<h2 id="备注">备注</h2>
<ul>
<li>所有新文件已提交到 <code>claude-session-a/battle-skill-item-pet-system</code> 分支</li>
<li>session-b 和 session-c 的 worktree 目录下已有各自的代码骨架（SkillView/BankView/PartyView 等），但那些文件是在主工作目录创建的，需要通过 <code>git checkout</code> 或手动复制到对应 worktree</li>
<li>建议各 session 在开始工作前，先 <code>git merge</code> session-a 的最新提交，确保基础功能完整</li>
</ul>
]]></content:encoded>
      <pubDate>Thu, 11 Jun 2026 13:51:12 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/sa611</guid>
      <category>石器时代</category>
      
    </item>
    <item>
      <title><![CDATA[Docker用法速查手册]]></title>
      <link>https://758192.xyz/post/docker</link>
      <description><![CDATA[从零开始学docker]]></description>
      <content:encoded><![CDATA[<h1 id="docker-命令速查手册">Docker 命令速查手册</h1>
<hr>
<h2 id="镜像管理">📦 镜像管理</h2>
<table>
<thead>
<tr>
<th>命令</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td><code>docker images</code></td>
<td>列出所有镜像</td>
</tr>
<tr>
<td><code>docker pull &lt;镜像名&gt;:&lt;标签&gt;</code></td>
<td>拉取镜像</td>
</tr>
<tr>
<td><code>docker rmi &lt;镜像ID&gt;</code></td>
<td>删除镜像</td>
</tr>
<tr>
<td><code>docker image prune -f</code></td>
<td>清除所有 <code>&lt;none&gt;</code> 悬空镜像</td>
</tr>
<tr>
<td><code>docker image prune -a -f</code></td>
<td>清除所有未使用的镜像（⚠️ 慎用）</td>
</tr>
<tr>
<td><code>docker tag &lt;源镜像&gt; &lt;新标签&gt;</code></td>
<td>给镜像打标签</td>
</tr>
<tr>
<td><code>docker build -t &lt;名称&gt;:&lt;标签&gt; .</code></td>
<td>从 Dockerfile 构建镜像</td>
</tr>
<tr>
<td><code>docker save -o &lt;文件名&gt;.tar &lt;镜像名&gt;</code></td>
<td>导出镜像为 tar</td>
</tr>
<tr>
<td><code>docker load -i &lt;文件名&gt;.tar</code></td>
<td>从 tar 导入镜像</td>
</tr>
<tr>
<td><code>docker history &lt;镜像名&gt;</code></td>
<td>查看镜像构建历史</td>
</tr>
</tbody></table>
<hr>
<h2 id="容器生命周期">🚀 容器生命周期</h2>
<table>
<thead>
<tr>
<th>命令</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td><code>docker run &lt;镜像&gt;</code></td>
<td>创建并启动容器</td>
</tr>
<tr>
<td><code>docker start &lt;容器&gt;</code></td>
<td>启动已停止的容器</td>
</tr>
<tr>
<td><code>docker stop &lt;容器&gt;</code></td>
<td>优雅停止容器</td>
</tr>
<tr>
<td><code>docker restart &lt;容器&gt;</code></td>
<td>重启容器</td>
</tr>
<tr>
<td><code>docker kill &lt;容器&gt;</code></td>
<td>强制杀死容器</td>
</tr>
<tr>
<td><code>docker rm &lt;容器&gt;</code></td>
<td>删除已停止的容器</td>
</tr>
<tr>
<td><code>docker rm -f &lt;容器&gt;</code></td>
<td>强制删除运行中的容器</td>
</tr>
</tbody></table>
<hr>
<h2 id="docker-run-常用参数">🏃 docker run 常用参数</h2>
<pre><code class="hljs language-bash">docker run \
  -d                          \  # 后台运行
  --name &lt;名称&gt;                \  # 容器命名
  -p &lt;宿主端口&gt;:&lt;容器端口&gt;      \  # 端口映射
  -v &lt;宿主路径&gt;:&lt;容器路径&gt;      \  # 目录挂载
  -e &lt;变量名&gt;=&lt;值&gt;             \  # 环境变量
  --network &lt;网络名&gt;           \  # 指定网络
  --restart unless-stopped     \  # 自动重启策略
  --rm                         \  # 停止后自动删除
  -it &lt;镜像&gt; /bin/bash            # 交互式进入
  &lt;镜像名&gt;:&lt;标签&gt;
</code></pre><h3 id="restart-策略">restart 策略</h3>
<table>
<thead>
<tr>
<th>值</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td><code>no</code></td>
<td>不自动重启（默认）</td>
</tr>
<tr>
<td><code>always</code></td>
<td>总是重启</td>
</tr>
<tr>
<td><code>unless-stopped</code></td>
<td>除非手动停止，否则重启</td>
</tr>
<tr>
<td><code>on-failure[:max]</code></td>
<td>非正常退出时重启</td>
</tr>
</tbody></table>
<hr>
<h2 id="容器查看">📋 容器查看</h2>
<table>
<thead>
<tr>
<th>命令</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td><code>docker ps</code></td>
<td>查看运行中的容器</td>
</tr>
<tr>
<td><code>docker ps -a</code></td>
<td>查看所有容器（含已停止）</td>
</tr>
<tr>
<td><code>docker ps --no-trunc</code></td>
<td>显示完整命令</td>
</tr>
<tr>
<td><code>docker logs &lt;容器&gt;</code></td>
<td>查看日志</td>
</tr>
<tr>
<td><code>docker logs -f &lt;容器&gt;</code></td>
<td>实时跟踪日志</td>
</tr>
<tr>
<td><code>docker logs --tail 100 &lt;容器&gt;</code></td>
<td>最后 100 行日志</td>
</tr>
<tr>
<td><code>docker top &lt;容器&gt;</code></td>
<td>查看容器内进程</td>
</tr>
<tr>
<td><code>docker stats</code></td>
<td>实时资源占用（CPU/内存/网络）</td>
</tr>
</tbody></table>
<hr>
<h2 id="容器详情-inspect">🔍 容器详情（inspect）</h2>
<table>
<thead>
<tr>
<th>命令</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td><code>docker inspect &lt;容器&gt;</code></td>
<td>查看所有详细信息（JSON）</td>
</tr>
<tr>
<td><code>docker inspect &lt;容器&gt; -f &#39;{{json .HostConfig.Binds}}&#39;</code></td>
<td>查看挂载目录</td>
</tr>
<tr>
<td><code>docker inspect &lt;容器&gt; -f &#39;{{json .NetworkSettings.Ports}}&#39;</code></td>
<td>查看端口映射</td>
</tr>
<tr>
<td><code>docker inspect &lt;容器&gt; -f &#39;{{json .Config.Env}}&#39;</code></td>
<td>查看环境变量</td>
</tr>
<tr>
<td><code>docker inspect &lt;容器&gt; -f &#39;{{json .HostConfig.RestartPolicy}}&#39;</code></td>
<td>查看重启策略</td>
</tr>
<tr>
<td><code>docker inspect &lt;容器&gt; -f &#39;{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}&#39;</code></td>
<td>查看 IP 地址</td>
</tr>
</tbody></table>
<hr>
<h2 id="数据卷-volume">💾 数据卷（Volume）</h2>
<table>
<thead>
<tr>
<th>命令</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td><code>docker volume ls</code></td>
<td>列出所有卷</td>
</tr>
<tr>
<td><code>docker volume create &lt;名称&gt;</code></td>
<td>创建卷</td>
</tr>
<tr>
<td><code>docker volume inspect &lt;名称&gt;</code></td>
<td>查看卷详情</td>
</tr>
<tr>
<td><code>docker volume rm &lt;名称&gt;</code></td>
<td>删除卷</td>
</tr>
<tr>
<td><code>docker volume prune -f</code></td>
<td>清除未使用的卷</td>
</tr>
</tbody></table>
<h3 id="v-vs-mount">-v vs --mount</h3>
<pre><code class="hljs language-bash"># -v 简写
docker run -v /host/path:/container/path &lt;镜像&gt;

# --mount 更明确
docker run --mount type=bind,source=/host/path,target=/container/path &lt;镜像&gt;
docker run --mount type=volume,source=myvol,target=/container/path &lt;镜像&gt;
</code></pre><hr>
<h2 id="网络管理">🌐 网络管理</h2>
<table>
<thead>
<tr>
<th>命令</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td><code>docker network ls</code></td>
<td>列出网络</td>
</tr>
<tr>
<td><code>docker network create &lt;名称&gt;</code></td>
<td>创建网络</td>
</tr>
<tr>
<td><code>docker network inspect &lt;名称&gt;</code></td>
<td>查看网络详情</td>
</tr>
<tr>
<td><code>docker network rm &lt;名称&gt;</code></td>
<td>删除网络</td>
</tr>
<tr>
<td><code>docker network prune -f</code></td>
<td>清除未使用的网络</td>
</tr>
<tr>
<td><code>docker network connect &lt;网络&gt; &lt;容器&gt;</code></td>
<td>容器加入网络</td>
</tr>
<tr>
<td><code>docker network disconnect &lt;网络&gt; &lt;容器&gt;</code></td>
<td>容器离开网络</td>
</tr>
</tbody></table>
<hr>
<h2 id="docker-compose">🐙 Docker Compose</h2>
<table>
<thead>
<tr>
<th>命令</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td><code>docker-compose up -d</code></td>
<td>后台启动所有服务</td>
</tr>
<tr>
<td><code>docker-compose down</code></td>
<td>停止并删除所有容器/网络</td>
</tr>
<tr>
<td><code>docker-compose down -v</code></td>
<td>同上，同时删除数据卷（⚠️ 慎用）</td>
</tr>
<tr>
<td><code>docker-compose restart &lt;服务名&gt;</code></td>
<td>重启某个服务</td>
</tr>
<tr>
<td><code>docker-compose logs -f &lt;服务名&gt;</code></td>
<td>跟踪某个服务日志</td>
</tr>
<tr>
<td><code>docker-compose ps</code></td>
<td>查看服务状态</td>
</tr>
<tr>
<td><code>docker-compose pull</code></td>
<td>拉取最新镜像</td>
</tr>
<tr>
<td><code>docker-compose build</code></td>
<td>重新构建镜像</td>
</tr>
<tr>
<td><code>docker-compose exec &lt;服务名&gt; /bin/sh</code></td>
<td>进入运行中的服务</td>
</tr>
</tbody></table>
<h3 id="docker-compose-yml-模板">docker-compose.yml 模板</h3>
<pre><code class="hljs language-yaml">version: &quot;3.8&quot;
services:
  app:
    image: nginx:latest
    container_name: my-app
    ports:
      - &quot;80:80&quot;
      - &quot;443:443&quot;
    volumes:
      - ./data:/var/lib/data
      - app_config:/etc/config
    environment:
      - DB_HOST=db
      - DB_PORT=5432
    depends_on:
      - db
    restart: unless-stopped
    networks:
      - frontend

  db:
    image: postgres:15
    container_name: my-db
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=secret
    restart: unless-stopped
    networks:
      - frontend

volumes:
  app_config:
  db_data:

networks:
  frontend:
</code></pre><hr>
<h2 id="清理命令">🧹 清理命令</h2>
<table>
<thead>
<tr>
<th>命令</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td><code>docker system prune -f</code></td>
<td>一键清理：停止的容器 + 悬空镜像 + 未用网络 + 构建缓存</td>
</tr>
<tr>
<td><code>docker system prune -a -f</code></td>
<td>同上，额外删除所有未使用镜像（⚠️ 慎用）</td>
</tr>
<tr>
<td><code>docker system prune -a --volumes -f</code></td>
<td>全清，包括数据卷（⚠️⚠️ 危险）</td>
</tr>
<tr>
<td><code>docker system df</code></td>
<td>查看 Docker 磁盘占用</td>
</tr>
<tr>
<td><code>docker container prune -f</code></td>
<td>清除已停止的容器</td>
</tr>
<tr>
<td><code>docker image prune -f</code></td>
<td>清除悬空镜像</td>
</tr>
<tr>
<td><code>docker volume prune -f</code></td>
<td>清除未使用的数据卷</td>
</tr>
<tr>
<td><code>docker network prune -f</code></td>
<td>清除未使用的网络</td>
</tr>
</tbody></table>
<hr>
<h2 id="实用技巧">🔧 实用技巧</h2>
<h3 id="进入运行中的容器">进入运行中的容器</h3>
<pre><code class="hljs language-bash">docker exec -it &lt;容器&gt; /bin/bash
# 如果没有 bash：
docker exec -it &lt;容器&gt; /bin/sh
</code></pre><h3 id="容器间文件拷贝">容器间文件拷贝</h3>
<pre><code class="hljs language-bash"># 容器 → 宿主机
docker cp &lt;容器&gt;:&lt;容器路径&gt; &lt;宿主路径&gt;

# 宿主机 → 容器
docker cp &lt;宿主路径&gt; &lt;容器&gt;:&lt;容器路径&gt;
</code></pre><h3 id="查看容器资源占用">查看容器资源占用</h3>
<pre><code class="hljs language-bash">docker stats --no-stream  # 一次性输出，不持续刷新
</code></pre><h3 id="导出-导入容器">导出/导入容器</h3>
<pre><code class="hljs language-bash">docker export &lt;容器&gt; -o &lt;文件名&gt;.tar   # 导出容器为 tar
docker import &lt;文件名&gt;.tar &lt;新镜像名&gt;   # 导入为镜像
</code></pre><h3 id="重命名容器">重命名容器</h3>
<pre><code class="hljs language-bash">docker rename &lt;旧名&gt; &lt;新名&gt;
</code></pre><h3 id="查看容器运行时的完整命令">查看容器运行时的完整命令</h3>
<pre><code class="hljs language-bash">docker ps --no-trunc --format &quot;{{.Names}}: {{.Command}}&quot;
</code></pre><hr>
<h2 id="一行命令集合">⚡ 一行命令集合</h2>
<pre><code class="hljs language-bash"># 删除所有已停止的容器
docker rm $(docker ps -aq --filter status=exited)

# 删除所有镜像
docker rmi $(docker images -q)

# 停止所有运行中的容器
docker stop $(docker ps -q)

# 删除所有容器（含运行中）
docker rm -f $(docker ps -aq)

# 查看所有容器 IP
docker inspect -f &#39;{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}&#39; $(docker ps -aq)

# 按大小排序镜像
docker images --format &quot;{{.Repository}}:{{.Tag}} {{.Size}}&quot; | sort -k2 -h
</code></pre>]]></content:encoded>
      <pubDate>Thu, 11 Jun 2026 06:31:01 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/docker</guid>
      
      <category>docker</category>
    </item>
    <item>
      <title><![CDATA[肥猫云 openwrt 的精简和运行]]></title>
      <link>https://758192.xyz/post/fccclient</link>
      <description><![CDATA[最近折腾在 360 T7 路由器上安装肥猫云（fcclient），踩了不少坑，记录一下整个过程。]]></description>
      <content:encoded><![CDATA[<p>最近折腾在 360 T7 路由器上安装肥猫云（fcclient），踩了不少坑，记录一下整个过程。</p>
<h2 id="路由器环境">路由器环境</h2>
<p>360 T7 搭载联发科 MT7981 (Filogic 820) 芯片，双核 Cortex-A53 aarch64，230MB 内存，Flash 只有 63MB 左右。刷的是 ImmortalWrt 24.10-SNAPSHOT。</p>
<h2 id="原始-ipk-包的问题">原始 ipk 包的问题</h2>
<p>从官方下载的 <code>luci-app-fcclient_3.0.7-202605210720_all.ipk</code> 有 25MB，解压后 data 区 53MB，其中：</p>
<ul>
<li>5 个架构的二进制文件（netflow_mips / mipsel / arm / x86_64 / aarch64），加起来接近 10MB</li>
<li>geo 数据库（geoip.dat + geosite.dat + GeoLite2-ASN.mmdb + geoip.metadb）约 43MB</li>
</ul>
<p>而 360 T7 只认 aarch64，其他 4 个架构纯属浪费空间。</p>
<h2 id="精简过程">精简过程</h2>
<p>写了一个 shell 脚本 <code>trim_ipk.sh</code>，逻辑很简单：把 ipk 解压后删掉不需要的架构二进制，只保留 <code>netflow_aarch64</code>，再重新打包。</p>
<p>结果从 25MB 砍到 1.9MB，精简效果立竿见影。不过这也只是二进制部分，geo 数据库不在这个包里。</p>
<h2 id="安装后的两个坑">安装后的两个坑</h2>
<h3 id="坑一-二进制名不匹配">坑一：二进制名不匹配</h3>
<p>安装后服务死活启动不了，<code>/etc/init.d/netflow status</code> 显示 &quot;active with no instances&quot;。查了一下 init 脚本，发现它找的是 <code>/usr/bin/netflow</code>，但 ipk 里安装的文件叫 <code>netflow_aarch64</code>。</p>
<p>手动创建一个软链接解决：</p>
<pre><code class="hljs language-sh">ln -sf /usr/bin/netflow_aarch64 /usr/bin/netflow
</code></pre><h3 id="坑二-geo-数据库丢失">坑二：geo 数据库丢失</h3>
<p>精简包只管二进制，geo 数据库需要单独安装。从本地解压 <code>geodata_mihomo.tar.gz</code> 上传到路由器，放到 <code>/etc/netflow/mihomo/</code> 目录下。注意解压时 tar 会自动多创建一层 <code>etc/</code> 目录，需要手动整理文件结构。</p>
<p>4 个数据库文件加起来约 43MB，解压后目录结构应该是：</p>
<pre><code>/etc/netflow/mihomo/
├── geoip.dat          (18.3 MB)
├── geoip.metadb       (8.8 MB)
├── geosite.dat        (4.0 MB)
└── GeoLite2-ASN.mmdb  (11.6 MB)
</code></pre><h3 id="最后">最后</h3>
<p>创建好软链接、放好数据库、重启服务，<code>/etc/init.d/netflow start</code> 后状态变为 &quot;running&quot;。</p>
<p>整个过程最大的感受是，OpenWrt 上有些包不是独立封装的，安装时最好检查一下 <code>control</code> 文件里的依赖关系和安装后的文件列表，避免装完发现缺东少西。另外路由器 Flash 和内存都紧张，精简包是刚需，特别是这种多架构合一的 ipk，删掉不用的架构能省不少空间。</p>
]]></content:encoded>
      <pubDate>Tue, 09 Jun 2026 10:13:43 GMT</pubDate>
      <guid isPermaLink="true">https://758192.xyz/post/fccclient</guid>
      
      <category>openwrt</category>
      <category>肥猫云</category>
    </item>
  </channel>
</rss>