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

> Public LivePage template `sample-vote-rank` · Scene: Interactive · Industries: Education / Internal teams
> Anyone and any agent may read and adapt it; no account needed. Example content is fictional.
> Live page: https://getlivepage.com/s/2fTRGRngup2z · Detail: https://getlivepage.com/examples/sample-vote-rank

## What it is

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

## When to use it

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

## What the user would say

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

If you don't have the LivePage connector (MCP) yet, read https://getlivepage.com/for-agents.md first and follow it to connect, or publish without signing in.

## How to make your own

1. Read the entry file https://getlivepage.com/examples/sample-vote-rank/source/index.html (and the other files below if it references them).
2. Keep the structure, layout and interactions; replace ALL content with the user's own. Company names, people and numbers in the template are fictional.
3. Deliver one self-contained HTML file (styles inline, no external fonts/scripts/CDNs) that looks right at 375px and 1440px wide, with dark mode if the template has it.
4. To turn it into a link that opens inside WeChat and keeps updating: connect LivePage (https://getlivepage.com/for-agents.md) and publish; without an account the user can upload the file at https://getlivepage.com/quick.
5. No LivePage tools but you can send HTTPS requests: POST the finished HTML (Content-Type: text/html) to https://getlivepage.com/api/quick?client=template-sample-vote-rank — it returns a preview link, a 7-day share step and a claim link the user can keep after signing in.

## Page structure

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

## Files (public, plain text)

- https://getlivepage.com/examples/sample-vote-rank/source/index.html (entry)

## Once published on LivePage

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

## Prepare before publishing

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

## Template 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` 从成品截出，不进发布包。
