# 小树美术 · 冬季班招生

> 活页公开模板 `sample-course-enroll` · 场景: 招生 · 招聘 · 落地页 · 行业: 教育培训
> 任何人、任何 Agent 都可以读、照着改，不需要账号。示例内容均为虚构。
> 真页面: https://space.24haowan.com/s/3kOQQbd94_DM · 详情: https://space.24haowan.com/examples/sample-course-enroll

## 这是什么

课程招生页 · 培训班、兴趣班招生，发到家长群

## 什么时候用

兴趣班、培训机构、工作室按周排课招生：家长要先看哪天几点有哪个班、还剩几个位子，再约试听，选它 —— 课表按年龄段筛、点一节看老师和余位，试听预约写回数据表后余位跟着减。只有一个班、一个开课时间、要当场收学费的，选 service-landing（平台表单 + 收款码）；一次性的活动按场次收报名，选 sample-event-signup；学生自己每天打卡记进度，选 sample-study-plan。

## 用户对助手说的原话

帮我做一份兴趣班招生页，发成一个网页链接，发到家长群：页头是机构名、校区和「冬季班招生」，首屏一幅用 SVG 描边一笔笔画出来的插画，旁边列开课日期、年龄分班、小班人数、免费试听和报名截止；第一节是周课表，周一到周日横排、上午 / 午后 / 傍晚 / 晚上竖排，每节课写班级、课题、老师和余位，不同年龄段用不同颜色，上面能按年龄段筛选，点一节课在下面看这节做什么、老师、教室和一排表示名额的圆点，满了的提示同课题的其他时段，手机上改成一天一列横着滑、上面一排「一 二 三」能跳到那天；接着三张价格卡（按课时算单价，课时越多越便宜，总价和单价要对得上，中间那档标「多数家长选」）和停课、退费、续报、付款四条说明；然后一面学生作品墙（用 SVG 画几幅抽象画当示意，配题目、孩子小名和年龄）、老师介绍；最后是试听预约表单（孩子名字、年龄、想试听哪节、家长手机），提交后存进数据表，页面读回把那节课的余位减一，并出一张预约卡。颜色清爽，少用底色块；电脑上课表全宽排开。名额有变就更新同一个链接。

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

## 照着做一份

1. 读入口文件 https://space.24haowan.com/examples/sample-course-enroll/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-course-enroll ，返回预览链接、7 天分享与认领链接（登录后保留、链接不变）。

## 页面结构

- 冬季班课表
- 课程与价格
- 孩子们的画
- 四位老师
- 预约试听

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

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

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

- 可筛选的周课表（周一到周日 × 时段，按年龄段筛，点一节看老师和余位；手机上一天一列横着滑）
- 页末试听预约（原生表单写进数据表 trials，页面读回后把对应课节的余位减掉，提交后就地出一张预约卡）
- 名额、价格调整后更新同一条链接，家长群里那条不用重发

## 发之前要备好

- 数据表 trials（列 child / age / slot / phone，append_open=true）：文末试听预约写进这里，slot 是课节编号（如 sat-am-a），页面读回后把那节课的余位减掉；发布前先用 set_data 建好
- 联系方式类数据表建议设 members_only=true 或口令可看：页面读回会把已过审的行返回给每位读者（官方示例成品就是 members_only，访客的提交不会入表）

## 模板说明（README）

模板市场第三轮补齐「招生 · 落地页」场景的一份（总览见 `core/space/examples/README.md`，品质标准见 `core/space/examples/QUALITY.md`）。一家虚构的少儿美术工作室「小树美术」把冬季班招生发到家长群。示例数据均为虚构。

## 演示哪个特色

**一张能点、能筛、名额会跟着预约变的周课表 + 页末试听预约写回数据表。**

- **记忆点**是「冬季班课表」：周一到周日 × 上午 / 午后 / 傍晚 / 晚上四个时段，17 节课按年龄段（小芽 4–5 岁 · 小苗 6–8 岁 · 小树 9–12 岁）分三种颜色。上面一排按年龄段筛（不合适的课变淡）；点一节课，下面显示这节做什么、老师、教室和 8 个表示名额的圆点，满了的提示同课题还有位子的那一节。电脑上课表全宽排开；手机上一天一列、横着滑，上面一排「一 二 三…」点了跳到那天，打开时停在周六。
- 首屏插画是一棵用 SVG 路径描边「画出来」的树（`stroke-dasharray` + `pathLength="1"`，一秒左右画完，果子再一颗颗冒出来）；太阳的光芒慢慢转，是全页唯一的循环动画。`prefers-reduced-motion` 时直接停在画好的样子；动画只靠 CSS，不跑脚本也会画。
- 价格三档按课时算单价：12 课时 ¥180 = ¥2,160；24 课时 ¥160 = ¥3,840（比报两次 12 课时省 ¥480）；48 课时 ¥140 = ¥6,720（比分两次报 24 课时省 ¥960）。
- 发出去之后：页末「预约试听」是原生表单，写进数据表 `trials`；脚本在时页内提交、就地出一张预约卡，并读 `./_data/trials.json`，按 `slot` 数每节课被预约了几次，把课表、详情、下拉框里的余位和页头的总余位一起减掉（预约先占位，名额 = 8 − 已报 − 试听预约）。名额、价格变了就更新同一个页面，家长群里那条链接不用重发。

## 改哪里变成我的

| 位置 | 改什么 |
|---|---|
| 页头 `.org` / `h1` / `.lead` / `.facts` | 机构名、校区、学期；开课 / 结课日期、年龄分班、每班人数、试听与报名截止 |
| 首屏 `.pic svg` | 换成你自己的插画也行：每条要「画出来」的线加 `class="draw" pathLength="1"`，`style="--d:.5s"` 是第几秒开始画；要填色的再加 `fillin`，要冒出来的用 `pop` |
| 课表 `.week` | 一节课一个 `<button class="cls a-<年龄段>" data-id data-age data-course data-t data-room data-en>`：`data-id` 写成 `<周几>-<时段>-<教室>`（`sat-am-a`，脚本靠前两段认出是周六上午），`data-en` 是已报人数；同一格放两节就是两个教室同时上。时段在 `.tl`；每班名额在脚本 `CAP`（8） |
| 课题说明 / 老师名 | 脚本里的 `WHAT`（课题 → 一句话）与 `T`（老师代号 → 名字）；年龄段在 `AGE`，改了要同改按钮的 `a-` 类和 CSS 里的三个颜色变量 |
| 价格 `.plans` / `.terms` | 三档的课时、单价、总价（自己乘一遍），中间那档的「多数家长选」；停课、退费、续报、付款 |
| 作品墙 `.wall` | 现在是 SVG 代码画的抽象画（不是真实作品）；换成你学生的作品照片时用 WebP（≤300 KB/张），写 `alt` |
| 老师 `.teachers` | 名字、一句介绍；头像是姓氏字的圆章，不放真人照片也行 |
| 「预约试听」 | 原生 `<form class="trial" action="./_data/trials">`：字段名就是表里的列名；`slot` 的下拉每节课一个 `<option value="课节编号" data-age>`，要和课表的 `data-id` 一致；地址、电话、试听流程在 `aside` |
| 页脚 | 平台标志与名称（与 `core/space/src/theme.ts` 的 `MARK_SVG` / `PUBLIC_NAME` 逐字一致，测试咬着）+ 一句适用场景；发自己的招生页时整段删掉 |
| `manifest.json` | `title` / `share.title` / `share.desc`（微信卡片上的字） |

## 数据表

页末试听预约写进数据表 `trials`（一次一行，`append_open=true`）。发之前先建表：

```
set_data  proposal_id: <id>  table: "trials"  columns: ["child","age","slot","phone"]  rows: []  append_open: true  revision: 0
```

用 `list_data_rows table=trials` 读回（家长手机号只有你看得到；页面读回时脚本只数 `slot`，不显示别人的名字和电话）。
试听后定下来报名的孩子，改页面里那节课的 `data-en`（已报 +1）再发一版；没来的那行可以 `set_data_row_status action=delete` 把位子放回去。
本地 `space-cli serve` 会把提交写进包里的 `_data/trials.json`，试完记得改回 `[]`。

## 怎么发出去

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

没有终端时也可以 MCP `publish_file`（`filename: "index.html"`、`content` 为全文、`manifest` 为 manifest.json 去掉 entry、`hold: true`），再按上面建表。
给谁看：招生页要发到家长群，用 `set_visibility visibility="public"`（先和使用者确认）。

## 素材

- 没有位图：首屏插画、作品墙、机构标志都是内联 SVG（作品墙是代码画的抽象画，不是任何孩子的真实作品）；机构、老师、孩子、地址、电话均为虚构。
- `thumb.webp` / `phone.webp`：画廊缩略图，由 `examples/verify-shots.mjs --write-thumb --write-phone` 从成品截出，不进发布包。
