# 关西五日 · 四个人的 AA 账本

> 活页公开模板 `sample-split-bill` · 场景: 小工具 · 轻应用 · 行业: 个人家庭 / 旅游出行
> 任何人、任何 Agent 都可以读、照着改，不需要账号。示例内容均为虚构。
> 真页面: https://space.24haowan.com/s/th6d03w01SX8 · 详情: https://space.24haowan.com/examples/sample-split-bill

## 这是什么

旅行 AA 账本 · 一个链接发到群里，谁付钱谁记一笔

## 什么时候用

几个朋友出去旅行、合租室友、聚餐搭子要 AA：每人轮流垫钱，要一本大家都能往里记账的共享账本，最后自动算出谁转给谁多少、最少几笔两清，选它；花销有外币（日元）时自动按真实汇率折人民币。团长收订单、按商品汇总选 sample-group-buy；小店每天在用的经营小应用选 livepage-app；只是发行程攻略、不记账选 sample-weekend-trip。

## 用户对助手说的原话

帮我给这次四个人的日本旅行做一个 AA 账本，发成一个网页链接放到群里：页头是小队名、行程日期和地点、谁记账；最显眼的是一共花了多少（日元按今天汇率折人民币）、人均多少，旁边一个醒目的「+ 记一笔」主按钮（点了跳到表单），下面四个人每人一格写垫付了多少、自己的份多少、应收还是应付；接着「怎么还钱」：用最少的转账笔数算好谁转给谁多少，画成一张箭头图（四个人放四角，箭头从要付钱的人指向要收钱的人，金额写在箭头上，有金币沿箭头流动），下面列出转账清单和一个「一键复制结算结果」按钮，复制出来能直接贴进群；然后按天分组的账单流水，每笔写谁付的、类别、怎么分，点开看每人摊多少；再是按天的柱状图（带日均虚线）和按吃住行玩买的横条；最后一张「记一笔」表单（谁付的、金额、日元或人民币、花在哪、类别、分给谁可多选、日期），提交存进一张数据表，页面读回所有人记的账重新结算。汇率用欧洲央行参考汇率（Frankfurter 免费接口）的真实数据，页里先放一份今天的快照，打开时再拉实时的。电脑上左边账单流水、右边结算图，手机上一栏，图两端各画一套。

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

## 照着做一份

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

## 页面结构

- 总账
- 账单流水
- 怎么还钱
- 按天 · 按类别
- 记一笔

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

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

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

- 「记一笔」原生表单写回数据表（POST ./_data/expenses），页面读回与已有账单合并，重算每人已付 / 应付
- 最少转账结算：内联 SVG 箭头图，金币沿箭头流动；一键复制结算结果发到群里
- 真实外部数据两层加载：日元按欧洲央行参考汇率（经 Frankfurter）折人民币，页内快照先算、实时拉到就重算，标明来源与更新时间
- 按天柱状图 + 按类别横条，手机电脑各一套坐标；每笔可展开看分摊明细
- 同一链接一路记到结账，微信卡片（share.title / share.desc）

## 发之前要备好

- 数据表 expenses（列 payer / amount / currency / item / cat / split / day，append_open=true）：「记一笔」表单写进这里，页面读回与页内已有账单合并后重算；发布前先用 set_data 建好，结完账把 append_open 关掉

## 模板说明（README）

四个朋友去关西五日游的共享账本：总花费大数字、每人垫付 / 应付，「怎么还钱」用最少的转账笔数算好并画成箭头图，底下一张「记一笔」表单。小队、人名、金额均为虚构；汇率是真实数据。

## 演示哪个特色

**读者写回数据表 + 页面读回重算 + 真实汇率两层加载。**

- 「记一笔」是原生表单 `<form method="post" action="./_data/expenses">`：不跑脚本也能提交；脚本在时页内 `fetch` 提交，就地重算总账、结算图和两张小图，新的一笔滑进流水。
- 打开页面时读回 `./_data/expenses.json`（群里其他人记的），与页内 `#seed` 里已经记下的账合并后结算；`_status` 为 `held`（审核中）的行先不算。
- 结算按「最少转账笔数」：把每人差额分成尽可能多个和为 0 的小组（4 个人最多 3 笔），组内大额对大额。结果画成内联 SVG 箭头图，金币沿箭头流动（全页唯一的循环动效，`prefers-reduced-motion` 时停）；「一键复制结算结果」把总额、人均和每笔转账复制成一段能直接贴进群的文字（带页面链接）。
- 日元花销按欧洲央行参考汇率（经 Frankfurter，`api.frankfurter.dev`，免费、无需 key）折人民币：页里内联快照先算，脚本拉到实时汇率（3 秒超时）就整页重算并显示「实时 · 更新于 HH:MM」，拉不到就留快照、显示「数据更新于 <快照时间>」。页面始终写明来源。

## 改哪里变成我的

| 位置 | 改什么 |
|---|---|
| 页头 `.org` / `h1` / `.sub` | 小队名、记账人、更新日期、行程标题、日期与地点 |
| 脚本 `PEOPLE` | 人名（顺序决定颜色 `p0`–`p3` 与箭头图四角的位置）；表单里「谁付的」「分给谁」两组按钮同步改。人数不是 4 个时，`graphSvg` 里的 `px` / `py` 坐标改成你的人数（例如 3 人排成三角） |
| 脚本 `DAYNOTE` | 每天一句备注（到大阪、京都……），按天分组和柱状图的第二行都用它 |
| `#seed`（JSON） | 已经记下的账，一行一笔，列与数据表相同：`day` / `payer` / `item` / `cat`（吃 住 行 玩 买）/ `amount` / `currency`（JPY 或 CNY）/ `split`（名字用顿号隔开） |
| 外币 | 换成别的币种：快照 `#fx-snapshot` 的 `JPY_CNY` 字段、脚本里实时请求的 `base=JPY` 与「円」字样一起改（例：`base=THB`） |
| `manifest.json` | `title` / `share.title` / `share.desc`；节增减时 `sections` 与页里的 `id` / `data-track-section` 三处同改 |
| 页脚 | 平台标志与名称（与 `core/space/src/theme.ts` 的 `MARK_SVG` / `PUBLIC_NAME` 逐字一致）+ 一句适用场景；发自己的账本时整段删掉 |

**静态版本**：页里成对的 `bake:名字` 注释标记之间，是脚本按快照算好的结果（总账、流水、结算图、两张小图），不跑脚本时读者看到的就是它。改了 `#seed` 或人名后要重新生成：用浏览器打开 `index.html?bake=1`（这个参数不拉实时汇率），把每个带标记的元素渲染后的 `innerHTML` 写回标记之间（用 playwright 跑十几行脚本即可）；只想省事也可以删掉标记之间的内容，脚本在时照样完整。

**汇率快照的格式**（每日刷新任务按它重写）：

```html
<script type="application/json" id="fx-snapshot">{"source":"Frankfurter (api.frankfurter.dev) · 欧洲央行参考汇率","fetched_at":"2026-10-30T13:44:00+08:00","date":"2026-10-29","JPY_CNY":0.042146}</script>
```

取数：`curl -A '<你的标识>' 'https://api.frankfurter.dev/v1/latest?base=JPY&symbols=CNY'` → `date` 填 `date`，`rates.CNY` 填 `JPY_CNY`，`fetched_at` 写抓取时间。刷新后重新生成静态版本，发一个 quiet 新版本。

## 数据表

「记一笔」写进数据表 `expenses`（列 `payer` / `amount` / `currency` / `item` / `cat` / `split` / `day`，一笔一行，`append_open=true`）。发布前先建表：

```
set_data  proposal_id: <id>  table: "expenses"  columns: ["payer","amount","currency","item","cat","split","day"]  rows: []  append_open: true  revision: 0
```

用 `list_data_rows table=expenses` 读回大家记的账；结完账用 `set_data … append_open: false` 关掉，账本就定格了。本地 `space-cli serve` 会把提交写进包里的 `_data/expenses.json`，试完记得改回 `[]`。

## 怎么发出去

单文件，最省事的是 MCP `publish_file`（不需要终端）：

```
publish_file
  filename: "index.html"
  content: <index.html 全文>
  title: "关西五日 · 四个人的 AA 账本"
  manifest: <manifest.json 的内容，去掉 entry>
  hold: true            # 先看预览，确认后 publish_version
```

然后建好 `expenses` 表；给群里的人看用 `set_visibility`（`passcode` 口令可看，或 `public`）。之后要改人名、补旧账，传同一个 `proposal_id` 再发一版 —— 链接不变，表里大家记的账也不会丢。

## 纪律

- 结算按「今天的汇率」把日元折成人民币；要按刷卡当天的汇率，把每笔的人民币金额直接记成 CNY。
- 表单只有「谁付的」和金额是硬条件，没有登录；群外的人拿到链接也能记，所以别设成 `public`，用口令更稳。
- 页脚那句「示例内容，均为虚构」发自己的账本时删掉。
