feat(website,docs,build): 官网加一个下载页(挑版本装机),文档站的照片换成与 README 同一份

下载页(`website/download.html` + `assets/download.js`)

- 官网首页的「立即下载」、顶栏与页脚的「取安装包」全部指向新页 `/download.html`。
  那一页是「先挑一个版本,再挑要装的那一份」:一个版本分段控件 + 四张卡
  (班级端 / 服务端 Windows / 服务端 Linux / ClassIsland 插件),每张卡列出这一版里
  真实存在的文件、体积与直链;
- 版本与文件清单**不在站点里存副本**,每次打开都由 `assets/download.js` 当场读 GitHub
  Releases —— 文件名、体积、链接照抄发布页,不靠命名约定去猜;
- 读不到时(离线,或匿名接口 60 次/小时按出口 IP 被限流)退回页面上那份
  `<meta name="ch-version">`,按发布命名约定拼直链,并在页面上**明说这是拼出来的**;
- 老版本缺哪个包就显示「这一版没有发布…」(`v0.1.0-fix` 只有插件包,实测正确);
  Linux 那一行安装命令跟着选中版本钉上 `--version`(tag 不是 `x.y.z` 时不带);
- 动态建出来的卡片与文件行派发 `ch:content`,由 `main.js` 补挂按压反馈
  —— 这些元素是拉到清单之后才出现的,启动时还看不到它们。

文档站的照片(`docs/images/`)

- 页面里的图一律从 `docs/screenshots/**` 换成 `docs/images/**`:后者就是 README 与官网
  吃的那一份(字节相同),前者是 9-26 的冒烟留档,比 README 落后一个版本;
- 展示图与回归留档这两套图的分工写进 `docs/dev/testing.md`「截图留档」,含重新采集命令
  (冒烟会把「岛外留白对照图」落在同一个目录,所以要先落临时目录再挑);
- 顺带修 README 手机截图那张标错的图注(`mobile-dashboard.jpg` 是仪表盘,不是抽屉菜单);
- `docs/reference.md` 验收表里那张 ClassIsland「真机实测截图」不再嵌图:它是连着桌面、
  任务栏和另一个窗口整屏截下来的,当文档配图不能用。断言与用例名都保留,另外注明了抓图位置。

版本落点

- `scripts/version.mjs` 增加 `website/download.html` 的兜底版本号,落点 13 → 14 处
  (`AGENTS.md` §4.4 与 `docs/dev/release.md` 同步);
- README「开始使用」表里那三个文件名改成**发布页上真实的名字**
  (`-x64-client-setup` / `-x64-client-portable` / `-x64-server-setup`)—— 原来写的是构建
  产物的名字;「上传前把产物改成 ASCII 名」这一步也一并写进发布流程,
  它是官网下载页离线兜底与 README 表格的共同依据。
This commit is contained in:
LoveChengke committed 2026-10-06 18:37:42 +08:00
1 parent ded10118f5
commit 0ea6bd887f
15 files changed
+1235 -167

No files matched your search

+29 -6
View File
@@ -80,20 +80,43 @@ pnpm build && pnpm verify:web
## 截图留档
回归测试顺手把截图存到 `docs/screenshots/`(island / client / web-mobile / classisland 四组),
文档站里用的就是这些图。要重新采集:
截图分两套,各管一件事:
| 目录 | 谁在用 | 谁产出 |
| ------------------- | ----------------------------------------------------------- | --------------------------------------------------------------------- |
| `docs/images/` | **文档站、README、官网用的是同一份图**,页面上展示的都是它 | `capture-shots.mjs`(Web / 手机)+ 客户端冒烟(客户端 / 灵动岛) |
| `docs/screenshots/` | 回归留档,页面不展示;`verify:*` 的像素级断言比对的就是它们 | 各冒烟脚本自动写入(island / client / web-mobile / classisland 四组) |
**展示图重新采集**(保证文档站与 README、官网用的是同一份图):
```bash
pnpm dev:server # 后端同时托管 Web 管理端
CAPTURE_OUT=docs/images,website/assets/shots node website/tools/capture-shots.mjs # → web-*.jpg / mobile-*.jpg
# 客户端与灵动岛走的是冒烟脚本。它除了正片,还会顺手落一份「岛外留白对照图」
# (*-window.png / *-backdrop.png),所以先落到临时目录,再挑要用的拷进去。
ISLAND_SHOTS_DIR="$PWD/.cache/shots" ELECTRON_CLIENT_SHOTS_DIR="$PWD/.cache/shots" \
ELECTRON_SMOKE_ISLAND_ACCENT='#0a84ff' ELECTRON_SMOKE_ISLAND_STYLE=black \
ELECTRON_SMOKE_USER=teacher1 ELECTRON_SMOKE_PASSWORD=123456 \
node packages/desktop-client/scripts/smoke.mjs
cp .cache/shots/{island-*,client-*}.png docs/images/
rm -f docs/images/*-window.png docs/images/*-backdrop.png
cp docs/images/{island-*,client-*}.png website/assets/shots/ # 官网那份保持同步
```
**回归留档重新采集**(同一套冒烟,把输出指到留档目录):
```bash
pnpm dev:server
ISLAND_SHOTS_DIR=F:/ClassHelper/.cache/island-shots \
ELECTRON_CLIENT_SHOTS_DIR=F:/ClassHelper/.cache/client-shots \
ISLAND_SHOTS_DIR="$PWD/.cache/island-shots" \
ELECTRON_CLIENT_SHOTS_DIR="$PWD/.cache/client-shots" \
ELECTRON_SMOKE_ISLAND_ACCENT='#0a84ff' ELECTRON_SMOKE_ISLAND_STYLE=black \
ELECTRON_SMOKE_USER=teacher1 ELECTRON_SMOKE_PASSWORD=123456 \
node packages/desktop-client/scripts/smoke.mjs
```
官网的实机图则用 `website/tools/capture-shots.mjs`(采集步骤见 `README.md` §7)。
> 展示图都是**逻辑像素 1×**(灵动岛的 268×44、424×230 就是这个数,不再乘 2),
> 页面按原始尺寸显示即可 —— 换图时别顺手放大,否则整页的尺寸对不上。
> 采集脚本会把窗口真的弹在屏幕上。客户端留档会**临时停掉 CSS 动画**再截图 ——
> 窗口被遮挡时 Chromium 冻结动画,而页面入场动画的起始帧是 `opacity: 0`,
> 不停掉的话截出来是**整片空白**(DOM 里文本齐全,只有图是空的)。