nomadweb/README.md
eric 99ebbed799 Refresh README for plan/compare sync, native deploy, and product funnel.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-29 05:02:29 -05:00

231 lines
7.3 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.

# nomadro · 数字游民旅居平台
全栈数字游民旅居指南,品牌 **nomadro** — 用一行代码环游世界 🌏
**线上:** [https://nomadweb.nomadro.com](https://nomadweb.nomadro.com)
核心产品闭环:**发现目的地 → 智能匹配 / 城市对比 → 旅居计划中心 → 登录云端同步**
## 技术栈
| 层级 | 技术 | 说明 |
|------|------|------|
| 前端 | Next.js 16 + React 19 | App Router、ISR、Turbopack、standalone |
| 后端 | FastAPI | REST API、业务逻辑、账号计划同步 |
| 数据 | PocketBase + Mock 降级 | 内容库;用户收藏/计划可落盘 |
| 部署 | Caddy + systemd(原生优先) | 生产非 Docker 跑 Web/API |
## 项目结构
```
nomadweb/
├── frontend/ # Next.js
│ ├── src/app/ # 路由:/ /plan /compare /tools /profile …
│ ├── src/components/ # UI 与工具组件
│ └── src/lib/ # API、auth、trip/plan 存储与同步
├── backend/ # FastAPI
│ ├── app/routers/ # API 路由
│ ├── app/services/ # PocketBase、Auth(含计划同步)
│ └── app/data/ # Mock 降级 + user_store(运行时)
├── deploy/ # Caddy、systemd 单元
├── scripts/ # 本地开发、生产部署脚本
├── pocketbase/ # PocketBase 数据目录
└── docker-compose*.yml # 本地 / 备选生产 Compose
```
## 快速开始
### 1. PocketBase(可选)
不启动则 API 自动使用 `backend/app/data/mock_data.py`。
```bash
docker run -d -p 8090:8090 -v ./pocketbase/pb_data:/pb_data ghcr.io/muchobien/pocketbase:latest
```
管理后台:http://localhost:8090/_/
### 2. FastAPI
```bash
cd backend
pip install -r requirements.txt
cp .env.example .env
uvicorn app.main:app --reload --port 8000
```
文档: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
### 其他方式
```powershell
.\scripts\dev.ps1 # Windows 一键
docker compose up -d # Compose 全栈
```
## 核心产品
| 能力 | 路径 / 入口 | 说明 |
|------|-------------|------|
| 🗺️ 地图 & 目的地 | `/#map` `/#destinations` | 筛选、收藏、勾选对比(最多 4 城) |
| 🎯 智能匹配 | FAB / `M` | 4 步问卷;偏好本地保存;Top 结果可写入计划 / 对比 |
| ⚖️ 城市对比台 | `/compare` | 可分享 `?cities=`;指标并排;写入计划 |
| 🗓️ 旅居计划中心 | `/plan` | 多城时间轴、出发月、预算、站内备注、签证方案与超期提醒、就绪清单、MD / ICS 导出、分享链接 |
| ☁️ 账号同步 | `/login?next=/plan` | 登录后合并本机与云端计划;收藏同步;服务重启落盘保留 |
| 👤 个人中心 | `/profile` | 计划仪表盘、就绪度、收藏写入计划、成就 |
演示账号:`demo@nomadro.com` / `demo123`
## 首页与工具箱
首页仍聚合大量旅居工具(按视口懒加载),完整列表见 `/tools` 与 `/changelog`。常见能力包括:
- 费用计算器、多币种、启动金 / 跑道、落地首月成本
- 时区看板、会议重叠、日照办公窗、时差估算
- 签证指南 + 停留倒计时、保险、税居天数
- 联合办公、住宿、SIM、电源、紧急联系、防坑与取现
- 行李清单、到站清单、专注时钟、博客与 FAQ 等
导航、Hero、快捷条、底栏与新手引导优先导向 **计划 / 对比**,小工具集中在工具箱。
## 体验与性能
- 首屏:地图 + 目的地;中屏及以下 `WhenVisible` + 动态拆包
- Outfit 自托管;中文系统字体;缩短 Loader;粒子延后、无连线
- 深浅色主题、`Ctrl+K` 全局搜索、Toast、Cookie 提示
- 响应式布局;`.section` 使用 `content-visibility`
## 页面路由
| 路径 | 说明 |
|------|------|
| `/` | 首页 |
| `/plan` | 旅居计划中心 |
| `/compare` | 城市对比台 |
| `/tools` | 工具箱 |
| `/destinations/[slug]` | 目的地详情(画像、停留月数、加入计划) |
| `/login` | 登录 / 注册(`?next=` 回流,默认 `/plan`) |
| `/profile` | 用户中心 |
| `/blog/[slug]` | 博客 |
| `/about` `/privacy` `/changelog` | 关于 / 隐私 / 更新日志 |
| `/sitemap.xml` | 含 `/plan`、`/compare` 等 |
## 后端 API(节选)
| 端点 | 方法 | 说明 |
|------|------|------|
| `/api/v1/destinations` | GET | 列表(region / search / sort) |
| `/api/v1/destinations/{slug}` | GET | 详情 |
| `/api/v1/destinations/compare` | POST | 按 slug 取城 |
| `/api/v1/calculator` | POST | 费用估算 |
| `/api/v1/search` | GET | 全局搜索 |
| `/api/v1/visas` 等 | GET | 签证 / FAQ / 博客 / 图表 |
| `/api/v1/auth/register` | POST | 注册 |
| `/api/v1/auth/login` | POST | 登录 |
| `/api/v1/auth/demo` | GET | 演示登录 |
| `/api/v1/auth/favorites` | GET/POST | 收藏 |
| `/api/v1/auth/plan` | GET/PUT | **旅居计划云端读写** |
| `/api/v1/auth/profile/stats` | GET | 个人统计 |
| `/api/v1/subscribe` | POST | 邮件订阅 |
| `/api/v1/health` | GET | 健康检查 |
PocketBase 不可用时内容接口降级 Mock。用户收藏与计划写入 `backend/app/data/user_store.json`(运行时生成,勿提交密钥与生产数据)。
## 环境变量
**Backend `backend/.env`**
```env
POCKETBASE_URL=http://127.0.0.1:8090
POCKETBASE_ADMIN_EMAIL=admin@nomadro.com
POCKETBASE_ADMIN_PASSWORD=admin123456
CORS_ORIGINS=http://localhost:3000
```
**Frontend `frontend/.env.local`**
```env
NEXT_PUBLIC_API_URL=http://localhost:8000/api/v1
NEXT_PUBLIC_SITE_URL=http://localhost:3000
```
生产前端构建时:
```env
NEXT_PUBLIC_API_URL=https://nomadweb.nomadro.com/api/v1
NEXT_PUBLIC_SITE_URL=https://nomadweb.nomadro.com
```
## 部署
### 生产(已上线)
| 项目 | 地址 |
|------|------|
| 网站 | https://nomadweb.nomadro.com |
| API 健康检查 | https://nomadweb.nomadro.com/api/v1/health |
| API 文档 | https://nomadweb.nomadro.com/docs |
| 仓库 | https://gitea.dsx2020.com/eric/nomadweb |
**架构(原生 systemd,Caddy 反代):**
| 进程 | 地址 |
|------|------|
| Caddy | HTTPS → 见 `deploy/caddy/nomadweb.caddy` |
| `nomadro-web` | `127.0.0.1:3055`(Next standalone) |
| `nomadro-api` | `127.0.0.1:8055`(uvicorn) |
| PocketBase | `127.0.0.1:8090` |
单元:`deploy/systemd/nomadro-web.service`、`nomadro-api.service`。
**推荐更新:**
```bash
# 需能 git pull 到 origin/dev1 时
python scripts/deploy_update.py
```
拉取 → 按变更增量构建前后端 → `systemctl restart`;会停掉占用端口的旧 Docker Web/API 容器。
**Gitea 不可用 / 仅本地有最新提交时:**
```bash
python scripts/deploy_direct_sync.py
```
SFTP 同步变更文件 → 重建前端(并重启 API)→ 健康检查。
**备选 Docker Compose:** 见 `docker-compose.prod.yml`(生产默认以原生为准)。
## 快捷键
| 按键 | 功能 |
|------|------|
| `Ctrl+K` | 全局搜索 |
| `M` | 智能匹配 |
| `P` | 打开旅居计划中心 |
| `T` | 打开工具箱 |
| `G` | 命运转盘(首页) |
| `?` | 快捷键帮助 |
| `Esc` | 关闭弹窗 |
## 相关文档
- 产品迭代:[`/changelog`](https://nomadweb.nomadro.com/changelog)
- 本地变更记录:`frontend/src/app/changelog/page.tsx`
## License
MIT