橘子のBlog
首页项目归档照片墙音乐灵境说说杂谈友链关于

云端杂谈

“ 代码、学术、提瓦特与泰拉大陆的碎片记录 ”

cover
✨ 疲惫
2026-08-14 22:02:16

差点见不到我的博客

原本是说想给博客的歌曲做个排序功能的,结果最后搞来搞去差点把后台搞崩了 **因为我的后台跑的是"过期的快照"** `my-blog-manager` 后台不是用 `npm run dev` 在跑,而是被 `launcher.py` 用**生产模式**启动的:它检测到 `.next/standalone/server.js` 存在,就执行 `node server.js`。 而文章页面是(`app/posts/[slug]/page.tsx`、`app/timeline/page.tsx`): ``` const postsDirectory = path.join(process.cwd(), 'posts'); ``` 生产模式下 `process.cwd()` = `.next/standalone`,所以后台读的是 `.next/standalone/posts/`——**都没有更新这个 standalone 快照**。TAT 目前的解决办法就是: 删掉或改名 `.next/standalone/server.js`,让 `launcher.py` 自动回退到 `npm run dev` 模式。这样后台读的就是 `my-blog-manager/posts/` 实时数据
cover
2026-06-02 23:01:52

一个拍纪录片的人,正在被时代淘汰

这两天看到了一个视频,讲的是一位田野就是乡工作者,也就是我们所说的纪录片导演,对当今世界的思考,受益良多: 在如今信息洪流的快节奏时代,一切都如同流星一样划过。短视频时代使得人们的耐心变得越来越少,但是这些纪录片记录者,放慢姿态,用时间来弥补,用热爱来守护。越是瞬息万变的节奏,越要定下心去守护内心的宁静,正如作者说的: > 这几年越来越意识到: > 很多人并不是不痛苦, > 只是已经学会了快速地活着。 > > 但纪录片这门手艺, > 偏偏反着来。 > > 谨以此片献给时代洪流下, > 仍认真用力活着的平凡人。 > > 我们不是时代的注脚, > 我们就是时代本身。 [一个拍纪录片的人,正在被时代淘汰\_哔哩哔哩\_bilibili](https://www.bilibili.com/video/BV1NSRXBwEZp/?spm_id_from=333.1391.0.0&vd_source=20fae464d78a66a35f63c35e32543721) ‍![](https://bu.dusays.com/2026/06/02/6a1ef03057ebe.png) ‍
cover
✨ Emo
2026-06-01 17:13:10

🐱煤球接入Deepseek

在此之前,煤球的模型是Gemini: [**my-blog-manager/app/api/chat/route.ts**](vscode-webview://1cte5emmbpca15lv39mqrfijum16bt8hnmbiov069074au52roah/my-blog-manager/app/api/chat/route.ts) 这是小猫 AI 的**后端路由**,直接对接 **Google Gemini API**: * 第 13 行:从环境变量 `GEMINI_API_KEY` 或 `OPENAI_API_KEY` 读取密钥 * 第 21-22 行:从 `siteConfig.geminiConfig` 读取模型 ID,构建请求 URL: ``` https://generativelanguage.googleapis.com/v1beta/models/{modelId}:generateContent?key={apiKey} ``` * 第 29-42 行:发送请求体,包含 `system_instruction`(猫设 prompt)、用户消息、`generationConfig`(token 上限、temperature) --- ### 2. API 配置(模型参数 + 猫设 Prompt) ``` geminiConfig: { modelId: "", systemPrompt: "", maxOutputTokens: , temperature: , }, ``` --- ### 3. 前端调用方 * [**my-blog-manager/components/CyberCat.tsx**](vscode-webview://1cte5emmbpca15lv39mqrfijum16bt8hnmbiov069074au52roah/my-blog-manager/components/CyberCat.tsx) — 页面右下角的赛博小猫组件,`handleFeed()`和 `handleChatSubmit()`都向 `/api/chat` 发 POST 请求 * [**my-blog-manager/components/settings/AICatSection.tsx**](vscode-webview://1cte5emmbpca15lv39mqrfijum16bt8hnmbiov069074au52roah/my-blog-manager/components/settings/AICatSection.tsx) — 后台设置页面,可修改 modelId、systemPrompt、temperature、maxOutputTokens,点"暂存至队列"写入 `geminiConfig` --- ‍ 而接入Deepseek有两个需要注意的点: ‍ * DeepSeek 用的是 OpenAI 兼容接口,跟 Gemini 的请求体结构完全不同: * **端点,鉴别权限都不相同** ‍ 此外:CMS 管理后台(Settings 页面 → AI 小猫配置)点「暂存至队列」并应用,**会丢失** `apiKey` **和** `baseUrl`。 原因是 [cms\_core/api/config.py:178-185](vscode-webview://1cte5emmbpca15lv39mqrfijum16bt8hnmbiov069074au52roah/my-blog-manager/cms_core/api/config.py#L178) 的写入逻辑——前端只传 4 个字段: ``` { modelId, systemPrompt, maxOutputTokens, temperature } ``` 后端用正则直接把整个 `geminiConfig` 块替换掉,新增的 `apiKey` 和 `baseUrl` 不在前端传的字段里 ‍ 解决问题:在 config.py 的 update\_site\_config 里加一个合并逻辑 —— 更新 dict 之前先保留已有字段,缺少的 key 不被丢弃。不影响现有任何功能。 ``` existing = {} m = re.search(rf"{key}\s*:\s*\{{([\s\S]*?)\}}", content) if m: existing = parse_ts_dict(m.group(1)) merged = {**existing, **value} ``` 不过!!!把 key 明文写在代码里相当于把房门钥匙贴在门上。🐖 所以我在**在 Vercel Dashboard → Settings → Environment Variables 加入环境变量,这样就不用把API放在仓库里面** ![](https://bu.dusays.com/2026/06/01/6a1d4c7e9676c.png) 搞定!
cover
2026-05-31 02:20:42

😋如何在不与 update.py 冲突的前提下为博客添加自定义功能

### `layout.tsx` **— 全局外壳** `XHBlogs/app/layout.tsx` 是 Next.js App Router 的**根布局**,它定义了: **职责具体内容**HTML 元数据页面标题、图标、SEO 描述字体加载Geist、Noto Serif SC 等全局字体全局 Provider主题切换 (`ThemeProvider`)、音乐播放 (`MusicProvider`)全局 UI 组件背景特效、浮动播放器、CyberCat、启动画面、弹幕背景全局样式`globals.css`、Tailwind 基础样式 `layout.tsx` **里的东西会出现在博客的每一个页面上。** 导航栏、背景、播放器这些"壳"都在这里。 **所以说**`page.tsx` **只负责它自己那条路由的内容部分,然后被套进** `layout.tsx` **的外壳里。** --- ## **二、update.py 覆盖规则速查** `update.py` 从上游 `XinghuisamaBlogs` 拉取最新代码,**只覆盖它名单里的文件** **会被覆盖:** ``` XHBlogs/components/ — 所有公共组件 XHBlogs/app/**/page.tsx — 所有页面的 page.tsx XHBlogs/app/layout.tsx — 根布局 XHBlogs/app/globals.css — 全局样式 my-blog-manager/cms_core/ — CMS 后端 my-blog-manager/components/— CMS 组件 my-blog-manager/app/**/page.tsx — CMS 页面 ``` 不会被覆盖: ``` XHBlogs/data/ — 数据文件 (albums.ts, friends.ts, projects.ts) XHBlogs/posts/ — 文章 .md XHBlogs/chatters/ — 说说 .md XHBlogs/moments/ — 瞬间 .md XHBlogs/siteConfig.ts — 全站配置 XHBlogs/public/ — 静态资源 my-blog-manager/data/ — CMS 数据文件 my-blog-manager/siteConfig.ts — CMS 配置 ``` ## **三、实践** ### **1:加一个独立页面(最推荐,零冲突)** 直接在 `XHBlogs/app/` 下新建目录 + `page.tsx`,Next.js 自动识别为路由。 ```  XHBlogs/  └── app/     └── tools/                     └── page.tsx       ← 访问 /tools 即可看到 ``` **优点:** 完全独立,不需要改动任何已有文件,永远不会冲突。 --- ### **B:全局组件(但需要改 layout.tsx / Navbar.tsx)** 因为我的功能需要出现在**每个页面**上(比如全局公告栏、回到顶部按钮),必须改 `layout.tsx` 或 `Navbar.tsx`。 **做法:把自定义代码放在独立目录,用 git patch 管理改动。** ```  步骤 1:创建自定义组件  XHBlogs/  └── custom/                 ← 扩展目录(update.py 不碰)     ├── index.ts           ← 统一导出入口     └── BackToTop.tsx       ← 组件  ​  步骤 2:在 layout.tsx 中引入组件,然后生成补丁  git diff HEAD -- XHBlogs/app/layout.tsx > XHBlogs/custom/layout-custom.patch ``` **update.py 恢复:** 一行命令全自动恢复 ```  git apply XHBlogs/custom/layout-custom.patch  git apply XHBlogs/custom/navbar-custom.patch   ``` --- ### **C:改已有页面** 给**已有的页面**(比如首页 `page.tsx`)加模块。 把新增模块写在 `custom/` 里,在 `page.tsx` 中引入。同样,跑 `update.py` 后补回 import 即可。 --- ## **四、siteConfig.ts 作为功能开关** `siteConfig.ts` 不在覆盖名单里,所以把它当作**自定义功能的控制面板**: **Vercel部署:** ``` XHBlogs (本地博客源码) │ ▼ CMS → deploy.py → git push OriginBlogsS2 (GitHub 源码仓库) │ ▼ Vercel 检测到 push → next build ``` 跑完 `update.py` 后、触发 Vercel 部署前,两条命令: ```  git apply XHBlogs/custom/layout-custom.patch  git apply XHBlogs/custom/navbar-custom.patch ``` > **结论:patch 文件在** `custom/` **安全区里,不会被覆盖。两条命令即可恢复全部自定义功能。** 搞定!!!😋😋😋