177 lines
4.5 KiB
Markdown
177 lines
4.5 KiB
Markdown
# 聚玩前端
|
||
|
||
基于 Next.js 15 的游戏代练平台前端应用。
|
||
|
||
## 技术栈
|
||
|
||
- **框架**: Next.js 15 (App Router)
|
||
- **语言**: TypeScript
|
||
- **样式**: Tailwind CSS 4
|
||
- **状态管理**: Zustand
|
||
- **表单**: React Hook Form + Zod
|
||
- **UI 组件**: Radix UI + shadcn/ui
|
||
- **测试**: Vitest
|
||
|
||
## 开发环境设置
|
||
|
||
### 前置要求
|
||
|
||
- Node.js 25+
|
||
- pnpm 10+
|
||
|
||
### 安装依赖
|
||
|
||
```bash
|
||
pnpm install
|
||
```
|
||
|
||
### 连接后端开发
|
||
|
||
1. **启动后端服务**
|
||
|
||
在后端仓库的 `deploy/dev` 目录下构建并启动所有微服务:
|
||
|
||
```bash
|
||
cd ../juwan-backend/deploy/dev
|
||
python3 build.py
|
||
docker compose up -d
|
||
```
|
||
|
||
验证后端是否正常运行:
|
||
|
||
```bash
|
||
curl http://127.0.0.1:18080/healthz
|
||
```
|
||
|
||
2. **启动前端开发服务器**
|
||
|
||
```bash
|
||
pnpm dev
|
||
```
|
||
|
||
访问 http://localhost:3000
|
||
|
||
Next.js 会自动将 `/api/*` 请求代理到 `http://localhost:18080/api/*`(后端 Envoy Gateway),无需额外配置。
|
||
|
||
### 其他命令
|
||
|
||
```bash
|
||
# 类型检查
|
||
pnpm typecheck
|
||
|
||
# 代码检查
|
||
pnpm lint
|
||
|
||
# 代码格式化
|
||
pnpm format
|
||
|
||
# 运行测试
|
||
pnpm test
|
||
|
||
# 完整检查(类型 + lint + 格式)
|
||
pnpm check
|
||
|
||
# 生产构建
|
||
pnpm build
|
||
|
||
# 启动生产服务器
|
||
pnpm start
|
||
```
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
juwan-frontend/
|
||
├── app/ # Next.js App Router 页面
|
||
│ ├── (auth)/ # 认证相关页面(注册/登录/找回密码)
|
||
│ ├── (account)/ # 账户相关页面(个人中心/认证申请)
|
||
│ ├── (order)/ # 订单相关页面(下单/聊天/评价/纠纷)
|
||
│ └── (main)/ # 主要页面(首页/搜索/打手/店铺)
|
||
├── components/ # 可复用组件
|
||
├── lib/ # 工具函数和类型定义
|
||
│ ├── api/ # API 调用函数
|
||
│ ├── domain/ # 业务逻辑(状态机等)
|
||
│ ├── types.ts # 核心类型定义
|
||
│ ├── errors.ts # 错误处理
|
||
│ └── decision.ts # 权限决策
|
||
├── store/ # Zustand 状态管理
|
||
├── tests/ # 测试文件
|
||
└── public/ # 静态资源
|
||
|
||
```
|
||
|
||
## API 代理配置说明
|
||
|
||
开发环境下,Next.js 会自动将 `/api/*` 请求代理到后端:
|
||
|
||
```typescript
|
||
// next.config.ts
|
||
async rewrites() {
|
||
if (process.env.NODE_ENV !== 'development') {
|
||
return []
|
||
}
|
||
const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:18080'
|
||
return [
|
||
{
|
||
source: '/api/:path*',
|
||
destination: `${backendUrl}/api/:path*`,
|
||
},
|
||
]
|
||
}
|
||
```
|
||
|
||
**优点**:
|
||
|
||
- 前端代码无需关心后端地址
|
||
- 避免 CORS 问题(同源请求)
|
||
- Cookie 自动携带
|
||
- 开发/生产环境无缝切换
|
||
|
||
## 环境变量
|
||
|
||
| 变量名 | 说明 | 默认值 |
|
||
| ------------------------- | ------------------------------- | ----------------------- |
|
||
| `NEXT_PUBLIC_BACKEND_URL` | 后端 API 地址(仅开发环境生效) | `http://localhost:18080` |
|
||
|
||
**注意**:
|
||
|
||
- 此变量仅在开发环境(`pnpm dev`)生效,用于配置 API 代理目标
|
||
- 生产环境不使用此变量,前后端通过 Envoy Gateway 统一路由
|
||
|
||
## 部署
|
||
|
||
本仓库作为后端仓库(`juwan-backend`)的子模块接入 dev compose,通过其中的 Envoy 网关同源对外提供。
|
||
|
||
`Dockerfile` 使用 Next.js standalone 输出。后端 `deploy/dev/build.py` 会扫描出 `frontend` target 一并构建为 `juwan/frontend:dev`,随 compose 拉起,浏览器从 `http://localhost:18080` 访问。
|
||
|
||
## 开发规范
|
||
|
||
- 使用 TypeScript 严格模式
|
||
- 遵循 ESLint 规则(`pnpm lint`)
|
||
- 提交前运行 `pnpm check` 确保代码质量
|
||
- 所有 API 调用必须有类型定义
|
||
- 组件使用 shadcn/ui 风格
|
||
|
||
## 常见问题
|
||
|
||
### Q: 本地开发如何连后端?
|
||
|
||
A: 在后端仓库 `deploy/dev` 下执行 `python3 build.py && docker compose up -d` 启动所有微服务,然后 `pnpm dev` 启动前端。默认代理到 `http://localhost:18080`,无需额外配置。
|
||
|
||
### Q: 后端连接失败怎么办?
|
||
|
||
A: 检查以下几点:
|
||
|
||
1. 后端 Docker 容器是否正常运行(`docker compose ps`)
|
||
2. Envoy Gateway 是否监听在 18080 端口(`curl http://127.0.0.1:18080/healthz`)
|
||
3. 如果使用了自定义端口,检查 `.env.local` 中的 `NEXT_PUBLIC_BACKEND_URL`
|
||
4. 浏览器控制台是否有 CORS 错误
|
||
|
||
### Q: 如何添加新的 API?
|
||
|
||
A:
|
||
|
||
1. 在 `lib/types.ts` 定义类型
|
||
2. 在 `lib/api/` 创建 API 函数
|
||
3. 在 `store/` 中调用 API
|