一群人从不同城市去同一个地方(婚礼、聚会、团建……):有人开车,有人坐高铁。这个工具用高德的真实行车时间先给出一个大方向,让大家心里有个底;具体在哪接、几点到,还是同行的人之间再商量。它回答:
- 不开车的人坐到哪个高铁站最合适(不一定是离目的地最近的那个);
- 哪位车主顺路接谁、在哪接、几点出发,绕路不超过各自的上限;
- 搭不上车的人在哪个站汇合打车,到站时间相近的拼一辆,尽量省钱;
- 可选:散场后怎么回去(返程:车主顺路送人去车站或回家),每个人可以有自己的离场时间。去程和返程是两个独立的开关,可以只规划返程。
结果包括:
- 推荐方案和备选方案;
- 每辆车的路线地图:灰色虚线是不接人时的直达路线,和实际路线对比,就能看出绕了哪段;
- 一页可以直接发给大家的方案页:每人一张时间线卡片,带高德导航链接;开了返程的话,另有返程一节。
线上版:https://carpool.eigentime.org ,首页有效果图、示例方案页(/demo)、适合哪些场合和常见问题,不用注册。也可以在本机运行,或者自己部署一份。
-
目的地:搜索并选中,坐标最准。
-
成员:谁开车、空几个座、最多愿意绕多久;每个人的出发地。几个人一起走(比如带家属)的,填「同行人数」,这组人会一起上同一辆车,或者一起打车,不会被拆开。选好或算过的地点会马上显示在地图上,坐标存进配置,下次不再查。
-
候选车站:点「推荐车站」,抽屉顶部是「找站设置」,默认在三个范围里找火车站,都可以改,改完先显示要搜索多少次:
- 目的地周边(默认 90 公里);
- 各车主出发地附近(默认 30 公里);
- 各车主的路上:默认沿路线每隔 30 公里取一个点,也可以改成「绕路上限内全覆盖」,更全但搜索次数更多;
- 还可以加上乘客出发地附近,给坐高铁的人找离家近的站。
不在 12306 站名表里的站(多半是货运站)、建设中或暂停营业的站、已在候选里的站会被去掉,但会列在「没列出的站」里写明原因,可以手动加入。结果默认按「车主最少绕路」排序,每位车主各绕多少、超过绕路上限的都标出来,地图上画出搜索过程,勾选加入即可。设置存在行程的
[options.suggest]里,各项含义和默认值见「推荐车站怎么找」。 -
车次:不开车的人在每个站后面点「查」,打开已填好出发城市、到达站和日期的 12306 页面,查到后填入车次和时刻(如
G1234 08:00→11:30)。程序会自动算用时,并倒推车主几点出发。 -
规划哪几段、返程(可选):表单顶部的「规划哪几段」有去程、返程两个开关,至少选一段,可以只规划返程(要填返程日期,用不到去程的车次和出发时间)。开了返程,填散场时间;不开车的人填回程车次(同样有 12306 查询链接),程序按「发车前多久到站」(默认 40 分钟)倒推;车主可以选返程是否顺路送人、最多绕多久。每个人可以填自己的离场时间(不填就是散场时间):车主几点走,车就几点走,乘客准备好后最多等车主 30 分钟(默认,可以改)。
-
计算方案:先让尽量多的人搭上顺风车,每位车主的绕路不超过上限;再比总分钟数(车主绕路 + 乘客坐车 + 打车组车程)。没搭上车的人另外打车:到站(返程是离场)时间相近的拼一辆,默认尽量拼车省钱,「选项」里可以改成各人走自己最快的站。去程和返程分别出方案,可以分别选,方案页按你选的组合生成。规则、默认值和版本号见「方案是怎么算出来的」,每个方案下面也列出了总分钟的构成。
-
发布方案页:每个行程一个方案页链接,重新发布会更新同一个链接。
- 试玩:没有邀请码、也没有高德 Key 的人可以打开
/try。里面是虚构的行程(宏村示例酒店,老王、老张开车,小李、小陈坐高铁,开返程),数据在web/try-trip.json;能改谁开车、空座、最多绕路、同行人数、车次和分钟数,能删成员和候选站,能开关去程和返程(可以只规划返程)、改乘客的离场时间、切换打车方式,「恢复示例」回到初始。不能搜索和改地点、加成员和车站、保存、发布方案页。行车时间在浏览器里按直线距离估算(直线公里数 × 1.3 ÷ 75 km/h,再加 10 分钟),路线画成直线,报告里写明是示意;全程不调用高德 Web 服务,也没有/api/t/请求(地图底图仍是高德瓦片)。构建时把编辑页复制成dist/try.html,页面按路径/try切到试玩模式。 - 新建行程:首页填行程名称,然后二选一:
- 有邀请码(站长发的,也可以直接打开邀请链接
/?invite=<邀请码>),用站点的公共高德额度; - 填自己的高德 Web 服务 Key。Key 只保存在服务端,不会回传到网页,调用次数算在你自己的额度里。
- 有邀请码(站长发的,也可以直接打开邀请链接
- 编辑链接即权限:形如
/t/<行程>#k=<密钥>,发给一起规划的人就能多人同时编辑。链接外传了,可以在「更多」里重置,旧链接和已经打开的页面立即失效。 - 编辑口令(可选,默认关):在「更多」里设置。设了以后,新设备打开编辑链接要先输入口令,已经在线的其他人会被请出、要重新输入;每个行程每小时最多试 10 次。清除后只凭编辑链接就能打开。
- 方案页:链接形如
/p/<方案页 id>,和行程 id 无关,只能看不能改。v3 之前发布过的行程沿用原来的/p/<行程 id>,重新发布还是更新这个链接;想分开可以在「更多」里换链接。- 车主的路线从出发地约 2 公里外开始画,「到家附近接」的地点不标位置,导航链接不带出发地。
- 可以设访问口令(每个方案页每小时最多试 20 次)、换一个链接(旧链接失效)或停止分享。
- 页面上有「打印 / 存为 PDF」按钮,打印时隐藏按钮、地图固定高度、卡片不跨页,黑白打印也能看清。
- 多人实时编辑:
- 改动停顿约 0.8 秒后自动保存;
- 顶部显示谁在线,正在被别人编辑的格子会标出名字;
- 两人改了不同的地方会自动合并;改了同一格时,保留后保存的一方,并给他弹出提示「对方改成了什么」,可以一键改用对方的;
- 断线期间的改动,恢复后补存。
- 历史版本:同一个人 2 分钟内的连续修改合并成一条,每个行程保留最近 100 条。可以查看和现在的差别、一键恢复;恢复本身也会生成新版本,还能再撤回。
- 调用上限:
- 用公共额度的行程:每个行程每天最多 1500 次(邀请码可以单独设),全站每天最多 4000 次高德调用。全站用过八成后,当天还没用过公共额度的行程暂停分配,留给已经在算的行程。
- 自带 Key 的行程每天最多 3000 次,只防程序出错时无限调用。
- 站点公共额度按高德的两个类别(路线测距类、搜索类)分别记今天和本月的用量,到月预算就停下提示。月预算默认路线测距类 140000 次、搜索类 4500 次,比高德的免费额度留了余量,可以用可选变量
OWNER_MONTHLY_LBS_BUDGET、OWNER_MONTHLY_SEARCH_BUDGET调整。高德没有查询剩余额度的接口,只能自己计数;条款或额度变了,改配置即可。 - 高德返回配额用完时,按 Key 和接口类别(搜索类、路线测距类)分开记住,北京时间次日零点前这一类不再调用。高德个人开发者的搜索配额比路线类少得多,搜索用完了不影响算行车时间。
- 到上限都是停下提示,不会继续调用;提示里可以直接改用自己的 Key。
- 数据保留期:出行日期过后 60 天、连续 180 天没人编辑,两者取较晚的,到期自动删除行程和方案页;删除前 7 天编辑页会提示。「更多」里可以随时手动删除。
- 其他:
- 配置可以导出、导入(JSON);
- 公开额度状态:
GET /api/status只返回粗粒度信息(ok、tight、out、paused四档、已用百分比、能否新建),节点缓存 60 秒;首页据此显示「今天站点公共额度:已用 23%」,紧张时提示可以改用自己的 Key,接口不可用时整块隐藏; - 同一 IP 每天最多新建 10 个行程,全站每天最多 200 个;
- 存了什么、给了哪些第三方、哪里可能花钱,见站内的费用与隐私页。
站长在 /admin 用站长口令登录。站长口令只用于管理页,不能在首页当邀请码用;登录后发的是随机会话令牌(24 小时过期),不是口令本身。可以:
- 看今天和本月的公共额度用量(按两个类别分开)、近 30 天每天的用量、今天新建的行程数;
- 用公共额度新建行程:直接给出编辑链接,不需要邀请码;
- 发邀请码:备注、最多建几个行程、有效期、每个行程每天的高德上限;
- 看每个邀请码建了几个行程、今天用了多少;停用或重新启用。邀请码停用后,用它建的行程不能再用公共额度,要改用自己的 Key,已有数据不受影响;
- 应急开关(置顶,操作要二次确认,最近 50 条操作有记录):暂停公共额度(用公共额度的行程立刻停止计算并提示改用自己的 Key,自带 Key 的不受影响)、暂停新建行程、一键停用所有邀请码、退出所有管理会话、对单个行程停用公共额度。「最近用公共额度的行程」只显示行程 id、新建时间、所用邀请码和今天用量,不显示行程内容。
站长口令可能泄露了,按顺序处理(管理页里也有同样的手册):
- 在管理页点「退出所有管理会话」,再暂停新建行程,需要的话也暂停公共额度;
- 在本机运行
npx wrangler secret put ACCESS_CODE换口令,旧口令立刻失效; - 检查邀请码和最近用过公共额度的行程,可疑的邀请码停用、可疑的行程停用公共额度,也看一下「最近操作」里有没有不是你做的;
- 确认没问题后,把暂停的开关恢复。
登录失败有次数限制(同一网络 15 分钟 5 次、全站每小时 30 次)。
登不进管理页时(比如有人故意试错,把全站登录锁了一小时),可以用环境变量直接暂停,不需要登录:
npx wrangler secret put FORCE_PUBLIC_PAUSED # 值填 1:暂停公共额度
npx wrangler secret put FORCE_CREATION_PAUSED # 值填 1:暂停新建行程
npx wrangler secret delete FORCE_PUBLIC_PAUSED # 恢复(另一个同理)管理页会标出哪些开关是被环境变量强制打开的。
需要 Python 3.11+,只用标准库。高德 Key 放在环境变量 AMAP_KEY 里,或者存进同目录的 .amap_key(已加入 .gitignore)。
python3 ui.py # 编辑 trip.toml,打开 http://127.0.0.1:8765
python3 carpool.py trip.toml # 只用命令行:报告打印到终端,并写到 trip-report.md返程在 TOML 里加一节 [return](enabled、depart_time、security_min、max_wait_min、date),成员的回程车次写在 return_trains,离场时间写 leave_time,同行人数写 party;只规划返程时在 [options] 里写 outbound = false,并填 [return] 的 date。打车怎么安排是 [options] 里的 taxi_mode、taxi_pool_extra_min、taxi_wait_min。都见 trip.example.toml。
本地版是单人使用:没有多人同步和历史版本,需要手动保存。保存时会把配置写回 TOML,手写注释不会保留;第一次保存前,原文件会备份为 trip.toml.bak。字段说明见 trip.example.toml。
浏览器:界面 + Pyodide(浏览器里运行的 Python,跑 carpool.py 等,计算都在这里;Pyodide、地图组件随站点自己托管在 /vendor/)
│ 编辑链接换来的 Cookie(只对该行程的路径有效);WebSocket 实时同步
▼
Worker(web/worker.js,用 placement.region 固定在香港附近运行,离高德近)
├─ 新建行程:校验邀请码或自带 Key,限制新建频率
├─ ConfigRoom(Durable Object,每个行程一个):配置、版本号、历史、当天用量、在线名单、
│ 方案页设置、到期删除的定时任务
├─ Usage(Durable Object):全站新建次数、站长 Key 当天用量、邀请码、按天汇总的访问统计
├─ 高德代理:只放行用到的接口;先查 Cloudflare 节点缓存,再按每秒 3 个批量请求
├─ 管理页接口:/api/admin/*,站长口令登录,之后凭会话令牌
└─ KV:方案页(带访问口令和过期时间)、按 Key 和接口类别记的配额标记
计算内核按职责分成几个模块,都在仓库根目录:
| 模块 | 内容 |
|---|---|
base.py |
常量、配置项定义(FIELDS、DEFAULTS)、规则版本号、进度回调 |
geo.py |
地点、高德客户端 Amap、高德接口 AmapLike、找站时的 POI 过滤 |
model.py |
行程模型和读配置、行车时间矩阵 |
routes.py、taxi.py、solver.py |
车主路线和乘客分配、打车安排、求解 |
timetable.py |
行程表 |
reporting.py |
报告 |
tomlio.py |
TOML 写出 |
carpool.py 是门面兼命令行:原来的 carpool.X 都还能用,给 carpool.progress 这类变量赋值,会转到真正定义它的模块。网页版加载哪些 Python 文件只写在 web/py-manifest.json 一处。
高德接口:计算只通过 geo.AmapLike 规定的那几个方法调用高德,文档字符串里列了每个方法对应的高德 Web 服务接口和额度类别。现在有四个实现:
geo.Amap:本地,直连高德;browser.BrowserAmap:网页版,经 Worker 代理;browser.TryAmap:试玩,不联网;- 测试里的
FakeAmap。
要改成浏览器直接调用、改用 JS API,或者换数据源(天地图、腾讯),只需新写一个满足 AmapLike 的实现,求解、行程表、报告、方案页都不用动。测试会检查各个实现都满足接口,也会检查计算里用到的方法都在接口里。
计算内核以「一段行程」(leg)为单位求解:去程是车主从家出发接人去目的地,返程是从目的地出发送人。两段互不影响,可以只算其中一段。座位按同行人数算,一组人不拆开。没搭上车的人怎么打车由 TaxiPool 安排,结果按「哪些人没搭上车」缓存。方案页由 share.py 生成。编辑器是 ui.html(本地版、在线版、试玩共用),页面只有结构和样式,脚本是 web/editor/ 下的 ES 模块:入口 main.js 判断是哪种模式;backend.js 是三种模式的后端实现,接口相同,并按模式生成一张能力表(caps:能不能保存、能不能实际搜索、有没有历史、能不能实时同步……)。其他模块只看能力表,不判断模式,测试会检查这一点。模块之间单向依赖,没有环,也由测试守着。求解之后,每个方案里「谁几点出发、几点到哪、等多久、打车几点汇合」只在行程表(carpool.timelines)里算一次,报告、方案页和界面数据都只读它,不再各自推算。tests/golden/ 里的金标准测试逐字节固定这三样输出:有意改了输出,用 GOLDEN_UPDATE=1 python3 -m unittest test_carpool.GoldenTest 重新生成,再看一遍 git diff。
需要 Node.js、Cloudflare 账号,以及一个高德 Web 服务 Key。免费套餐就够用,超出免费额度只会报错,不会扣费。
npm install
npx wrangler login
npx wrangler kv namespace create DATA # 把输出的 id 填进 wrangler.jsonc
npx wrangler secret put AMAP_KEY # 站长的高德 Web 服务 Key
npx wrangler secret put ACCESS_CODE # 站长口令:只用来登录管理页 /admin
npm run deploy # 构建 dist/ 并部署构建时(web/vendor.mjs)会下载编辑页用的 Pyodide、Leaflet、marked(约 13 MB),逐个校验 sha256,缓存在 .cache/vendor/,拷到 dist/vendor/;第一次构建要能访问 jsDelivr 和 cdnjs,下载失败或校验不对会让构建报错,不会回退到 CDN。网络要走代理的话,设好 HTTPS_PROXY(下载用 curl)。许可证文件随依赖一起放在 dist/vendor/ 下。
可选设置:
- 在
wrangler.jsonc的vars里设TRIP_DAILY_LIMIT、OWN_TRIP_DAILY_LIMIT、OWNER_DAILY_LIMIT,调整每日上限;设OWNER_MONTHLY_LBS_BUDGET、OWNER_MONTHLY_SEARCH_BUDGET,调整站点公共额度的月预算(默认 140000 和 4500); - 在
routes里绑定自己的域名。workers.dev域名在国内不翻墙常常打不开。 wrangler.jsonc的assets.run_worker_first里的页面路径(/、/demo、/try、/guide、/for/*等)让 Worker 先处理再转给静态文件,用来统计页面访问;not_found_handling: "404-page"让不存在的地址返回404.html。这两处和web/worker.js配套,不要删。- 站点地址和搜索引擎收录(构建时读环境变量,在
npm run build/npm run deploy前设好):SITE_ORIGIN:站点的完整地址,如https://carpool.example.com(不带路径)。用在页面的 canonical、Open Graph、结构化数据、sitemap.xml、robots.txt和llms*.txt里。不设就是官方站https://carpool.eigentime.org。SITE_INDEXABLE:设成1才允许搜索引擎收录。换了域名又没设它的话,默认不收录:所有页面加<meta name="robots" content="noindex">,robots.txt只有Disallow: /,不生成sitemap.xml、llms.txt、llms-full.txt。这样自部署的副本不会和官方站抢搜索结果;想让自己的站被收录再设SITE_INDEXABLE=1。- 例:
SITE_ORIGIN=https://carpool.example.com SITE_INDEXABLE=1 npm run deploy。 - 自部署的站点请用你自己的名字、域名和标识,不要冒充官方服务:「拼车出行规划」、Eigentime 的名称和标识不授权给分叉使用,见
LICENSING.md第 5 节。别忘了改wrangler.jsonc里routes的域名。
- 不设
AMAP_KEY和ACCESS_CODE的话,就只能自带 Key 新建行程。 - 高德 Key 的使用条款和配额以高德开放平台为准。按 2025 年 5 月起的定价,个人认证开发者「非商业目的」的免费月配额是:路线、测距、地理编码等基础服务 15 万次,关键字、周边等搜索服务 5000 次,只有认证后的第一年;用于商业目的要另外购买许可。部署前请自己确认你的用途符合条款。
本地调试:在 .dev.vars 里写上 AMAP_KEY=... 和 ACCESS_CODE=...,然后运行 npm run dev。12306 站名表 web/stations12306.json 由 web/gen_stations12306.py 生成,需要时重新生成。
版本发布在 GitHub Releases,更新内容看仓库的 CHANGELOG.md;从 v3.2.0 开始按版本号发布。
- 关注新版本:在 GitHub 仓库页点 Watch → Custom → 勾上 Releases,有新版本会通知你。
- 拉取上游的更新:
- 你是 fork 的:在你的 fork 页面点 Sync fork,再
git pull到本机; - 你是直接克隆的:
git pull(想固定在某个版本,用git checkout v3.2.0这样的标签)。
- 你是 fork 的:在你的 fork 页面点 Sync fork,再
- 看
CHANGELOG.md里标了「不兼容」的条目:它们说明了配置、环境变量或接口有哪些必须同步改动的地方(比如wrangler.jsonc里的assets设置)。你自己改过wrangler.jsonc(KV id、域名、vars)的话,合并时保留你的值,只补上新增的条目。 - 部署:
npm install && npm run deploy。Durable Object 的迁移由 wrangler 按wrangler.jsonc里的migrations自动执行,不用手动处理;已有的行程和方案页不受影响。 - 出问题要回滚:
npx wrangler rollback,回到上一个已部署的版本(要指定版本时先npx wrangler deployments list看版本号)。回滚只换代码,不会改动已存的数据;如果新版本新增了 Durable Object 迁移,回滚后那一步迁移不会撤销。
首页带 Open Graph、Twitter 卡片和 JSON-LD(WebApplication 与 FAQPage)。robots.txt 允许首页、/demo、/privacy,禁止 /t/、/p/、/api/、/admin;另有 sitemap.xml 和 llms.txt(给 AI 问答读的简短说明)。/demo 是静态的示例方案页,行程是虚构的。编辑页和管理页带 noindex。这几个文件都在 web/ 下,换了域名要一起改。
- 构建时(
web/build.mjs)给每个页面生成内容安全策略(CSP):内嵌脚本按哈希放行,不允许unsafe-inline和unsafe-eval;编辑页的 Pyodide、Leaflet、marked 都是自己托管的同源文件,不放行任何 CDN;示例页和方案页仍用 cdnjs,带 SRI 完整性校验。 - 所有响应都带安全头(
nosniff、X-Frame-Options、Referrer-Policy、HSTS、Permissions-Policy):静态文件在web/_headers,Worker 生成的响应在web/worker.js,两处要保持一致。 - 方案页的 HTML 由编辑者的浏览器上传,所以放进 CSP 沙箱(独立的匿名来源):读不到本站的存储和 Cookie,也不能发请求。
- 改动状态的请求(
/api/*的 POST 和 DELETE、方案页口令表单)校验 Origin,跨站来源会被拒;WebSocket 也校验 Origin;500 错误不返回内部错误原文。 - 流量统计在服务端做,只记按天汇总的次数(页面访问、爬虫、外站来源的域名和
?from=参数、新建行程、发布和打开方案页的次数),不记 IP 和完整地址,不用 Cookie,保留 35 天;管理接口/api/admin/stats返回近 30 天。 - 行程实例(Durable Object)的内部接口只接受 Worker 自己发起的请求;客户端请求只有白名单里的路径(配置、同步、历史、恢复、改名)会转给行程实例。不是自带 Key 的行程一律经过公共额度的全部护栏。
- 限次:管理登录(检查和记录是一次原子操作)、编辑口令(最近一小时)、方案页口令(按来源和按页各有上限)、新建行程(按来源和全站);来源 IP 只存加盐、按天轮换的哈希。每个行程的保存、发布和实时连接也有频率或数量上限。
- 免费套餐的额度(Workers 请求、Durable Object、KV 写入)在代码里没法完全防住恶意刷量;用完时当天报错、不扣费(前提是 Workers Free 套餐)。需要的话在 Cloudflare 后台给站点加一条速率限制规则。
- Cloudflare 的 Web Analytics 开了自动注入时,会往页面里加统计脚本标签。CSP 不放行它,浏览器会直接拦下,不下载、不运行(构建时
web/build.mjs检查每个页面的script-src只放行本站、cdnjs 和内嵌脚本的哈希)。官方站因为同一域名下的博客在用,保持开启,隐私页写明了这一点。自己部署时不需要的话,在 Cloudflare 后台关掉即可。 - 发现安全问题请按
SECURITY.md私下报告,不要公开提 issue。
- 行车时间来自高德驾车测距,接近查询时的路况,每次查会浮动几分钟,当天也可能有出入。
- 不调用 12306 的非公开接口,车次需要手填。不填车次时,会用高德公共交通估算,但高德跨城只给直达火车、不含换乘,也查不到刚开通的线路,可能很不准。
- 推荐车站分不出高铁站和普速站,选的时候留意一下。高德没收录、或站名和 12306 站名表(2026-10-07 生成)对不上的站找不到,会列在「没列出的站」里;「沿路线取点」只保证路线两侧一定宽度内没有遗漏,要更全就切到「绕路上限内全覆盖」。
- 同一格两人同时改时,保留后保存的一方;先保存的一方的改动,可以在提示里一键改回,或者去「历史」里找回。
- 方案页存在 KV 里,重新发布后,其他地区可能要等约一分钟才看到新内容。
- 方案页模糊了车主出发地,但路线和车站仍然能看出大致区域,只发给相关的人;需要的话加访问口令。
- 返程只考虑车主从目的地送人去车站或顺路的家,不考虑在车站之间换乘;打车费用是按里程的粗估。
npm test # Worker、页面合并逻辑、编辑页静态检查、站点构建(node --test)和 Python(unittest),都离线运行编辑页的交互用端到端测试验证:
npm run e2e # 试玩、本地、在线三种模式的 18 个场景,约 2 分钟- 什么时候跑:改了编辑页(
ui.html、web/editor/)、ui.py或 Worker 接口以后,以及每次发布前。它要起本地服务和浏览器,所以不在npm test里。 - 前提:本机要有 Playwright 1.62.1 对应的 Chromium。没有的话先运行
npx playwright install chromium。 - 会不会碰到真的 Key:不会。测试自己起
wrangler dev和ui.py:用临时生成的假 Key 和测试口令,不读.dev.vars;本地存储放在临时目录,跑完按进程号停掉、删掉。浏览器里发往高德代理和站外的请求一律拦下,出现一次就算失败。 - 截图对比:
node web/e2e/shots.mjs <目录>生成 32 张固定状态的截图,用于重构前后逐像素比对。偶尔会有地图矢量图形边缘的抗锯齿差异,比如试玩、桌面、深色那几张,重跑一次即可。
管理页的交互仍在浏览器里手动验证:npm run build 后 npx wrangler dev。编辑页里所有确认、提示、输入都是页内弹窗(<dialog>)和轻提示,没有原生 alert / confirm / prompt;自动化脚本用稳定的选择器:确认 [data-dialog-ok]、取消 [data-dialog-cancel]、输入框 [data-dialog-input]、错误提示 [data-dialog-error]。
carpool.RULES_VERSION 是计算规则的版本号。所有配置项(默认值、范围、中文名)只在 config-fields.json 里定义一处,carpool.DEFAULTS 由它生成。只有排序规则或成本口径变了才加一,改界面、改文字不加。test_carpool.py 里的规则快照测试固定了几个场景的方案顺序和各项数字:快照失败说明排序或成本变了,如果是有意修改,更新期望值、把 RULES_VERSION 加一,并同步 web/pages/guide-method.html(默认值表会和 DEFAULTS 自动核对)和 CHANGELOG.md。
地图角标写着高德的审图号 GS(2025)5996号,在三处各写了一份:web/editor/map.js、share.py、web/demo.html 的 attribution(web/ui.test.mjs 会检查三处一样)。高德更新审图号时,三处都要改。
示例页是用虚构数据算一次方案、发布,再把生成的方案页改成站点页面:在编辑页导入虚构配置(宏村示例酒店,老王从杭州开车、老张从南京开车,小李同行 2 人从上海、小陈从武汉坐高铁,开返程)、计算方案、发布方案页,把得到的 HTML 存下来,运行 python3 web/make_demo.py 存下的文件.html 生成 web/demo.html。计算一次会消耗一次高德额度,方案页模板(share.py)改了才需要重新生成。
v2(多行程、并发、通用化)的计划和验收标准见 docs/v2-plan.md,v3(开源授权、隐私、邀请码、返程和同行人数)见 docs/v3-plan.md。
AGPL-3.0-or-later。授权说明、第三方组件与数据来源、贡献须知见 LICENSING.md。
这个项目是作者业余时间做的。觉得有用的话,可以在爱发电支持作者的开源工作,也可以看看作者的赞助页。支持完全自愿,不对应任何功能或权益;线上站点继续免费、没有付费功能,赞不赞助都不影响使用。
我的 AI 启蒙和学习,来自 LINUX DO 社区。