自驾路书 → PDF / 微信小程序 / 手机网页
> SkillHub 市场版说明:本技能在市场分发时包含 PDF + 手机网页 + 真实数据管线(高德/Open-Meteo)三条完整能力;微信小程序形态依赖配套的 mp-shell 小程序壳,按平台规则不随技能包上传,需要小程序的用户请单独获取「完整包」。
把「我要从 A 到 B,X 号到 Y 号」变成按需交付的成品路书:
A4 可打印的 PDF(离线地图)、能在微信里导航/打电话/看天气的小程序、扫码即开的单文件手机网页。
三种形态共用同一份行程数据,创建时先问清要哪几样。
核心原则
- 一次性把信息问清,不要挤牙膏。 第一次回复就把所有缺口列成一张表问完。
- 能补就补,补不了才问。 有明确行业默认值的(如自驾日均行车上限、房型、餐饮预算区间)直接补齐,并在交付时说明"这几处是我按默认值补的,可以改"。
- 所有数字必须来自真实接口。 里程走高德驾车实算,店家走高德 POI 实抓,天气走高德 + Open-Meteo。禁止凭印象写"约 300km""人均 80 元"。
- 不确定的就标出来。 门票价、营业时间写"以现场为准 / 出发前电话确认"。
- 不要写内部订房信息。 人数、房间数这类字样不要出现在路书里 —— 路书会被转发。
输入清单
必填(缺了就必须问,不许硬编)
| 项 | 说明 |
|---|---|
| 出发地 | 精确到区/车站,用于算第一段里程 |
| 目的地 | 可以是一个区域("乌兰布统")或几个点("想去赤峰、克旗、阿尔山") |
| 起止日期 | 决定天数、天气取哪几天、是否撞假期高峰 |
| 交付形态(多选) | ① PDF(A4 可打印,含手绘路线图)② 微信小程序(可导航/打电话/看天气)③ 手机网页(单文件 HTML,扫码即看)。必须问,不要默认只出一样。 |
| 人数 | 只用于内部计算(房间数、包车/包桌分量),不写进路书文案 |
强烈建议(没有就按默认值补齐,并说明)
| 项 | 默认值 |
|---|---|
| 交通方式 | 自驾(本 skill 专做自驾;非自驾先确认) |
| 节奏 | 每日纯行车 ≤ 5 小时、至少 1 个主景点 |
| 住宿偏好 | 景区内/近景点优先,参考价中档 |
| 兴趣标签 | 无则默认"风景 + 摄影 + 本地吃" |
可选(问一句即可,不问也能做)
车型/底盘高度、是否带老人小孩、餐饮忌口、预算上限、是否要绕路多去一个点。
补齐规则
- 日期跨度 N 天 → N-1 晚;去程日与返程日各按"纯行车 ≤ 8 小时"排,超出就中间加住宿点。
- 不知道住哪 → 选当天最后一个景点 30km 内的县城/镇区,酒店给 2 个(主选 + 备选)。
- 不知道吃什么 → 按地区做"必吃三样",每区 5 家真实店家(评分 ≥4.0、有电话优先)。
- 目的地只给了区域没给具体点 → 用高德 POI 搜该区域 4A 以上景区 + 高分观景点,自行组线。
工作流
Phase 0 · 信息确认
把缺口整理成一张表一次性问完。表里要区分「必填(缺了没法开工)」和「我能补(默认值是 X)」。
用户答完缺失项即可开工,不要反复确认。
「交付形态」这一项必须问,且用多选的方式问(PDF / 微信小程序 / 手机网页,可多选)。
三者的下游产物不同,中途再补会重复走数据管线,第一次就问清楚。
用 AskUserQuestion 的 multiSelect: true 问,别在正文里列一堆选项让他打字回。
| 形态 | 适合什么时候要 |
|---|---|
| 要打印出来路上翻、发给不会用小程序的人、离线看(地图不联网也能显示) | |
| 微信小程序 | 要一键导航、打电话、看实时天气、能转发出去 |
| 手机网页 | 只想发个链接/二维码让对方点开就见内容,不上架小程序 |
不要默认只出一样,也不要自己替他决定——但可以给一句建议("要发给同行的人,小程序 + PDF 最稳")。
示例触发:"10月3号从沈阳出发去乌兰布统,7号回来,6个人,给份自驾攻略"
Phase 1 · 行程骨架(先出文字版给用户过)
- 按天切分,每天:日期 / 主路线 / 纯行车时长 / 1-2 个主景点 / 住宿点。
- 先算时间账:导航给的时长偏乐观,自行加 20% 余量;标出"最紧的一天"和"必须几点前出发"。
- 定下去程/返程走廊(尽量不走回头路),并把每天的点位串成链。
- 把骨架发给用户确认 —— 这一步改起来最便宜,别跳。
Phase 2 · 抓真实数据
在工作目录放两个数据文件(从 scripts/templates/ 复制改名):
trip_data.py(客观行程)和 trip_guide.py(经验判断)。然后依次跑:
export AMAP_KEY=你的高德Web服务Key # 可选,不设则用内置兜底 Key
python scripts/fetch_routes.py # 真实 GPS 轨迹 + 每段里程时长 -> routes.json
python scripts/fetch_segs.py # 逐段 A→B 里程(比总览更细,每段可导航)-> routes_segs.json
python scripts/fetch_foods.py # 沿线真实餐饮店家 -> foods.json
python scripts/fetch_weather.py # 16 天天气快照 -> weather_snapshot.json
每个脚本只改顶部配置块(坐标表 / 点位链 / 查询词 / 天气取点),下面的逻辑不要动。
跑完检查产物非空:fetch_segs.py 会打印每段里程,fetch_foods.py 会打印每区保留家数。
Phase 3 · 攻略层
在 trip_guide.py 里写:按地区必吃三样、气象、穿衣、自驾、交通时间账。
这类内容要具体到可执行("县城餐厅 19:30 后只剩炒菜"),不要写"注意保暖"这种废话。
Phase 4 · 生成交付物(只做 Phase 0 里选中的那几样)
三个脚本读同一份 trip_data.py,所以数据只做一遍,形态随便组合。
全部脚本都从工作目录(python scripts/xxx.py 的当前目录)读写,产物也落在工作目录;
可用 TRIP_DIR=/path 覆盖。images/ 的图片三个形态共用。
依赖:pip install pillow reportlab(PDF 版要 reportlab;图片压缩要 pillow)。
4A · PDF(A4 可打印)
python scripts/build_pdf.py # -> <META.title>.pdf
- 地图是本地用真实 GPS 折线画的(按天着色 + 标记点),不依赖任何在线地图服务,打印不糊。
- 封面/页脚/文档标题全部取自
META(title/head/head_sub/dates/cover_note),
不要在脚本里硬编码行程名。 - 图片走源文件(
img_path()),不内嵌 base64,所以体积可控但有图才跑得动。
4B · 手机网页(单文件 HTML,扫码即看)
python scripts/build_mobile.py # -> <META.title>-手机版.html
- 单文件、内嵌 base64 图片,丢到任何静态托管/发微信都能直接打开。
- 用的是 Leaflet + 高德瓦片,在线才能看地图;离线场景只能靠 PDF。
- 没有
wx.*接口,所以「一键导航」退化成唤起地图 App 的 URL scheme,功能弱于小程序。
4C · 微信小程序
cp -r assets/mp-shell ./mp # 小程序壳
python scripts/build_mp_data.py # MP_DIR=./mp -> mp/utils/roadbook-data.js
python scripts/make_logo.py # 512×512 头像 -> 小程序头像.png
build_mp_data.py会打印自检行:navSegs : N 段, 未解析坐标: []—— 这个列表必须为空,
非空说明有地名没匹配到坐标(去ALIAS/ADDR补)。- 地名 → 坐标解析有个坑:
nav_of()里必须先按「A→B 取终点」解析,再退化成整串模糊匹配,
顺序反了会把"欧式风光区→影视基地"误匹配成起点。 - 壳里的
images/是空的,build_mp_data.py会把压缩后的图写进去;主包上限 2MB。 - 生成前必读
references/wechat-constraints.md。
出片前自检(选了哪样就查哪样)
| 形态 | 检查项 |
|---|---|
能打开;地图不是空白(空白 = routes.json 没跑 / DAYS 的 routes key 对不上);封面没有人数字样 |
|
| 手机网页 | 在产物里搜 __ 搜不到残留占位符;标题/chips 是本次行程 |
| 小程序 | build_mp_data.py 的「未解析坐标」为空;主包 < 2MB;images/ 有图 |
Phase 5 · 交付
按形态交付,别一股脑全塞给用户:
| 形态 | 给什么 | 结尾要说的 |
|---|---|---|
<title>.pdf |
可直接打印;地图是离线的,不联网也能看 | |
| 手机网页 | <title>-手机版.html |
发微信/丢静态托管都能开;要联网才有地图 |
| 小程序 | .genie 卡片 + 小程序头像.png |
附「如何预览和发布」;① 哪些是默认值补的 ② 天气域名要配 https://restapi.amap.com(不需要他自己有域名)③ 体验版更新要清掉本地小程序记录再扫 |
通用规则:
- 小程序只给
.genie卡片,不调workbuddy_sites_deploy,不写「应用空间」。 - 明确告诉用户哪几处是「按默认值补的,可以改」。
- 三种形态的数据必须一致(同源
trip_data.py);改内容就重跑脚本,不要手改产物。
必读的硬限制
微信侧的平台限制(导航只能走 openLocation、携程直达只能用 shortLink、公众号跳第三方不可能、
体验版没有版本号、头像只能后台改、主包 2MB、预览环境缺 wx.* 接口)全部记在:
references/wechat-constraints.md—— 生成小程序前必读references/data-sources.md—— 高德 / Open-Meteo 接口用法、坑、WMO 天气码对照
两条最容易翻车的:
1. 高德预报只有 4 天。 行程日在第 5 天以后,配好域名也照样空白 —— 必须用 Open-Meteo(16 天)并内置快照兜底。
2. 预览环境没有 wx.* 接口。 所有调用走 utils/wx-safe.js 封装,裸调会让页面白屏。
目录约定
工作目录/
├── trip_data.py 行程主数据(三种形态共用,改这里)
├── trip_guide.py 攻略层
├── routes.json GPS 轨迹
├── routes_segs.json 逐段里程
├── foods.json 店家
├── weather_snapshot.json 天气快照
├── images/ 实景照片
├── <title>.pdf [4A] PDF 版
├── <title>-手机版.html [4B] 手机网页版
├── 小程序头像.png [4C] 头像
└── mp/ [4C] 小程序壳(assets/mp-shell 复制而来)
脚本都在 skill 的 scripts/ 下,从工作目录里执行(python scripts/xxx.py),
产物落在工作目录;不在工作目录跑就用 TRIP_DIR=/abs/path 指过去。