前端项目初始化,登录页支持暗色主题与禁止滑动

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
fish
2026-04-26 14:40:55 +08:00
parent bd258e19c2
commit c91e038953
29 changed files with 994 additions and 53 deletions

View File

@@ -4,28 +4,53 @@
## 项目状态
> **当前状态:尚未初始化代码。** 技术栈待定,目录除本文件外为空。
> 在选定技术栈后,请补全本文件中标记为「⚠️ 待补充」的章节。
**技术栈已确定,项目已初始化。**
| 维度 | 选型 |
|------|------|
| 框架 | React 18 + TypeScript 5 |
| 构建 | Vite 6 |
| UI 库 | Ant Design 5 + @ant-design/icons |
| 路由 | React Router 6 |
| 状态管理 | Zustand客户端状态 |
| HTTP 客户端 | AxiosAPI 封装在 `src/api/` |
## 定位
`frontend/` 是 asset_helper 的 **Web 前端**,调用后端 API默认通过 Nginx 网关 `https://api.example.com` 暴露)。
`frontend/` 是 asset_helper 的 **Web 管理后台**,调用后端 API通过 Nginx 网关暴露)。
-`backend/` 通过 HTTP/JSON 交互,遵循根目录 [CLAUDE.md](../CLAUDE.md) 中定义的跨端契约
-`app/`(移动/桌面端)共享后端,但 UI 实现独立
- 当前为后台管理系统,后续可扩展为面向用户的 Web 端
## 技术栈
## Docker 开发与部署
> ⚠️ 待补充:选定后请填写。建议候选:
>
> | 维度 | 候选 |
> |------|------|
> | 框架 | React 18 / Vue 3 / Next.js |
> | 语言 | TypeScript推荐与 Rust 后端类型对齐更顺) |
> | 构建 | Vite / Next.js |
> | 状态管理 | Zustand / Pinia / React Query |
> | UI 库 | Ant Design / Element Plus / shadcn-ui |
> | HTTP 客户端 | axios / ky / fetch 封装 |
### 开发环境(热更新,不污染物理机)
```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/*` 到后端网关容器
## 与后端的协作约定
@@ -35,25 +60,18 @@
```ts
interface ApiRequest<T> {
device: number; // 见下方 device 编码
language: number; // 见下方 language 编码
device: number; // 前端固定使用 Device.Web = 3
language: number; // 默认 Language.SimplifiedChinese = 1
data: T; // 业务字段
}
```
**device 编码(必须与 backend 保持一致)**
- `1` = iOS
- `2` = Android
- `3` = Web ← **前端使用此值**
- `4` = iPad
- `5` = macOS
- `6` = Windows
- `7` = Linux
**device 编码:**
- `1` = iOS`2` = Android、`3` = Web ← **前端使用此值**
- `4` = iPad、`5` = macOS、`6` = Windows、`7` = Linux
**language 编码:**
- `1` = 简体中文
- `2` = 繁体中文
- `3` = 英文
- `1` = 简体中文(默认)、`2` = 繁体中文、`3` = 英文
### 2. 响应包装
@@ -75,7 +93,7 @@ interface LoginResponse {
}
```
JWT 存储建议HttpOnly CookieCSRF 防护)或 localStorage注意 XSS 风险),后续根据安全策略统一
**JWT 存储策略**:存于 Zustand 内存中(页面刷新丢失,需重新登录)。如需持久化,可改为 localStorage,但需注意 XSS 风险。
### 4. 错误响应HTTP 非 200
@@ -87,44 +105,88 @@ interface ErrorResponse {
}
```
## 目录结构
```
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<RequestType, ResponseType>('/api/v1/users/xxx', payload)
// ✅ 认证接口(扁平格式,不包装)
import { loginAccount } from '@/api/auth'
const result = await loginAccount({ account: 'xxx', password: 'xxx' })
```
## 代码风格
- 注释使用**中文**(与后端保持一致)
- TypeScript 类型与后端 Rust 结构体一一对齐,避免 `any`
- API 客户端集中封装在一处(如 `src/api/`,不在组件中直接 fetch
## 目录结构
> ⚠️ 待补充:技术栈选定后填写。常见骨架:
>
> ```
> frontend/
> ├── src/
> │ ├── api/ # API 客户端封装device/language 注入、错误统一处理)
> │ ├── components/ # 可复用 UI 组件
> │ ├── pages/ # 路由页面
> │ ├── stores/ # 状态管理
> │ ├── types/ # 与后端对齐的类型定义
> │ └── utils/
> ├── public/
> ├── package.json
> └── vite.config.ts (或对应配置)
> ```
- TypeScript 类型与后端 Rust 结构体一一对齐,禁止 `any`
- API 调用集中在 `src/api/`,不在组件中直接写 axios
- 路由守卫在 `src/router/index.tsx` 中统一配置
## 常用命令
> ⚠️ 待补充:技术栈选定后填写(如 `pnpm dev` / `pnpm build` / `pnpm test`)。
| 命令 | 说明 |
|------|------|
| `npm install` | 安装依赖(开发容器内自动执行) |
| `npm run dev` | 启动开发服务器(容器内) |
| `npm run build` | 生产构建 |
| `npm run preview` | 预览生产构建 |
## 开发环境
- 后端网关默认监听 `localhost:80`/`443`,本地需配置 hosts 或直连 `localhost`
- 后端开发证书为自签名,浏览器需信任或开发环境关闭 HTTPS
- 后端网关默认通过 Docker 网络或 `host.docker.internal` 访问
- 开发容器内 Vite 监听 `0.0.0.0:5173`,映射到宿主机 `3000`
- 如需后端使用 HTTPS 自签名证书Vite proxy 已配置 `secure: false`
## 扩展指南
新增页面/功能时:
1. 先在 `types/` 定义与后端对齐的类型
2.`api/` 添加调用封装(务必通过统一封装注入 `device`/`language`
3. 再开发组件/页面
3. `pages/` 创建页面组件
4.`router/index.tsx` 添加路由
5. 如需加入侧边栏菜单,在 `layouts/MainLayout.tsx``menuItems` 中配置
发现重复逻辑时优先抽到 `utils/` 或自定义 HookReact/ ComposableVue
发现重复逻辑时优先抽到 `utils/` 或自定义 Hook。