# 最美班级风采 · 投票打榜

> 活页公开模板 `sample-vote-rank` · 场景: 互动玩法 · 行业: 教育培训 / 企业内部
> 任何人、任何 Agent 都可以读、照着改，不需要账号。示例内容均为虚构。
> 真页面: https://space.24haowan.com/s/2fTRGRngup2z · 详情: https://space.24haowan.com/examples/sample-vote-rank

## 这是什么

投票打榜 · 班级、团队、作品评选

## 什么时候用

要在群里发起一场评选、让大家点一下就投票并实时看排名的，选它：最美班级、优秀团队、最佳作品、年会节目、门店评比。候选一般 4–12 个，每个有一张封面和一句话。只是问大家「选哪个时间 / 去哪里」、不需要排名与领奖台的，选 sample-event-signup；请人来参加活动、收出席回执的，选 sample-invitation。

## 用户对助手说的原话

帮我做一个投票打榜的网页，发到家长群里让大家投：学校六一评「最美班级」，8 个班参选。手机竖屏为主，电脑上居中一块手机大小的舞台。首屏是活动主视觉（彩旗、气球的插画，大标题）、一个走秒的截止倒计时，下面是实时前三的领奖台：中间第一、左边第二、右边第三，柱子高度按票数比例，页面打开时柱子从台面长出来，柱顶是班级头像、班名和票数；接着是 8 个班的卡片，按票数排名，每张有插画封面、班名和昵称、一句口号、一句做了什么、一条票数条和「投一票」按钮，点了票数 +1 往上飘、名次变了卡片要动画交换位置，有轻的提示音（可静音）；每人每天 3 票，只在页面上提示还剩几票；投票存到一张数据表（每行一票：班级、投票人称呼），页面读这张表把票数加到已有票数上，领奖台、卡片和总票数三处要对得上；脚本不跑时也能看静态排行，并有一个选班级的投票表单。最后写活动规则（投票时间、每天几票、谁能投、平票怎么算）和奖项设置。颜色明快但别花，插画全用内联矢量图画。以后补候选或改截止时间就更新同一个链接。

如果你还没有活页连接器（MCP），先读 https://space.24haowan.com/for-agents.md ，照里面的说明接入，或不登录直接发布。

## 照着做一份

1. 读入口文件 https://space.24haowan.com/examples/sample-vote-rank/source/index.html（它引用的其他文件见下方列表）。
2. 保留结构、版式和交互，把内容**全部**换成用户自己的；模板里的公司、人名、数字都是虚构的，一样都别留。
3. 交付一个自包含的单文件 HTML：样式写在页面里，不引外部字体 / 脚本 / CDN；手机 375 宽和电脑 1440 宽都要好看，模板有暗色就保留暗色。
4. 要发成微信里能打开、改了链接不变的网页：接入活页（https://space.24haowan.com/for-agents.md）后发布；没有账号也可以让用户在 https://space.24haowan.com/quick 上传这个文件。
5. 没有活页工具、但能发 HTTPS 请求：把做好的 HTML 以 Content-Type: text/html POST 到 https://space.24haowan.com/api/quick?client=template-sample-vote-rank ，返回预览链接、7 天分享与认领链接（登录后保留、链接不变）。

## 页面结构

- 实时排行
- 8 个班
- 投票
- 规则与奖项

## 文件（公开，纯文本）

- https://space.24haowan.com/examples/sample-vote-rank/source/index.html（入口）

## 发成活页之后还能做的

- 一键投票写回数据表（原生表单 POST ./_data/votes 打底，脚本在时页内提交），页面读回实时算票数和排名
- 首屏领奖台按票数长高、名次变化时卡片换位，排行本身就是一张值得截图转发的画面
- 同一链接更新不变（补候选、改截止时间都在这一页），阅读回执看看哪几节被看了
- 微信卡片（share.title / share.desc）

## 发之前要备好

- 数据表 votes（列 class / voter，append_open=true）：「投一票」和文末表单都写进这里，一行一票，页面读回加到基础票数上；发布前先用 set_data 建好，到截止时间把 append_open 关掉

## 模板说明（README）

模板市场第二波「富媒体 H5」模板之一（总览见 `core/space/examples/README.md`，品质标准见 `core/space/examples/QUALITY.md`）。虚构的「澄溪路小学」六一「最美班级风采」评选，家长群里转发投票。示例内容均为虚构。

## 演示哪个特色

**群里点一下就投票，排名实时变 —— 投票写回数据表，页面读回算票。**

- **记忆点**是首屏的领奖台：内联 SVG，中间第一、左第二、右第三，柱高 = 票数 / 第一名票数 × 140，页面打开时柱子从台面长出来，柱顶是班级头像、班名、票数。上面是彩旗气球的主视觉和走秒的截止倒计时（真在投票期里打开走真时间，否则停在样例里的 5 月 28 日 10:18:37 往下走）。
- 8 张候选卡片按票数排名。点「投一票」：票数 +1 往上飘、数字跳一下、名次变化时卡片用 FLIP 动画交换位置（四（5）班 296、五（2）班 294，给五（2）班投两票就能看到换位），同时一声 Web Audio 现合成的「叮」（只在点按后发声，右上角静音）和一下轻震。
- **数字自洽**：每张卡片的 `data-base` 是基础票数（8 个班合计 2,660），页面读 `./_data/votes.json`（一行一票）加上去；领奖台、卡片、总票数三处同一个来源。
- 每人每天 3 票只在前端提示（记在本机，读得到 `_mine` 行时也算进去），不是服务端限制。
- 降级：脚本不跑时领奖台和排行按 `data-base` 静态显示，「投一票」跳到文末原生表单（`<form method="post" action="./_data/votes">`），照样能投；`prefers-reduced-motion` 时所有动效停在终态。

## 改哪里变成我的

| 位置 | 改什么 |
|---|---|
| 顶栏 `.school` | 主办方标志与名称 |
| `.art h1` / `.sub` | 活动名、一句说明 |
| 脚本里的 `START` / `END` / 样例此刻 | 投票起止时间；`.cd small` 那行同步改 |
| `#pod` 领奖台 | 三个台位的头像（`use href="#ic-…"`）、班名、票数、柱高写成不跑脚本时的初值（脚本会按票数重算） |
| `.list` 卡片 | 每个候选一张 `li.card`：`data-name`（也是写进表里的 `class` 值）、`data-nick`、`data-ic`（封面插画 symbol）、`data-base`（基础票数，新活动写 0）；按票数从高到低排，`.no` 写名次 |
| 顶部 `<symbol id="ic-…">` | 封面插画，88×88 内联 SVG，一个候选一个 |
| 文末表单 `select[name=class]` | 选项的 `value` 与卡片 `data-name` 逐字一致 |
| `PER_DAY` | 每人每天几票（同步改「活动规则」那句） |
| 规则 `.rules` / 奖项 `.prizes` | 活动规则、奖项设置、联系人 |
| 页脚 | 平台标志与名称（与 `core/space/src/theme.ts` 的 `MARK_SVG` / `PUBLIC_NAME` 逐字一致，测试咬着）+ 一句适用场景；发自己的活动时整段删掉 |
| `manifest.json` | `title` / `share.title` / `share.desc`（微信卡片上的字） |

## 数据表

投票写进数据表 `votes`（一行一票，列 `class` / `voter`，`append_open=true`）。发之前先建表：

```
set_data  proposal_id: <id>  table: "votes"  columns: ["class","voter"]  rows: []  append_open: true  revision: 0
```

用 `list_data_rows table=votes` 读回、核对异常票。到截止时间用 `set_data` 传 `append_open: false` 关掉写回（页面会提示「投票已经截止了」）。本地 `space-cli serve` 会把投票写进包里的 `_data/votes.json`，试完记得改回 `[]`。

## 怎么发出去

```bash
export SPACE_TOKEN=sk-space-…            # MCP create_cli_token
node core/space/cli/space-cli.mjs push core/space/examples/sample-vote-rank \
  --proposal <proposal_id> --manifest core/space/examples/sample-vote-rank/manifest.json --hold
```

没有终端时也可以 MCP `publish_file`（`filename: "index.html"`、`content` 为全文、`manifest` 为 manifest.json 去掉 entry、`hold: true`），再按上面建表。
要发到家长群：确认后 `set_visibility` 设成 `public`（或 `passcode` 只给本校家长），把链接转进群里。

## 素材

- 没有位图：主视觉、封面插画、奖牌、标志都是内联 SVG；学校、班级、人名与票数均为虚构。
- `thumb.webp` / `phone.webp`：画廊缩略图与手机首屏图，由 `examples/verify-shots.mjs --write-thumb --write-phone` 从成品截出，不进发布包。
