SSkilltecabyclaudinhocode
Enviar skill
← Voltar para o catálogo

travel-planner

Design e Frontend

Generate interactive, image-rich HTML travel itinerary pages with distance verification, real landmark photos, countdown timers, and mobile-first design. Trigger when user asks to plan a trip, create a travel itinerary, or make a trip page/website.

1estrelas
Ver no GitHub ↗Autor: allenwang-makerLicença: MIT

Travel Planner — 旅行行程页面生成器

将旅行计划转化为一个精美的、可分享的单文件 HTML 页面:图文并茂、交互丰富、移动端友好。

触发条件

  • 用户要求做旅行规划/行程页面
  • 用户说 /travel-planner 或 "做一个旅行页面"
  • 用户提供了旅行日期、目的地、住宿信息

核心原则

  1. Zero Dependencies — 单 HTML 文件,内联 CSS/JS,无需构建工具
  2. Distance-Verified — 所有步行/驾车时间必须通过路线 API 验证,不要凭感觉估算
  3. Real Images — 使用 Wikipedia API 获取真实景点照片,不用占位图
  4. Local Names First — 景点名用当地语言(方便导航认路),括号内加中文:La Pedrera (米拉之家)
  5. Mobile-First — 手机端是主要阅读场景,所有交互都要在触屏上流畅

Phase 1: 收集信息

用 AskUserQuestion 一次性问清关键信息:

Question 1 — 行程概览 (header: "行程"): 请提供你的旅行日期和目的地城市

Question 2 — 住宿信息 (header: "住宿"): 有住宿地址吗?(精确地址能优化每日动线)Options: 有地址 / 只有城市 / 还没订

Question 3 — 已确定行程 (header: "已定行程"): 有没有已经确定的景点/时间?(如预约了某个博物馆的时段)Options: 有 / 没有

Question 4 — 偏好 (header: "偏好"): 旅行风格?Options: 文化深度游 / 美食为主 / 休闲放松 / 暴走打卡

关键:从住宿地址反推动线

住宿地址是优化行程的锚点:

  • 用住宿坐标计算到各景点的步行距离
  • 按"从住处出发 → 沿一个方向推进 → 回住处"的逻辑设计每日动线
  • 避免"上午去城东,中午回城西吃饭,下午又去城东"的折返

Phase 2: 行程规划 + 距离验证

Step 2.1: 规划日程

按天组织行程,每天包含:

  • 上午/下午/晚间的时间轴
  • 景点描述(历史背景、亮点、实用信息)
  • 餐厅推荐(结合当天动线终点,不要在城东逛完推荐城西的餐厅)
  • 交通方式和预估时间
  • 需要提前预约的标注

Step 2.2: 距离验证(CRITICAL)

必须使用路线 API 验证所有步行/驾车段落。不要凭直觉估算距离。

优先使用 OpenRouteService MCP(如果已安装)。如果 MCP 未加载,直接 curl 调用 ORS API:

# Geocoding(注意:不带 /v2 前缀)
GET https://api.openrouteservice.org/geocode/search?api_key={KEY}&text={address}&size=1

# 步行路线
GET https://api.openrouteservice.org/v2/directions/foot-walking?api_key={KEY}&start={lon},{lat}&end={lon},{lat}

# 驾车路线
GET https://api.openrouteservice.org/v2/directions/driving-car?api_key={KEY}&start={lon},{lat}&end={lon},{lat}

标记所有超过 2.5km 的步行段落,建议替代交通方式(地铁/公交/打车)。

Step 2.3: 预约检查

整理所有景点的预约要求:

  • 🔴 必须提前预约(限时入场)
  • 🟡 强烈建议预约(热门日期会售罄)
  • 🟢 可以现场买票
  • ⚪ 免费/无需门票

Phase 3: 图片获取

使用 Wikipedia API 批量获取景点照片:

url = f"https://{lang}.wikipedia.org/w/api.php?action=query&titles={title}&prop=pageimages&format=json&pithumbsize=1200"
# headers: User-Agent required

策略:

  1. 先用英文 Wikipedia 搜索
  2. 找不到则用当地语言版本(it/es/de...)
  3. 所有图片容器必须设置 aspect-ratio + background 占位色,防止加载时布局偏移
  4. loading="lazy" 延迟加载
  5. onerror 处理函数优雅降级

图片准确性: 只用确认对应的 Wikipedia 词条图片。不要猜测 URL,不要用 Unsplash source(已废弃,返回 503)。


Phase 4: HTML 生成

生成前必读: design-system.mdpitfalls-and-fixes.md

分段写入策略

HTML 文件通常 1000+ 行,单次生成容易超时。必须分段写入:

  1. Part 1: <head> + CSS + Hero + Day 1-2(用 cat > 创建文件)
  2. Part 2-N: 剩余天数(用 cat >> 追加)
  3. Final: JavaScript(用 cat >> 追加)

页面结构

├── Hero(全屏封面 + 倒计时 + 城市概览)
├── Day Navigation(sticky 顶部导航)
├── Day 1-N Sections(每天一个 section)
│   ├── Day Header(日期 + 天气 + 标签)
│   ├── Hero Image(当天目的地大图)
│   ├── Timeline(时间轴组件,每个活动一个节点)
│   ├── Image Grid(景点照片 2-3 列)
│   ├── Restaurant Cards(可折叠的餐厅推荐)
│   ├── Insider Tips(实用贴士框)
│   └── Local Info(当地特色,可折叠)
├── Practical Info(签证/货币/插头/安全等)
├── Travel Phrases(当地语言常用语 + 发音)
└── Footer

倒计时逻辑

const target = new Date('YYYY-MM-DDT00:00:00+TZ');
// 如果已过出发日期 → 隐藏倒计时
if (diff <= 0) { wrap.classList.add('hidden'); return; }

日期导航 Tab

设计要点(来自实际踩坑):

  • 视觉要克制:无边框、透明背景、小字号。Active 状态用浅灰底 + 加粗,不要用填充色
  • 点击区域要足够大:padding: 8px 14px 最低限度
  • -webkit-tap-highlight-color: transparenttouch-action: manipulation(消除移动端 300ms 延迟)
  • scroll-margin-top 控制滚动对齐,不要手算 offset

Insider Tips 格式

每个景点提供"不一定要 XX,但一定要 YY"式的实用建议:

  • "不一定要进博物馆,但一定要爬上台阶看全景 — 免费"
  • "不一定要买票上岛,从沙洲上看和踩水就已经很棒了"
  • "不一定要进内部,但屋顶天台是精华中的精华"

天气信息

不要断言实际天气("晴"、"多云"),只写"往年均温 XX-XX°C"。加上日出日落时间。


Phase 5: 移动端适配

移动端是主要阅读场景。 必须检查:

@media (max-width: 768px) {
  /* 图片网格 3列→2列 */
  /* 餐厅卡片纵向堆叠 */
  /* 天气栏纵向堆叠 */
  /* section padding 收紧 */
}
@media (max-width: 640px) {
  /* 图片网格→1列 */
  /* 表格→卡片布局(尤其是常用语表格!) */
  /* hero 图比例 21:9 → 4:3 */
  /* timeline 左间距缩小 */
  /* info-grid → 1列 */
}

表格在手机上的处理: 4列表格(如常用语)在手机上必须重排为卡片布局:

.phrase-table thead { display: none }
.phrase-table tr { display: grid; grid-template-columns: auto 1fr; }

Phase 6: 部署

GitHub Pages(推荐,公开分享)

cd <project-dir>
git init && git checkout -b main

# 创建 GitHub Actions workflow
mkdir -p .github/workflows
cat > .github/workflows/pages.yml << 'EOF'
name: Deploy to GitHub Pages
on:
  push:
    branches: ["main"]
permissions:
  contents: read
  pages: write
  id-token: write
jobs:
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/configure-pages@v5
      - uses: actions/upload-pages-artifact@v3
        with:
          path: '.'
      - id: deployment
        uses: actions/deploy-pages@v4
EOF

# 用 gh CLI 创建仓库并部署
gh repo create <name> --public --source . --remote origin --push
gh api repos/<user>/<name>/pages --method POST \
  --field "build_type=workflow" --field "source[branch]=main" --field "source[path]=/"

缓存提示: GitHub Pages cache-control: max-age=600(10分钟)。更新后给朋友发 ?t=xxx 参数链接绕过缓存。


Phase 7: 交付

告诉用户:

  1. 文件位置(完整绝对路径)
  2. 在线链接
  3. 需要提前预约的景点清单 + 预约链接
  4. 如何更新:改 index.htmlgit commitgit push 自动重新部署

Supporting Files

FilePurposeWhen to Read
design-system.mdCSS 变量、组件样式、颜色方案Phase 4 生成 HTML 前
pitfalls-and-fixes.md实际踩过的坑和修复方案Phase 4-5 生成和测试时

Como adicionar

/plugin marketplace add allenwang-maker/travel-planner-skill

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Comentários · Nenhum comentário

Entre para comentar. Entrar

  • Ainda não há comentários. Seja o primeiro.