qiyuan-blog-template
带 AI 问答的 Astro 全功能博客模板— 内置 RAG 站内问答、文章朗读、评论、网盘、短链与资源站EdgeOne Makers 部署开箱即用。基于 Astro 深度定制的个人博客与技术资源站模板衍生自 Koharu 主题在线示例https://www.qiyuan.icu,项目地址:[https://github.com/violet27chen/qiyuan-blog-template]功能页面截图上图为**示例站qiyuan.icu已开启全部可选功能**首页顶部 Hero 视频区、作者卡片、文章列表、站内 AI 助手浮窗、导航栏的资源/网盘/短链入口等。模板默认关闭这些可选功能克隆后按需开启。歌单临时邮箱网盘资源站本仓库qiyuan-blog-template是一个博客模板在 GitHub 仓库页面点击Use this template即可一键创建你自己的博客仓库再按需修改config/site.yaml、填充文章、配置环境变量后部署。部署优先推荐国内友好的EdgeOne Makers详见下方「作为模板使用」资源站为独立子项目需单独部署见「资源站搭建教程」。 作为模板使用进入本仓库qiyuan-blog-template页面点击Use this template → Create a new repository填写你的新仓库名可任意命名。git clone到本地npm install。复制.env.example为.env按需填写各功能的环境变量不填则对应功能自动关闭。编辑config/site.yaml改site.title/url/avatar/social为你自己的信息。删除src/content/blog/welcome.md放入你自己的.md文章。部署到 EdgeOne Makers或其它 Astro 兼容平台在平台的环境变量中配置与.env相同的键值。可选功能默认关闭为保持模板开箱即用的纯净度以下可选功能默认全部关闭克隆后按需开启功能配置文件开关默认值开启方式评论comment.providernone关闭改为giscus/waline/twikoo/custom并填对应配置站内 AI 助手RAGrag.enabledfalse设为true并配置SILICONFLOW_API_KEY/NEON_SERVERLESS_URL等资源站resources.enabledfalse设为true并单独部署resource-site/见「资源站搭建教程」临时邮箱tempMail.enabledfalse设为true并在 Cloudflare 部署收信 Worker D1 Email Routing文章朗读文章 frontmatteraudio: true不设置即关闭在文章顶部加audio: true并配置SILICONFLOW_API_KEY R2网盘导航项enabledfalse导航项改为enabled: true 部署/api/drive/*R2/S3 KV短链导航项enabledfalse导航项改为enabled: true 部署/api/shorten/*说明评论 / 临时邮箱 / 文章朗读属「零依赖或轻依赖」配好即用站内 AI 助手 / 资源站 / 网盘 / 短链 依赖边缘函数与外部服务Neon / Supabase / R2 / Cloudflare需在部署平台配置对应环境变量。各功能的完整配置见下方「功能特性」与各docs/*.md。 开发工具右键样式编辑器仅本地astro dev本地astro dev运行时直接定死右键可用无需开关在页面任意位置右键即弹出样式编辑器边看边调。面板内不使用任何表情符号图标一律为内联 SVG所有可调属性均标注中文 / 日文 / 英文三语。元素编辑右键所点元素的内联样式文字/背景颜色、字号、字重、内边距、外边距、圆角、边框、对齐、行高、不透明度。上传媒体替换元素面板顶部「上传图片 / 画像 / Image」按钮SVG 图标支持图片 / GIF / 视频右键img如头图、精选分类图→ 直接替换其src若右键的是包裹图片的容器会自动定位其中的img一并替换。右键带背景图的元素如背景图区域→ 替换其background-image上传视频则注入一个绝对定位的video覆盖层作为动态背景。内容以 base64 / blob 注入刷新后还原开发期调试用不写盘。主题变量按当前「亮色 / 暗色」分别编辑全局 CSS 变量SVG 太阳 / 月亮 图标切换。变量以自然语言说明呈现如「页面背景色 / ページ背景 / Page background」技术变量名仅作小号代码注记。改动注入style并持久化到localStorage刷新后保留「复制 CSS」可导出「重置」恢复默认。面板不显示滚动条已隐藏主题变量区改双列网格压缩高度点击面板外空白处自动关闭面板配色使用博客主题变量自动跟随亮/暗主题。⚠️ 该功能仅在import.meta.env.DEV下挂载src/layouts/Layout.astro中以{import.meta.env.DEV StyleEditor /}包裹src/components/dev/StyleEditor.tsx组件内亦有兜底守卫。astro build时被自动 tree-shake不进入生产产物对线上访客零影响。安全响应头两个边缘函数edge-functions/api/[[default]].js与resource-site/edge-functions/api/[[default]].js已为所有 API 响应统一注入安全头经getCorsHeaders()spread一处覆盖全部 JSON / 流式 / 代理响应响应头值X-Content-Type-OptionsnosniffReferrer-Policystrict-origin-when-cross-originX-Frame-OptionsSAMEORIGIN非DENY保证网盘内联预览的同站iframe不被阻断Permissions-Policycamera(), microphone(), geolocation()Strict-Transport-Securitymax-age63072000; includeSubDomains未上 preload 列表不加preload静态资源HTML / JS / CSS / 字体 / 图片的安全头需在EdgeOne 控制台 → 站点加速 → 配置 → HTTP 响应头修改响应头中按文件后缀统一添加上述同样的头CDN 缓存层注入被缓存的资源也带安全头。CSP 暂未启用站内有 AdSense 与内联脚本需单独审计。可选加固在EdgeOne 控制台 → 安全防护 → 速率限制给写入类接口配「客户端 IP 60s 内 ≥1 次 → 拦截 429」覆盖POST /api/comment-image、POST /api/drive/upload-init、POST /api/temp-mail/address防滥发。EdgeOne 边缘直接判真实客户端 IPEO-Connecting-IP不会因 CDN 聚合误伤全体用户。技术栈Astro 5SSG 定制主题支持中文 / English / 日本語 三语[lang]/镜像路由。部署平台EdgeOne Makers腾讯云边缘函数 / 云函数。站点qiyuan.icu跑在边缘全文搜索用 Pagefind。边缘运行时edge-functions/api/[[default]].js—— EdgeOne 边缘函数单体承载 RAG 聊天、临时邮箱、评论、上传、MCP、统计等全部 API。cloud-functions/—— Makers 云函数如博客图床上传api/images/upload。外部依赖NeonPostgres pgvector博客文章向量库、Supabase资源站向量库、硅基流动bge-m3 / bge-reranker 嵌入重排、商汤 sensenova ModelScope 智谱生成模型、CloudflareKV 评论存储 R2 评论图 临时邮箱 Worker/D1。功能特性博客文章Markdown/MDX封面图目录Pagefind 站内搜索支持按语言切换。站内 AI 助手RAG「就这篇文章问 AI」检索博客文章Neon pgvectorrag_posts余弦检索 资源站Supabaseproducts混合检索向量 词法ilikeRRF 融合各取候选经重排后送入上下文。嵌入BAAI/bge-m3、重排BAAI/bge-reranker-v2-m3均经硅基流动免费。生成首选商汤 sensenovadeepseek-v4-flash多密钥轮询、关闭思考模式兜底 ModelScope / 智谱 GLM / 硅基流动 DeepSeek。使用的大模型平台硅基流动SiliconFlow嵌入BAAI/bge-m3 重排BAAI/bge-reranker-v2-m3免费并作生成最终兜底DeepSeek。商汤 sensenova生成首选模型deepseek-v4-flash多密钥轮询、关闭思考模式。ModelScope 魔搭生成兜底Llama-3.3-70B国内直连免费。智谱 GLM生成兜底GLM-4.7-Flash永久免费、国内直连。性能优化Neon 预热请求内SELECT 1与嵌入并发消除 scale-to-zero 冷启动、问题向量缓存LRU 5 条相同问题跳过重复嵌入调用。临时邮箱qiyuanmail.cc.cdCloudflare Email Routing → Worker → D1temp_addresses/temp_messagesTurnstile 人机验证前端支持收件箱、自动刷新、HTML 邮件渲染链接新标签打开。⚠️ 收信 Worker D1 Email Routing 需在Cloudflare 控制台自行部署代码见cloudflare/本仓库的边缘函数只负责 UI 与读信/生成地址。评论系统评论存Cloudflare KV图片存Cloudflare R2经上传 Worker 直写无需 S3 密钥config/site.yaml中comment.provider默认none可选custom/giscus/waline/twikoo。R2 独立图床评论图走r2.qiyuan.icu国内经 EdgeOne 边缘回源 Cloudflare浏览器全程只碰腾讯网络。文章朗读Edge TTS 预生成音频文章 frontmatter 加audio: true即生成中文朗读 mp3。流程为发布前本地用 Edge TTS 合成 → 上传 Cloudflare R2audio/slug.mp3经r2.qiyuan.icuCDN→ 前端播放器点击播放非运行时实时合成体验更稳。清单src/assets/audio-manifest.json记录每篇slug → { url, voice, chars, bytes, generatedAt }文章页据此显示播放器。音频 URL 自动带缓存破坏参数?vmp3 内容 sha256 前 12 位R2/EdgeOne 对未知 query 参数按同一对象返回但浏览器/CDN 以完整 URL 作缓存键故音频内容更新后 URL 必变、强制重新拉取避免旧 mp3 被长期缓存R2 默认Cache-Control: max-age604800。生成npm run generate:audio增量内容音色哈希命中则跳过-- --force全量重生成-- --local强制落本地public/audio/。增量缓存存.cache/audio-cache.json。短链Short URL把长链接缩短成{origin}/api/s/slug。存储于 Cloudflare KV与评论同命名空间前缀short:支持自定义短码3–32 位字母数字_-或自动生成 6 位随机码仅接受http/https目标访问/api/s/slug即 302 跳转到原链接不存在返回 404。需配置CF_KV_*。公开网盘Netdisk/drive浏览器经 S3 presigned PUT 直传 Cloudflare R2文件元数据存 Cloudflare KV单文件默认上限 500MBDRIVE_MAX_BYTES可覆盖。提供上传初始化/api/drive/upload-init、完成回调/api/drive/upload-complete、列表/api/drive/list、分享页元数据/api/drive/meta/:token。文件 24 小时后自动删除KVexpirationTtlDRIVE_TTL_HOURS可改时长需配合 Cloudflare 控制台 R2 桶 Lifecycle 规则前缀drive/才能真正清理对象。需配置R2_*与CF_KV_*。本地开发npminstallnpmrun dev# http://localhost:4321npmrun build# 构建到 dist/npmrun preview# 预览构建结果需要Node.js 18.17.1推荐 20与 npm 9。RAG 相关脚本可选CI/部署时通常自动跑npm run index:neon文章向量、npm run index:resources资源向量回填、npm run generate:summaries等。文章朗读音频需本地预生成npm run generate:audio合成并上传 R2 后须提交src/assets/audio-manifest.json部署只读取清单、不生成音频。新增或编辑audio: true文章后务必重跑本命令。环境变量EdgeOne 控制台边缘函数通过环境变量注入密钥本仓库代码不包含任何密钥。RAG 必需变量说明SILICONFLOW_API_KEY嵌入(bge-m3)/重排(bge-reranker) 必需文本生成也复用它作最后兜底NEON_SERVERLESS_URL博客文章向量库rag_postspgvector连接串必需SUPABASE_URL/SUPABASE_SERVICE_KEY资源站向量库products连接信息必需生成模型首选 兜底变量说明SENSENOVA_API_KEYS生成首选多把密钥用逗号/换行分隔按顺序轮询全部失败才顺延下一个平台模型固定deepseek-v4-flash思考模式已强制关闭MODELSCOPE_API_KEY可选兜底ModelScope 魔搭Llama-3.3-70B国内直连免费ZHIPU_API_KEY可选兜底智谱GLM-4.7-Flash永久免费、国内直连评论 / R2 图床变量说明CF_KV_NAMESPACE_ID/CF_KV_API_TOKENCloudflare KV评论 短链存储必需否则评论/短链接口 503CF_ACCOUNT_IDCloudflare 账户 IDR2 / KV 共用默认已知可不改UPLOAD_WORKER_URL/UPLOAD_WORKER_KEY上传 WorkerR2 绑定直写评论图优先于 S3 直传R2_ACCOUNT_ID/R2_ACCESS_KEY_ID/R2_SECRET_ACCESS_KEY/R2_BUCKET/R2_PUBLIC_URL文章朗读音频与网盘上传 R2 所用的 S3 凭据评论图已改走上传 Worker但音频与网盘仍走 S3 直传缺省则音频落本地public/audio/、网盘不可用网盘 / 短链变量说明DRIVE_TTL_HOURS网盘文件存活时长小时默认24到期由 KVexpirationTtl自动标记失效并需配合 R2 桶 Lifecycle 规则前缀drive/真正删除对象DRIVE_MAX_BYTES网盘单文件大小上限字节默认524288000500MB短链复用上方CF_KV_*网盘复用上方R2_*与CF_KV_*。临时邮箱变量说明TEMP_MAIL_D1_IDD1 数据库 IDCF_D1_API_TOKEND1 读写 Token含 D1:Edit 权限TURNSTILE_SECRETTurnstile 私密密钥注意不是站点密钥TEMP_MAIL_DOMAIN可选默认qiyuanmail.cc.cd资源站可选变量说明JWT_SECRET资源站用户登录 JWT 签名密钥必填否则/api/auth/*报错PUBLISH_KEYMCP 发布与图片上传密钥同时用于/api/publish与/api/images/upload可选PUBLIC_BASE_URL公开站点基址如https://www.qiyuan.icu用于生成分享 / SEO 链接资源站是独立部署的项目博客只是引用它的数据。完整步骤见下方「资源站搭建教程」。资源站搭建教程⚠️资源站与博客是两个相互独立的部署不要混为一谈资源站网盘资源分享站一个单独的 EdgeOne 项目源码在本仓库的resource-site/子目录拥有自己的边缘函数、Supabase 数据库与可选前端页面需单独部署、绑定自己的域名如resources.qiyuan.icu。博客通过共用同一套 Supabase 数据库 RESOURCES_API_PROXY指向资源站域名来引用资源数据在内置「资源」页/resources中展示、搜索、获取网盘链接。也就是说先把resource-site/当作独立项目部署好博客再指过去。二者可共用同一个 Supabase 项目也可各自独立。架构┌──────────────────── 资源站独立部署resource-site/ 浏览器 │ EdgeOne 项目 A域名如 resources.qiyuan.icu ├─ 资源站站点 ──────┤ ├─ edge-functions/api/[[default]].js认证/商品/评论/图片/MCP │ │ └─ Supabaseusers / products / reviews / ordersproduct-images 桶 │ └──────────────────── │ └─ 博客「资源」页 ──→ EdgeOne 项目 B博客本仓库根目录 /resources └─ /api 经 RESOURCES_API_PROXY 引用资源站或直连同一套 Supabase 读取 products一、部署资源站独立项目源码见resource-site/详细文档见resource-site/README.md。建库与 RLS在 Supabase SQL Editor 依次执行resource-site/database/schema.sql建表users/products/reviews/orders/quark_ordersresource-site/database/rls_policies.sqlRLSusers对 anon 完全不可见商品匿名只读上架建 Storage 桶创建product-images桶并设为公开或经/api/images/*代理。单独部署resource-site/将该目录作为独立 EdgeOne 项目部署边缘函数 可选静态前端并在其控制台配置环境变量SUPABASE_URLhttps://your-project.supabase.co SUPABASE_SERVICE_KEYeyJ... # 服务端密钥 JWT_SECRET*** # 资源站登录 JWT 签名密钥必填前端页面public/*.html未随模板附带可自行编写或从原站取用仅需 API 时可只部署边缘函数。二、让博客引用资源站数据层博客与资源站共用同一套 Supabase。如需 RAG 语义搜索在 Supabase 执行database/products_embedding.sql为products加向量列分类多语言可选执行database/resource_category_i18n.sql。配置指向博客侧设置RESOURCES_API_PROXY指向资源站域名如https://resources.qiyuan.icu本地开发时npm run dev会据此代理/api。开启资源页config/site.yaml中resources.enabled: true默认已开按需改label/icon/ownerUserId。部署博客推送到 GitEdgeOne Makers 自动构建并发布。验证# 对资源站域名验证curlhttps://resources.your-domain.com/api/categoriescurlhttps://resources.your-domain.com/api/products?limit2返回 JSON 即说明资源站已正常工作。管理后台可注册账号、发布商品密码需同时包含大写 小写 数字 符号。更多文档资源站独立部署说明 与 部署指南资源站 API 接口资源站数据库结构博客侧资源引用配置详细AI 资源发布提示词站点配置主配置在config/site.yaml常用项配置项说明site.title/site.subtitle站点标题与副标题site.name/site.author作者名称site.avatar头像路径当前/img/avatar.svg可换.jpg/.webpsite.url站点 URL用于 RSS 与 SEOsite.startYear建站年份tempMail.domain临时邮箱域名默认qiyuanmail.cc.cdturnstileSiteKeyTurnstile 站点密钥公开用于前端渲染验证框comment.provider评论提供商默认none可选custom/giscus/waline/twikoo替换头像将图片放到public/img/avatar.svg或同名.jpg/.webp并同步更新public/favicon.icofavicon 由头像生成。如何添加文章在src/content/blog/新建 Markdown/MDX 文件如my-post.md。在文件顶部写 frontmatter--- title: 我的文章标题 description: 一句话摘要 pubDate: 2026-06-05 heroImage: ./cover.png # 可选封面放同级或子目录 categories: - 笔记 tags: - 标签一 audio: true # 可选设为 true 即生成该篇文章的 Edge TTS 中文朗读音频详见上方「文章朗读」 --- 正文内容写在这里…封面图规则与文章同目录heroImage: ./cover.png在子目录heroImage: ./my-post/cover.png保存后本地npm run dev预览或npm run build构建。pubDate/heroImage会自动映射为date/cover与src/content.config.ts中的 schema 对齐。修改图片后建议运行npm run generate:lqips更新占位渐变。目录结构路径说明config/site.yaml站点主配置src/pages/页面路由含[lang]/多语言镜像src/content/blog/文章集合Markdown/MDXsrc/components/UI 组件含tempmail/、chat/src/layouts/页面布局edge-functions/api/[[default]].jsEdgeOne 边缘函数RAG 聊天 / 临时邮箱 / 评论 / 上传 / MCP / 统计cloud-functions/Makers 云函数博客图床上传等cloudflare/临时邮箱收信 Worker、D1 schema、wrangler 配置需自行部署到 Cloudflarepublic/静态资源favicon、图片、字体等scripts/generate-audio.mjs文章朗读音频生成Edge TTS → R2/CDN产出src/assets/audio-manifest.jsonsrc/assets/audio-manifest.json音频清单slug → { url, voice, chars, bytes, generatedAt }url带?v哈希缓存破坏部署推送到 Git 后由EdgeOne Makers自动构建npm run build并发布边缘函数随仓库部署。部署前需在 EdgeOne 控制台填好上面对应的环境变量尤其SILICONFLOW_API_KEY/NEON_SERVERLESS_URL/SUPABASE_*/SENSENOVA_API_KEYS/CF_KV_*。临时邮箱功能另需在Cloudflare 控制台完成部署cloudflare/下的收信 Worker、建 D1 表、配置 Email Routing catch-all → Worker、配置 Turnstile。详见各文件内注释。许可证本项目以MIT 许可证开源详见 LICENSE。你可以自由 fork、修改、部署为自己的博客只需保留版权与许可证声明商业用途亦可风险自负。