diff --git a/CMS-Bot.md b/CMS-Bot.md new file mode 100644 index 0000000..7470727 --- /dev/null +++ b/CMS-Bot.md @@ -0,0 +1,92 @@ +# cms-bot 使用教程 + +cms-bot 是本模板的**投稿机器人**——一个 GitHub App。访客在「📝 投稿」「🎵 投稿音乐」页面提交表单后,你的 Cloudflare Pages Function 会以 cms-bot 的身份在仓库里创建分支并发起 Pull Request;你审核合并后,Pages 自动重新构建,内容上线。 + +``` +表单提交 → /api/submit(Pages Function) + → 以 cms-bot 身份建分支 chronicle/* 或 music/* + → 自动开 PR → 管理员合并 → 站点自动更新 +``` + +由 cms-bot 发起的 PR 会自动打上「班史投稿」/「音乐投稿」标签(`.github/labeler.yml`)。 + +## 一、创建 App + +> GitHub App 名字全局唯一,`cms-bot` 若被占用就换一个(如 `xx-class-cms-bot`)。 +> App 归创建它的账号/组织所有——建议在自己的账号(或组织)下创建,私钥不假人手。 + +### 方式 A:手动创建(通用) + +1. 打开 GitHub → 头像 → **Settings → Developer settings → GitHub Apps → New GitHub App**。 + (组织仓库也可以在组织 Settings → Developer settings 里建,让 App 归组织所有。) +2. 按下表填写: + +| 字段 | 填写 | +| --- | --- | +| GitHub App name | `cms-bot` | +| Homepage URL | 你的仓库地址 | +| Webhook → **Active** | **取消勾选**(本模板只用 REST API,不需要 webhook) | +| Repository permissions → **Contents** | **Read and write** | +| Repository permissions → **Pull requests** | **Read and write** | +| Where can this GitHub App be installed | **Any account**(= 公开,任何仓库都能安装) | + +3. 页面底部 **Create GitHub App**。 + +### 方式 B:一键创建链接(manifest 流程) + +适合帮别人预填全部权限。生成一个一次性 code(1 小时有效),对方打开链接点一下 Create 即可: + +```bash +source ~/proxy.sh # 如需代理 +curl -sX POST https://api.github.com/user/apps/from-manifest \ + -H "Authorization: Bearer $(gh auth token)" \ + -H "Accept: application/vnd.github+json" \ + -d '{"name":"cms-bot","url":"https://github.com/Vb-Lg/class-history-template","public":true,"default_permissions":{"contents":"write","pull_requests":"write"}}' +# 返回 {"code":"xxxx"} → 创建链接: +# https://github.com/app/apps-from-manifest/xxxx +``` + +## 二、拿到三样凭据 + +创建完成后,在 App 设置页(Settings → Developer settings → GitHub Apps → cms-bot): + +1. **App ID**:页面「About」区,纯数字。 +2. **私钥**:底部 **Private keys → Generate a private key**,自动下载 `.pem` 文件;用文本编辑器打开,**全文**(含 `BEGIN/END` 行)即 `GITHUB_PRIVATE_KEY`。 +3. **Installation ID**:左侧 **Install App** → Install → 选你的仓库;安装页 URL `https://github.com/settings/installations/<数字>` 中的数字即 Installation ID。 + +## 三、配置 Cloudflare Pages + +Pages 项目 → Settings → Variables and Secrets(Production 与 Preview 都加): + +| 变量 | 值 | +| --- | --- | +| `GITHUB_APP_ID` | App ID | +| `GITHUB_INSTALLATION_ID` | Installation ID | +| `GITHUB_PRIVATE_KEY` | `.pem` 私钥全文 | +| `GITHUB_OWNER` | 仓库所有者(用户名或组织名) | +| `GITHUB_REPO` | 仓库名 | + +可选覆盖项见 [[Deployment\|部署]] 的环境变量总表。 + +## 四、验证 + +1. 打开线上站点「📝 投稿」页,填一篇测试投稿提交; +2. 出现「✅ 已创建 PR #N」并附链接即成功; +3. 仓库 Pull requests 里应有一条由 **cms-bot** 发起的 PR(自动带标签); +4. 合并后 Pages 自动重建,内容出现在「📖 班史列表」。 + +## 常见问题 + +| 现象 | 原因 / 处理 | +| --- | --- | +| `installation token failed` | App ID / 私钥 / Installation ID 不匹配,或 App 没安装到该仓库 | +| `分支不存在: main` | `GITHUB_BASE_BRANCH` 与仓库默认分支不一致 | +| PR 创建成功但站点没更新 | Pages 构建失败或未触发,看 Cloudflare 部署日志 | +| 提交报「服务异常」 | 看 Pages 的 Functions 日志(Deployment → Functions logs) | +| 想改投稿目标目录 | 配 `CONTENT_DIR` / `SONGS_DIR` / `MEDIA_DIR` 等变量 | + +## 安全须知 + +- `.pem` 私钥 = bot 的完整身份:**只**存在 Cloudflare 环境变量里,不要提交进仓库、发群里、写进 wiki。 +- 因此**每个独立部署的班级都建议创建自己的 App**(按上面步骤约 5 分钟),而不是共用同一个 cms-bot 的私钥——谁拿到私钥,就能以 bot 身份写入它安装过的**所有**仓库。 +- bot 只需要 Contents 和 Pull requests 两项权限,不要多开。 diff --git a/Content-Format.md b/Content-Format.md new file mode 100644 index 0000000..2e28bc6 --- /dev/null +++ b/Content-Format.md @@ -0,0 +1,54 @@ +# 内容格式 + +## 班史文章 `src/content/YYYYMMDD.md` + +文件名用日期(同一天多篇加 `-1`、`-2` 后缀),frontmatter 字段: + +| 字段 | 必填 | 说明 | +| --------- | ---- | -------------------------------------- | +| `title` | ✓ | 标题 | +| `date` | ✓ | 日期 `YYYY-MM-DD`,决定排序 | +| `summary` | | 摘要,显示在列表页和文章页副标题 | +| `author` | | 记录人 | +| `cover` | | 封面图路径,如 `/pages/static/xxx.png` | + +正文支持完整 Markdown,含 `
` 折叠块。示例: + +```markdown +--- +title: 运动会夺冠记 +date: 2025-09-28 +summary: 4×100 接力最后一棒逆转 +author: 体育委员 +cover: /pages/static/sports-day.png +--- + +# 运动会夺冠记 + +正文…… +``` + +文章生成到 `/pages/<文件名去扩展名>`,例如 `src/content/20250928.md` → `/pages/20250928`。 + +## 歌曲 `src/songs/*.json` + +```json +{ + "title": "歌名", + "artist": "歌手", + "date": "20250901", + "link": "https://...", + "note": "这首歌和班级的故事", + "author": "推荐人" +} +``` + +- `title`、`artist` 必填;`link` 须以 `http(s)://` 开头; +- `date` 用 `YYYYMMDD` 字符串,决定排序; +- 文件名任意(不冲突即可),在线投稿生成的形如 `20251005-a1b2c3.json`。 + +## 静态资源 + +文章引用的图片、音视频放 `public/pages/static/`,正文以 `/pages/static/文件名` 引用。投稿表单上传的封面图也会由后端提交到该目录。 + +以上三类内容也都可以不经过表单、直接改文件提交——投稿表单只是给同学用的便捷入口(见 [[CMS-Bot|cms-bot 使用教程]])。 diff --git a/Deployment.md b/Deployment.md new file mode 100644 index 0000000..fc40d84 --- /dev/null +++ b/Deployment.md @@ -0,0 +1,47 @@ +# 部署到 Cloudflare Pages + +## 1. 连接仓库 + +Cloudflare Dashboard → Workers & Pages → Create → Pages → Connect to Git → 选择模板仓库。 + +## 2. 构建配置 + +| 配置项 | 值 | +| --- | --- | +| Framework preset | None(或 Astro) | +| Build command | `npm run build` | +| Build output directory | `dist` | +| 环境变量 | `NODE_VERSION = 22.12.0` | + +## 3. Pages Functions + +`functions/` 目录会被自动部署为 Pages Functions,无需额外配置: + +- `POST /api/submit` —— 投稿 → GitHub PR(需配置 [[CMS-Bot|cms-bot]]) +- `GET/POST /api/messages` —— 留言墙(需绑定 D1,见 [[Message-Board|留言墙]]) + +## 4. 环境变量总表 + +在 Pages 项目 → Settings → Variables and Secrets 中配置(Production 与 Preview 都要): + +| 变量 | 必填 | 用途 | +| ------------------------ | ---- | -------------------------------------------------- | +| `NODE_VERSION` | ✓ | `22.12.0` | +| `GITHUB_APP_ID` | ✓* | cms-bot 的 App ID(*启用投稿功能需要) | +| `GITHUB_INSTALLATION_ID` | ✓* | cms-bot 的 Installation ID | +| `GITHUB_PRIVATE_KEY` | ✓* | cms-bot 的 `.pem` 私钥全文 | +| `GITHUB_OWNER` | ✓* | 仓库所有者 | +| `GITHUB_REPO` | ✓* | 仓库名 | +| `GITHUB_BASE_BRANCH` | | 投稿目标分支,默认 `main` | +| `CONTENT_DIR` | | 文章目录,默认 `src/content` | +| `MEDIA_DIR` | | 上传文件目录,默认 `public/pages/static` | +| `MEDIA_URL_PREFIX` | | 上传文件 URL 前缀,默认 `/pages/static` | +| `SONGS_DIR` | | 歌曲目录,默认 `src/songs` | +| `TURNSTILE_SECRET_KEY` | | Turnstile 私钥,见 [[Turnstile\|Turnstile]] | +| `PUBLIC_TURNSTILE_SITE_KEY` | | Turnstile 站点 key(**构建时**变量,需加入构建环境) | + +不配置 GitHub 相关变量时:站点正常浏览,仅投稿功能不可用。 + +## 5. 后续更新 + +合并任何投稿 PR 或直接 push 到默认分支后,Pages 会自动重新构建部署,内容随即上线。 diff --git a/Home.md b/Home.md index 95b302d..72bfa46 100644 --- a/Home.md +++ b/Home.md @@ -1 +1,27 @@ -Welcome to the class-history-template wiki! +# 班史模板 class-history-template + +基于 **Astro 7 + Cloudflare Pages** 的班级纪念册模板:班史文章、班级歌单、留言墙、在线投稿(PR 审核流)开箱即用。 + +## 功能一览 + +- 🏠 **首页**:班级简介、人物志、荣誉墙、记忆墙(均为示例文案,可自行替换) +- 📖 **班史列表 / 文章页**:`src/content/*.md` 自动生成,按日期升序排列,支持封面、摘要、上下篇导航 +- 🎵 **班级歌单**:`src/songs/*.json` 自动生成,支持每日随机排序、随机抽歌 +- 💬 **留言墙**:Cloudflare D1 数据库存储 +- 📝 **在线投稿**:班史 / 音乐两种表单,提交后由 [[CMS-Bot|cms-bot]] 自动建分支并发 PR,管理员审核合并后自动发布 + +## 文档导航 + +| 页面 | 内容 | +| --- | --- | +| [[Quick-Start\|快速开始与定制]] | 本地开发、班级信息定制、删除示例内容 | +| [[Content-Format\|内容格式]] | 班史文章 / 歌曲的文件格式与字段说明 | +| [[Deployment\|部署到 Cloudflare Pages]] | 构建配置、环境变量总表 | +| [[CMS-Bot\|cms-bot 使用教程]] | 投稿机器人的创建、安装与配置 | +| [[Message-Board\|留言墙(D1)]] | D1 数据库建表与绑定 | +| [[Turnstile\|Turnstile 人机验证]] | 投稿表单人机验证(可选) | + +## 相关链接 + +- 模板仓库:[Vb-Lg/class-history-template](https://github.com/Vb-Lg/class-history-template) +- cms-bot 公开页(创建后可用):https://github.com/apps/cms-bot diff --git a/Message-Board.md b/Message-Board.md new file mode 100644 index 0000000..a8dfb31 --- /dev/null +++ b/Message-Board.md @@ -0,0 +1,40 @@ +# 留言墙(D1) + +首页留言墙由 `functions/api/messages.js` 提供,数据存在 Cloudflare D1 里。 + +## 1. 创建数据库 + +Dashboard → Storage & Databases → **D1** → Create database(名字随意,如 `class-history-messages`)。 + +## 2. 建表 + +在 D1 控制台的 Console 里执行: + +```sql +CREATE TABLE IF NOT EXISTS messages ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + text TEXT NOT NULL, + time TEXT NOT NULL, + ip TEXT, + created_at INTEGER NOT NULL +); +``` + +## 3. 绑定到 Pages + +Pages 项目 → Settings → Functions → **D1 database bindings**: + +| Variable name | D1 database | +| --- | --- | +| `DB` | 刚创建的数据库 | + +绑定名必须是 **`DB`**(代码里 `env.DB` 取的就是它)。 + +## 行为说明 + +- 同一 IP 两条留言间隔至少 20 秒; +- 名字最长 12 字,内容最长 120 字,未填名字显示「匿名同学」; +- 列表按时间倒序返回最多 200 条,库内只保留最近 500 条(自动清理)。 + +不绑定 D1 时:页面其余功能正常,留言墙显示「数据库未绑定」。 diff --git a/Quick-Start.md b/Quick-Start.md new file mode 100644 index 0000000..38eb2d0 --- /dev/null +++ b/Quick-Start.md @@ -0,0 +1,31 @@ +# 快速开始与定制 + +## 环境要求 + +Node.js ≥ 22.12。 + +## 本地开发 + +```bash +npm install +npm run dev # http://localhost:4321 +``` + +注意:`npm run dev` 只渲染页面,`/api/*` 由 Cloudflare Pages Functions 提供服务,**只有线上可用**——本地留言墙会显示「加载失败」、投稿提交会报错,属正常现象。需要本地调试 API 时可用 `npx wrangler pages dev`。 + +## 定制班级信息 + +1. **`src/site.config.ts`**:班级名、顶栏 logo、首屏徽章、首页统计数字——改这一个文件,全站所有「XX届X班」字样自动更新。 +2. **`src/pages/index.astro`**:班级简介、人物志、荣誉、记忆墙的示例文案(搜索 `20XX` 和各区块的中文示例)。 +3. **`public/js/index.js`**:首屏打字机轮播文案(`lines` 数组)。 +4. 主题色(金色 `#e6c068`)在 `public/css/*.css` 中定义。 + +## 删除示例内容 + +模板自带三处示例,正式使用前删除前两个: + +- `src/content/20250101.md` —— 示例文章 +- `src/songs/20250101-example.json` —— 示例歌曲 +- `public/pages/static/cover-placeholder.svg` —— 占位封面(可保留备用) + +正式写内容请看 [[Content-Format|内容格式]]。 diff --git a/Turnstile.md b/Turnstile.md new file mode 100644 index 0000000..54cd5ff --- /dev/null +++ b/Turnstile.md @@ -0,0 +1,25 @@ +# Turnstile 人机验证(可选) + +给投稿表单加上 Cloudflare Turnstile 人机验证,防脚本刷 PR。**不配置则跳过验证**,功能不受影响。 + +## 1. 创建站点 + +Dashboard → **Turnstile** → Add site → 拿到一对 key: + +- **Site Key**(前端用) +- **Secret Key**(后端用) + +## 2. 配置 + +两个变量**成对配置**才启用: + +| 变量 | 配在哪 | 说明 | +| --- | --- | --- | +| `PUBLIC_TURNSTILE_SITE_KEY` | Pages **构建时**环境变量(本地构建写入 `.env`) | 注入前端,渲染验证组件 | +| `TURNSTILE_SECRET_KEY` | Pages 运行时环境变量 | `functions/api/submit.ts` 校验 token | + +> 注意 site key 是**构建时**变量:改了它要重新部署才生效。 + +## 3. 验证 + +线上打开投稿页,表单下方出现 Turnstile 验证组件即已启用;提交时会先校验,未通过提示「请先完成人机验证」。 diff --git a/_Footer.md b/_Footer.md new file mode 100644 index 0000000..5ebff78 --- /dev/null +++ b/_Footer.md @@ -0,0 +1 @@ +class-history-template · 有问题欢迎提 [Issue](https://github.com/Vb-Lg/class-history-template/issues) diff --git a/_Sidebar.md b/_Sidebar.md new file mode 100644 index 0000000..7c5243b --- /dev/null +++ b/_Sidebar.md @@ -0,0 +1,13 @@ +**班史模板 · 文档** + +- [[Home|首页]] +- [[Quick-Start|快速开始与定制]] +- [[Content-Format|内容格式]] +- [[Deployment|部署到 Cloudflare Pages]] +- [[CMS-Bot|cms-bot 使用教程]] +- [[Message-Board|留言墙(D1)]] +- [[Turnstile|Turnstile 人机验证]] + +--- + +[仓库](https://github.com/Vb-Lg/class-history-template) · [Issues](https://github.com/Vb-Lg/class-history-template/issues)