nomadweb/README.md
eric bf654f76e6 Add visa wizard, coworking, packing, season guide, and UX polish
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-28 23:05:48 -05:00

248 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# NomadFlow · 数字游民旅居平台
全栈数字游民旅居指南,采用 **Next.js + FastAPI + PocketBase** 架构。
品牌:**NomadFlow** — 用一行代码环游世界 🌏
## 技术栈
| 层级 | 技术 | 说明 |
|------|------|------|
| 前端 | Next.js 16 + React 19 | SSR/ISR、组件化 UI、Turbopack |
| 后端 | FastAPI | REST API、业务逻辑 |
| 数据库 | PocketBase | 数据持久化、管理后台 |
| 图表 | Chart.js (CDN) | 数据可视化 |
| 部署 | Vercel + Railway + Docker | 前后端分离部署 |
## 项目结构
```
nomadweb/
├── frontend/ # Next.js 前端应用
│ ├── src/app/ # 页面路由 (App Router)
│ ├── src/components/ # UI 组件 (30+)
│ └── src/lib/ # API 客户端、Auth、Toast
├── backend/ # FastAPI 后端
│ ├── app/routers/ # API 路由
│ ├── app/services/ # PocketBase、Auth 服务
│ └── app/data/ # Mock 降级数据
├── pocketbase/ # PocketBase 数据目录
├── scripts/ # 开发启动脚本 (dev.ps1 / dev.sh)
├── docker-compose.yml # 一键启动全部服务
├── index.html # 原始静态版(保留)
└── README.md
```
## 快速开始
### 方式一:本地开发(推荐)
**1. 启动 PocketBase(可选)**
```bash
# 下载: https://pocketbase.io/docs/
# 或使用 Docker:
docker run -d -p 8090:8090 -v ./pocketbase/pb_data:/pb_data ghcr.io/muchobien/pocketbase:latest
```
访问 http://localhost:8090/_/ 创建管理员(可选,不启动则自动使用 Mock 数据)。
**2. 启动 FastAPI 后端**
```bash
cd backend
pip install -r requirements.txt
cp .env.example .env # 按需修改
uvicorn app.main:app --reload --port 8000
```
API 文档: http://localhost:8000/docs
**3. 启动 Next.js 前端**
```bash
cd frontend
cp .env.local.example .env.local
npm install --legacy-peer-deps
npm run dev
```
访问 http://localhost:3000
### 方式二:一键脚本(Windows)
```powershell
.\scripts\dev.ps1
```
### 方式三:Docker Compose
```bash
docker compose up -d
```
| 服务 | 地址 |
|------|------|
| 前端 | http://localhost:3000 |
| API | http://localhost:8000/docs |
| PocketBase | http://localhost:8090/_/ |
## 功能特性
### 首页核心板块
| 板块 | 说明 |
|------|------|
| 🗺️ 世界地图 | 交互式 SVG 热力图,点击查看城市详情 |
| 🌍 目的地 | 筛选/搜索/排序,收藏,最多 4 城对比 |
| 🎯 智能匹配 | 4 步问卷,推荐最适合的旅居城市 |
| 🕐 时区看板 | 实时时钟 + 与国内团队工作时间重叠分析 |
| 🗓️ 行程规划 | 多城市规划,预算汇总,分享/导入链接 |
| 🧮 费用计算器 | 按目的地、住宿档次、月数估算预算 |
| 💱 多币种换算 | CNY/USD/EUR/THB 等 8 种货币互转 |
| 📊 就绪度测评 | 5 题评估你的数字游民准备程度 |
| 💻 生活方式 | 交互式「游民一天」时间轴 |
| 📋 签证指南 | 难度筛选 + 签证智能匹配向导 |
| 💻 联合办公 | 精选 Co-working Space,城市/评分/网速排序 |
| 🌤️ 最佳月份 | 12 月气候适宜度热力表,避开雨季 |
| 🧳 行李清单 | 可勾选打包清单,localStorage 持久化 |
| 📝 博客 | 标签筛选 + 阅读进度 + 相关推荐 + 分享 |
| ❓ FAQ | 搜索 + 展开/收起全部 |
### 交互与体验
- ✨ Canvas 粒子背景 + 品牌加载动画
- 🌓 深色/浅色主题切换(localStorage 持久化)
- 🔍 全局搜索 `Ctrl+K`(目的地/博客/签证/FAQ)
- 🧭 右侧浮动章节导航
- 📊 顶部滚动进度条
- ⚖️ 可视化城市对比(评分圆环 + 条形图)
- 🔔 全局 Toast 通知
- 💡 游民小贴士浮动提示
- 🍪 Cookie 同意横幅
- ⌨️ 快捷键:`M` 智能匹配、`?` 帮助面板
- 📱 响应式布局,移动端适配
### 用户系统
- 🔐 登录 / 注册 / 一键演示账号
- ❤️ 收藏目的地(同步 API)
- 👤 用户中心:统计、收藏、行程、成就徽章
- 演示账号:`demo@nomadflow.io` / `demo123`
### 后端 API
| 端点 | 方法 | 说明 |
|------|------|------|
| `/api/v1/destinations` | GET | 目的地列表(region/search/sort) |
| `/api/v1/destinations/{slug}` | GET | 目的地详情 |
| `/api/v1/destinations/compare` | POST | 城市对比(2–4 城) |
| `/api/v1/calculator` | POST | 费用计算 |
| `/api/v1/search` | GET | 全局搜索 |
| `/api/v1/blog` | GET | 博客列表 |
| `/api/v1/blog/{slug}` | GET | 博客详情 |
| `/api/v1/auth/register` | POST | 注册 |
| `/api/v1/auth/login` | POST | 登录 |
| `/api/v1/auth/demo` | GET | 演示登录 |
| `/api/v1/auth/favorites` | GET/POST | 收藏管理 |
| `/api/v1/charts/*` | GET | 图表数据 |
| `/api/v1/subscribe` | POST | 邮件订阅 |
> PocketBase 不可用时,API 自动降级到 `backend/app/data/mock_data.py`。
## 页面路由
| 路径 | 说明 |
|------|------|
| `/` | 首页(全部板块) |
| `/login` | 登录 / 注册 |
| `/profile` | 用户中心 |
| `/destinations/[slug]` | 目的地详情(城市画像、加入行程) |
| `/blog/[slug]` | 博客详情(阅读进度) |
## 环境变量
### Backend (`backend/.env`)
```env
POCKETBASE_URL=http://127.0.0.1:8090
POCKETBASE_ADMIN_EMAIL=admin@nomadflow.io
POCKETBASE_ADMIN_PASSWORD=admin123456
CORS_ORIGINS=http://localhost:3000
```
### Frontend (`frontend/.env.local`)
```env
NEXT_PUBLIC_API_URL=http://localhost:8000/api/v1
```
## 部署
### 生产环境(已上线)
| 项目 | 地址 |
|------|------|
| 网站 | https://nomadweb.nomadro.com |
| API 健康检查 | https://nomadweb.nomadro.com/api/v1/health |
| API 文档 | https://nomadweb.nomadro.com/docs |
| Git 仓库 | https://gitea.dsx2020.com/eric/nomadweb |
**服务器架构:**
- 服务器:`107.173.30.245`
- 反向代理:Caddy(自动 HTTPS)
- 前端容器:`127.0.0.1:3055` → Next.js
- 后端容器:`127.0.0.1:8055` → FastAPI
- 数据库:PocketBase(Docker 内部网络)
**更新部署:**
```bash
# SSH 登录服务器后(当前开发分支为 dev1)
cd /opt/nomadweb
git fetch origin && git checkout -B dev1 origin/dev1
export DOMAIN=nomadweb.nomadro.com
export NEXT_PUBLIC_API_URL=https://nomadweb.nomadro.com/api/v1
export NEXT_PUBLIC_SITE_URL=https://nomadweb.nomadro.com
export CORS_ORIGINS=https://nomadweb.nomadro.com
docker compose -f docker-compose.prod.yml up -d --build
```
或使用 Docker Compose 生产配置:
```bash
docker compose -f docker-compose.prod.yml up -d --build
cp deploy/caddy/nomadweb.caddy /etc/caddy/sites/nomadweb.caddy
systemctl reload caddy
```
### 本地 Docker Compose
```bash
docker compose up -d
```
### 前端 → Vercel
1. 导入 `frontend/` 目录
2. 环境变量:`NEXT_PUBLIC_API_URL=https://nomadweb.nomadro.com/api/v1`
3. 自动构建部署
### 后端 → Railway
1. 连接 `backend/` 目录
2. 配置 `POCKETBASE_URL`、`CORS_ORIGINS`
3. 读取 `railway.toml` 自动部署
## 快捷键
| 按键 | 功能 |
|------|------|
| `Ctrl+K` | 全局搜索 |
| `M` | 智能目的地匹配 |
| `?` | 快捷键帮助 |
| `Esc` | 关闭弹窗 |
## License
MIT