做了一个中国旅行网站,专门服务外国人

AI摘要
该项目为外国游客提供一站式中国旅行解决方案,聚焦签证查询自动化、个性化行程规划及信息整合。通过本地规则匹配与AI兜底处理签证政策,基于真实文化体验库生成行程,并采用静态站点技术优化性能。属于技术实现与产品设计结合的知识分享。

先说说为什么做这个项目

去年有几个外国朋友想来中国玩,问了我一堆问题:

  • “我持美国护照,去成都需不需要签证?”

  • “我想学做川菜,哪里能订到靠谱的体验课?”

  • “7天时间去北京+西安,怎么安排比较合理?”

我帮他们在小红书上翻了半天,又查签证政策、又对比Klook和携程,折腾了一下午。后来我想,如果有一个网站能把这些零散信息串起来,让外国人自己就能搞定,应该挺有用的。

于是就有了 Haojourney


它解决什么问题

简单来说,就是把外国人来中国旅行前最头疼的三件事,用代码 + AI 自动化掉:

1. 签证政策查起来太费劲

中国的签证政策其实挺复杂的:互免、单方面免签、144/240小时过境、海南免签… 而且每个国家的政策还不一样。我做了个 签证检查器,先本地匹配规则(支持 100+ 国家的别名),搞不定再走 DeepSeek AI 兜底。8秒超时自动 fallback,保证不卡死。

2. 行程规划很容易变成”游客打卡团”

市面上的行程工具基本就列几个景点。我想做的是把真实的本地文化体验塞进去——比如跟老师傅学做小龙包、在茶园跟着茶农采茶、去看一场真正的川剧变脸。目前录了 205 个活动,覆盖 73 个城市,都是能直接订的。

AI 规划行程时,会先从这 205 个活动里挑匹配的塞进 itinerary,再让 DeepSeek 补全每天的细节。这样生成的行程不是瞎编的,而是有真实活动做背书的。

3. 信息分散在十个平台

我把体验目录、签证指南、旅行博客(季节攻略、eSIM、支付方式)全放在一个站里,用 Next.js 静态导出,打开速度够快,SEO 也做了全套(动态 sitemap、IndexNow、JSON-LD 结构化数据)。


技术栈和实现思路

| 层面 | 选型 | 原因 |

|——|——|——|

| 框架 | Next.js 15 App Router | 静态导出 + API Route 混合,签证检查走 Edge,AI 生成走 Node |

| UI | shadcn/ui + Tailwind | 不想自己写组件,但又要能深度定制 |

| AI | DeepSeek-V3 | 中文理解好,价格够低, itinerary 生成 1500 tokens 够用了 |

| 数据 | 本地 JSON + Supabase Auth | 活动数据直接 import JSON,比接 CMS 简单;Auth 用 Supabase 省事儿 |

| 部署 | Vercel | 静态页面自动全球 CDN,API 延迟也低 |

几个值得说的技术点

签证检查器的规则设计

我没让 AI 直接回答签证问题,而是先维护了一套本地规则:

  • 互免 29 国

  • 单方面 30 天免签 48 国

  • 240 小时过境 55 国

  • 海南 59 国免签

  • 24 小时过境(所有国家)

用户输入国家后,先本地匹配,90% 的情况不用调 API。只有当用户输入了奇奇怪怪的别名(比如 “United States of America” 写成 “USA” 或 “US”)时,才走 DeepSeek 做模糊匹配。这样响应快、成本低、准确率反而更高。

行程生成的 RAG 思路

虽然没用向量数据库,但思路是一样的:用户选了城市和兴趣偏好 → 先从 205 个活动里过滤出匹配的(最多 10 个)→ 把这些活动作为上下文发给 DeepSeek → 让 AI 基于真实活动生成 day-by-day 行程。这样避免了 AI 瞎编一个”成都熊猫茶馆体验”但实际上不存在的情况。

静态导出的一些取舍

因为用了 next export,图片优化关掉了(unoptimized: true),导致一开始 PNG 图片直接打包进去,体积爆炸。后来写了个脚本把 32 张 PNG 批量转 WebP,从 70MB 压到 20MB 出头。

Experiences 列表页一开始是全部 205 条一起渲染,虽然静态导出本身没问题,但 DOM 太大。后来加了服务端分页,每页 12 条,URL 带 ?page=2 参数,SEO 也保住了。


目前的数据

  • 活动:205 个,覆盖 73 个城市

  • 签证政策:支持 6 种大类,100+ 国家匹配

  • 页面:全站静态生成 247 个页面

  • 性能:首页 Lighthouse 95+(主要是静态页面的优势)


踩过的坑

  1. AI 超时必须处理。DeepSeek 偶尔抽风,8秒不返回就触发 fallback,用本地模板生成一个基础行程,不能让用户白等。

  2. 静态导出的 dynamic route/experiences/[slug] 有 200+ 个活动页面,用 generateStaticParams 全部预渲染,但构建时间会变长。如果以后做到 1000+ 活动,可能需要改策略。

  3. Auth 的 hydration 问题。Next.js 静态导出 + Supabase Auth,服务端渲染时拿不到 user,导致页面闪一下登录状态。最后把 Auth 相关的 UI 都包在 client component 里,用 mounted 标志位控制,避免水合不匹配。


下一步想做的事

  • 把活动数据从 JSON 迁到数据库,方便后台编辑

  • 加用户评论和评分,让体验质量更透明

  • 做多语言(日语、韩语、西班牙语)

  • 试试把行程生成改成流式输出,体验更顺滑

讨论数量: 2

我好奇你怎么推广?

7小时前 评论

现在怎么样推广这个问题的啊,怎么样去实现这些功能

3小时前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!