# Frontend — Claude Code 项目指南 本文件为 Claude Code(及其它 AI Agent)提供前端项目的背景、结构说明和开发规范。 ## 项目状态 **技术栈已确定,项目已初始化。** | 维度 | 选型 | |------|------| | 框架 | React 18 + TypeScript 5 | | 构建 | Vite 6 | | UI 库 | Ant Design 5 + @ant-design/icons | | 路由 | React Router 6 | | 状态管理 | Zustand(客户端状态) | | HTTP 客户端 | Axios(API 封装在 `src/api/`) | ## 定位 `frontend/` 是 asset_helper 的 **Web 管理后台**,调用后端 API(通过 Nginx 网关暴露)。 - 与 `backend/` 通过 HTTP/JSON 交互,遵循根目录 [CLAUDE.md](../CLAUDE.md) 中定义的跨端契约 - 与 `app/`(移动/桌面端)共享后端,但 UI 实现独立 - 当前为后台管理系统,后续可扩展为面向用户的 Web 端 ## Docker 开发与部署 ### 开发环境(热更新,不污染物理机) ```bash cd frontend docker-compose -f docker-compose.dev.yml up --build ``` - 访问:`http://localhost:3000` - 源码通过 volume 挂载,修改后自动热更新 - API 请求通过 Vite proxy 转发到后端网关(默认 `http://host.docker.internal:80`) **如需修改后端地址:** ```bash VITE_API_BASE_URL=http://your-backend:80 docker-compose -f docker-compose.dev.yml up ``` ### 生产构建与部署 ```bash cd frontend docker-compose up --build ``` - 访问:`http://localhost:20080`(端口可通过 `ADMIN_WEB_PORT` 环境变量修改) - 多阶段构建:Node 构建 → Nginx 提供静态文件 - Nginx 代理 `/api/*` 到后端网关容器 ## 与后端的协作约定 以下约定来自 [backend/CLAUDE.md](../backend/CLAUDE.md),前端调用时**必须遵守**: ### 1. 请求包装(注册/业务类接口) ```ts interface ApiRequest { device: number; // 前端固定使用 Device.Web = 3 language: number; // 默认 Language.SimplifiedChinese = 1 data: T; // 业务字段 } ``` **device 编码:** - `1` = iOS、`2` = Android、`3` = Web ← **前端使用此值** - `4` = iPad、`5` = macOS、`6` = Windows、`7` = Linux **language 编码:** - `1` = 简体中文(默认)、`2` = 繁体中文、`3` = 英文 ### 2. 响应包装 ```ts interface ApiResponse { success: boolean; message: string; data: T | null; // 失败时为 null } ``` ### 3. 登录/认证类接口(扁平响应) ```ts interface LoginResponse { success: boolean; token: string | null; // JWT message: string; } ``` **JWT 存储策略**:存于 Zustand 内存中(页面刷新丢失,需重新登录)。如需持久化,可改为 localStorage,但需注意 XSS 风险。 ### 4. 错误响应(HTTP 非 200) ```ts interface ErrorResponse { error: string; message: string; code: number; } ``` ## 目录结构 ``` frontend/ ├── docker/ │ ├── Dockerfile # 生产多阶段构建 │ ├── Dockerfile.dev # 开发环境(volume 挂载源码) │ └── nginx.conf # 生产 Nginx SPA 配置 ├── src/ │ ├── api/ │ │ ├── client.ts # Axios 封装(device/language 注入、JWT、错误处理) │ │ └── auth.ts # 认证相关 API │ ├── components/ # 可复用 UI 组件(待扩展) │ ├── hooks/ # 自定义 Hooks(待扩展) │ ├── layouts/ │ │ └── MainLayout.tsx # 后台主布局(侧边栏 + 头部 + 内容区) │ ├── pages/ │ │ ├── LoginPage.tsx # 登录页(账号/邮箱切换) │ │ ├── DashboardPage.tsx # 仪表盘首页 │ │ └── NotFoundPage.tsx # 404 │ ├── router/ │ │ └── index.tsx # 路由配置(登录守卫 + 受保护路由) │ ├── stores/ │ │ └── auth.ts # Zustand 认证状态(token + login/logout) │ ├── types/ │ │ ├── api.ts # 通用 API 类型(device/language 枚举、包装类型) │ │ └── auth.ts # 认证相关类型 │ ├── utils/ │ │ └── storage.ts # localStorage 封装(带前缀隔离) │ ├── App.tsx # 根组件(ConfigProvider + RouterProvider) │ └── main.tsx # 入口 ├── docker-compose.dev.yml # 开发编排(热更新) ├── docker-compose.yml # 生产编排 ├── index.html ├── package.json ├── tsconfig.json / tsconfig.app.json / tsconfig.node.json └── vite.config.ts ``` ## API 调用规范 **必须使用封装函数,禁止直接 fetch/axios:** ```ts // ✅ 业务接口(自动注入 device/language) import { apiPost, apiGet } from '@/api/client' const data = await apiPost('/api/v1/users/xxx', payload) // ✅ 认证接口(扁平格式,不包装) import { loginAccount } from '@/api/auth' const result = await loginAccount({ account: 'xxx', password: 'xxx' }) ``` ## 代码风格 - 注释使用**中文**(与后端保持一致) - TypeScript 类型与后端 Rust 结构体一一对齐,禁止 `any` - API 调用集中在 `src/api/`,不在组件中直接写 axios - 路由守卫在 `src/router/index.tsx` 中统一配置 ## 常用命令 | 命令 | 说明 | |------|------| | `npm install` | 安装依赖(开发容器内自动执行) | | `npm run dev` | 启动开发服务器(容器内) | | `npm run build` | 生产构建 | | `npm run preview` | 预览生产构建 | ## 开发环境 - 后端网关默认通过 Docker 网络或 `host.docker.internal` 访问 - 开发容器内 Vite 监听 `0.0.0.0:5173`,映射到宿主机 `3000` - 如需后端使用 HTTPS 自签名证书,Vite proxy 已配置 `secure: false` ## 扩展指南 新增页面/功能时: 1. 先在 `types/` 定义与后端对齐的类型 2. 在 `api/` 添加调用封装(务必通过统一封装注入 `device`/`language`) 3. 在 `pages/` 创建页面组件 4. 在 `router/index.tsx` 添加路由 5. 如需加入侧边栏菜单,在 `layouts/MainLayout.tsx` 的 `menuItems` 中配置 发现重复逻辑时优先抽到 `utils/` 或自定义 Hook。