# 出口报价利润试算台

> 活页公开模板 `sample-trade-margin` · 场景: 小工具 · 轻应用 · 行业: 电商外贸 / 制造供应链
> 任何人、任何 Agent 都可以读、照着改，不需要账号。示例内容均为虚构。
> 真页面: https://space.24haowan.com/s/tOzW8wawbyFg · 详情: https://space.24haowan.com/examples/sample-trade-margin

## 这是什么

出口报价利润试算台 · 外贸业务员自用，填成本出三档外币报价，拖汇率看哪里会亏

## 什么时候用

要一个自己天天用的报价小工具：外贸业务员、小工厂老板按采购成本、退税、杂费、海运费和目标利润率倒推 EXW / FOB / CIF 外币报价，用真实汇率算利润和保本汇率，并把每轮报价存下来。选它的关键是「我自己算、看汇率风险、存版本」。要发给客户看、让客户选配置和数量出总价，选 sample-quote-sheet；要一份给海外买家看的英文产品目录，选 sample-export-catalog；要每天发到业务群的汇率早盘（牌价板、走势、换算），选 sample-fx-daily；房贷、分期这类给客户自己拖的计算器，选 sample-mortgage-calc。

## 用户对助手说的原话

帮我做一个出口报价利润试算台，发成一个网页链接自己用：页头写我的公司、业务员、试算单号和日期，以及产品、客户代号、起运港、报价有效期；最上面是 EXW / FOB / CIF 三档外币报价并排，每档写每件赚多少、利润率，点一档就按这一档往下算；电脑上左边一栏是输入（采购成本含税、数量、出口退税率 13% / 9% / 不退、国内杂费、海运整柜或拼箱切换、目标利润率滑块、报价币种美元 / 欧元 / 英镑 / 日元），按目标利润率倒推报价并向上取整到分；右边最显眼的是「汇率跌到哪会亏」：一个结汇汇率滑块（今天的 −10% 到 +5%），拖动时这一单利润的大数字实时跳，下面一张图横轴是汇率、纵轴是这一单利润，标出亏损区、保本的安全线、今天和近 30 天的波动区间，图也能直接拖，再加一句汇率每变动 1% 利润变动多少；然后是一张三档并排的算例表（采购、退税、杂费、运费、保险、成本、报价、利润、安全线）；通栏放今天的四种汇率和近 30 天走势图，安全线在图上标出；最后一张「保存这一版报价」表单（客户代号、产品、贸易术语、报价、利润率，后三项按当前计算自动填），存进数据表，并在旁边列出最近存的 5 条。汇率用欧洲央行参考汇率（Frankfurter 免费接口）的真实数据：页里先放一份今天抓的快照，打开时再拉实时的，拉不到就显示快照时间。手机上一栏排：首屏只放三档报价和「汇率跌到哪会亏」的利润大数字、汇率滑块与下面的保本线图，成本、数量、退税等输入项排在它们后面，不要挤上首屏，图换一套适合窄屏的坐标。

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

## 照着做一份

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

## 页面结构

- 三档报价
- 汇率跌到哪会亏
- 成本和费用
- 每只怎么算的
- 今天的汇率
- 保存这一版报价

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

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

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

- 页面里现算：改成本、退税率、杂费、整柜 / 拼箱运费、利润率、币种，三档报价、利润、算例表同一帧重算；不跑脚本时显示按默认输入算好的一份
- 真实外部数据两层加载（页内快照先画，脚本在时拉欧洲央行参考汇率实时替换，标明来源与更新时间）
- 拖结汇汇率滑块或直接拖图，利润大数字与汇率安全线实时跳动
- 每轮报价经原生表单写进数据表 quotes（client / product / term / price / margin），页面读回最近 5 条
- 同一链接一直可用：换产品、运价变了就更新同一个页面

## 发之前要备好

- 数据表 quotes（列 client / product / term / price / margin，append_open=true）：文末「保存这一版报价」表单写进这里，发布前先用 set_data 建好；自用建议同时 members_only=true，页面设仅自己或口令可看
- 可选：每个工作日早上的定时任务，抓一次 Frankfurter 汇率刷新页里的快照（fx-snapshot）后发到同一个页面；不刷新时页面打开也会自己拉实时数据

## 模板说明（README）

模板市场「小工具 · 轻应用」的一份（总览见 `core/space/examples/README.md`，品质标准见 `core/space/examples/QUALITY.md`）。
业务员接到询价，先把采购成本、退税、杂费、海运费和想要的利润率填进去，立刻出 EXW / FOB / CIF 三档外币报价；再拖一下结汇汇率，看汇率跌到哪这一单就白干。谈价改过几轮，每轮存一版，下次打开还在。示例数据均为虚构；汇率是真实的。

## 演示哪个特色

**一个能算的页面 + 真实汇率两层加载 + 存下的报价写回数据表并读回。**

- **记忆点**是「汇率跌到哪会亏」那一块：拖「假如结汇时」滑块（−10% … +5%），或直接在图上拖，这一单利润的大数字、图上的利润线小圆点同一帧跳动；跌过琥珀色虚线的「安全线」，数字变成砖红色的「亏」。图的横轴是结汇汇率、纵轴是这一单利润，亏损区浅砖色、近 30 天的真实波动区间浅靛色，一眼看出离亏本还有多远。下面一句敏感度：汇率每变动 1%，这一单利润变动多少元、相当于利润的几成。
- 三档报价：按目标利润率倒推（利润 ÷ 报价 = 目标利润率），向上取整到分（日元到元）；点一档，安全线、算例表高亮、保存表单都切到这一档。
- 输入：采购成本（含 13% 增值税）、数量、退税率（13% / 9% / 不退）、国内杂费、海运（整柜：每柜运费 × 柜数；拼箱：单价 × 货量）、目标利润率滑块、报价币种（USD / EUR / GBP / JPY）。改任何一项立刻重算。
- 今天的汇率：四种币种兑人民币 + 近 30 天变化，和一张宽走势图（当前币种），安全线在图的范围里就画虚线，离得远就在图底写「比 30 天最低还低 x%」；指到哪天看哪天。
- 不跑脚本时：页面里写着按默认输入和快照汇率算好的一份（三档报价、大数字、两张图、整张算例表），表单照常能提交。
- 电脑上左栏输入（吸顶）、右栏结果，汇率走势与保存区通栏；手机上一栏，三档报价先出来，输入区顶上吸着当前这一档的报价和每只利润，图换一套 343 宽的坐标。
- 发出去之后：「保存这一版报价」是原生表单，写进数据表 `quotes`；页面读回最近 5 条（客户代号、产品、术语、报价、利润率）。

## 公式与验算

R = 1 单位外币折人民币（欧洲央行参考价，非美元币种用美元交叉换算），Q = 数量，m = 目标利润率。

- 退税后成本 N = 采购价 × (1 − 退税率 ÷ 1.13)；杂费分摊 D = 杂费 ÷ Q；海运分摊 F = 运费（USD）× 今天美元汇率 ÷ Q。
- 成本：EXW = N；FOB = N + D；CIF = N + D + F，另加保险 = CIF 报价 × 110% × 0.3%。
- 报价 P = 成本 ÷ ((1 − m − 保险率) × R)，向上取整到分；每只利润 = P × R × (1 − 保险率) − 成本。
- 安全线（保本汇率）= 成本 ÷ (P × (1 − 保险率))；汇率每变动 1% 的利润变动 = Q × P × R × (1 − 保险率) × 1%。

默认这一版（采购 28.60 元 / 只、12,000 只、退税 13%、杂费 3,600 元、1 × 40GP 1,980 美元、利润率 8%、美元，快照 1 USD = 6.6616）：
退税 3.29、FOB 成本 25.61 → FOB 4.18 美元，每只赚 2.24 元，这一单 26,829 元；安全线 6.1267（离今天 8.0%）；汇率每变 1% 利润变 3,341 元。
EXW 4.13 / CIF 4.38 美元。

## 改哪里变成我的

| 位置 | 改什么 |
|---|---|
| 页头 `.org` / `h1` / `.facts` | 你的公司、业务员、试算单号和日期；产品、客户代号、起运港、报价有效期 |
| 左栏 `#calc` 各 `input` 的 `value` | 默认采购价、数量、退税率（`checked`）、杂费、整柜 / 拼箱运费、利润率、币种 —— 页面打开就按这些算 |
| 脚本 `TNAME` / `TDESC` | 三档的名字和说明（起运港、目的港） |
| 脚本 `INS` | 保险加成和费率（默认 110% × 0.3%） |
| 脚本 `LO` / `HI` | 滑块范围（千分点，默认 −10% … +5%） |
| 「保存这一版报价」 | 默认客户代号、产品；`client` / `product` / `term` / `price` / `margin` 五个字段名就是表里的列名 |
| 页脚 | 平台标志与名称（与 `core/space/src/theme.ts` 的 `MARK_SVG` / `PUBLIC_NAME` 逐字一致，测试咬着）+ 一句适用场景；发自己的页面时整段删掉 |
| `manifest.json` | `title` / `share.title` / `share.desc`（微信卡片上的字） |

改了默认输入之后，不跑脚本时看到的那一份（页面里 `<!--b:名字-->` 与 `<!--/b:名字-->` 之间的内容，以及带 `data-bakev` 的两个输入框）要重新生成：用浏览器打开页面（断网，让它按快照算），把每个 `data-bake` 元素的 `innerHTML` 写回标记之间。只给会跑脚本的人看可以不管，脚本一跑就覆盖。

## 汇率数据（两层加载）

- 数据源：欧洲央行参考汇率，经 Frankfurter 免费接口（`https://api.frankfurter.dev/v1/<30 天前>..?base=USD&symbols=CNY,EUR,GBP,JPY`），页面上署名并显示更新时间。
- 第一层：页里的 `<script type="application/json" id="fx-snapshot">`，格式 `{"source": "…", "fetched_at": "<ISO 时间，带 +08:00>", "rates": {"YYYY-MM-DD": {"CNY": 6.6616, "EUR": 0.89847, "GBP": 0.75093, "JPY": 158.06}, …}}`（以美元为基准，约 30 天、只有工作日）。首屏按它算，底部写「数据更新于 <抓取时间>（页面快照）」。
- 第二层：脚本在时拉同一个接口（3 秒超时），拿到就替换并重算，写「实时，更新于 HH:MM」；拿不到就保留快照。
- 想每天刷新快照：定时任务每个工作日早上抓一次上面的接口，把结果写进 `fx-snapshot` 再发到同一个页面（不刷新也行，读者打开时会自己拉实时数据）。
- 欧洲央行参考价不是银行结汇价，页面上写了「留点余量」。

## 数据表

文末表单写进数据表 `quotes`（一次一行，`append_open=true`）。这是自用工具，建议同时 `members_only=true`（只有工作区成员能存，访客看不到表单提交入口也存不进来），页面可见范围设成仅自己 / 口令：

```
set_data  proposal_id: <id>  table: "quotes"  columns: ["client","product","term","price","margin"]  rows: []  append_open: true  members_only: true  revision: 0
```

页面读回 `./_data/quotes.json` 里最近 5 条（按 `_at` 倒序）；你也可以用 `list_data_rows table=quotes` 在助手那边读全部。
本地 `space-cli serve` 会把提交写进包里的 `_data/quotes.json`，试完改回 `[]`。

## 怎么发出去

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

```
publish_file
  filename: "index.html"
  content: <index.html 全文>
  title: "出口报价利润试算台"
  manifest: <manifest.json 的内容，去掉 entry>
  hold: true            # 先看预览，确认后 publish_version
```

然后按上面建 `quotes` 表。有终端时用 CLI：

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

给谁看：默认仅自己可见，自用就保持这样；要给老板或同事看，用 `set_visibility` 设口令。产品换了、运价变了就更新同一个页面，收藏的链接不变。

## 素材

- 没有位图；公司标志是内联 SVG 几何图形（帆）。公司、业务员、客户代号、产品、成本和运价均为虚构。
- 汇率是真实数据（欧洲央行参考汇率，经 Frankfurter）；成本口径、退税率、保险费率是常见做法的示例，以你自己的报关和货代报价为准。
- `thumb.webp` / `phone.webp`：画廊缩略图，由 `examples/verify-shots.mjs --write-thumb --write-phone` 从成品截出，不进发布包。
