diff --git a/docs/PHASE6-DESIGN.md b/docs/PHASE6-DESIGN.md new file mode 100644 index 000000000..39f8cc4f2 --- /dev/null +++ b/docs/PHASE6-DESIGN.md @@ -0,0 +1,678 @@ +# Phase 6: 前端完善 - 详细设计文档 + +> 版本:v1.0 +> 创建时间:2026-06-17 +> 负责人:小虾 🦐 +> 预计时间:4-6 周 + +--- + +## 📋 目标 + +在 Phase 4 完成的后端 API 基础上,构建完整的前端用户界面,让用户可以通过图形化界面使用所有 SaaS 功能。 + +--- + +## 🎯 核心目标 + +1. **用户认证界面** - 注册/登录/密码管理 +2. **工作空间管理** - 创建/管理工作空间和成员 +3. **订阅管理界面** - 查看/升级/管理订阅 +4. **Admin 后台** - 系统管理和数据监控 +5. **响应式设计** - 支持桌面/平板/移动端 + +--- + +## 🛠️ 技术栈选型 + +### 前端框架 +**选择:React 18 + TypeScript** + +**理由:** +- 生态成熟,组件丰富 +- TypeScript 提供类型安全 +- 与后端 API 配合良好 +- 社区活跃,文档完善 + +**替代方案:** +- Vue 3 + TypeScript(更简单,但生态相对小) +- Next.js 14(支持 SSR,适合 SEO) + +### UI 组件库 +**选择:Ant Design 5.x** + +**理由:** +- 企业级 UI 组件 +- 中文文档完善 +- 开箱即用的表单/表格/布局 +- 符合国内用户习惯 + +**替代方案:** +- Material-UI(更现代,但学习曲线陡) +- Chakra UI(轻量,但组件不够丰富) +- shadcn/ui(新兴,基于 Tailwind) + +### 状态管理 +**选择:Zustand** + +**理由:** +- 轻量简单 +- TypeScript 友好 +- 无需 Provider 包裹 +- 学习成本低 + +**替代方案:** +- Redux Toolkit(功能强大,但复杂) +- Jotai/Recoil(原子化状态,适合大型应用) + +### 路由 +**选择:React Router v6** + +### HTTP 客户端 +**选择:Axios + React Query** + +**理由:** +- Axios:成熟稳定,拦截器方便 +- React Query:自动缓存、重试、分页支持 + +### 表单管理 +**选择:React Hook Form + Zod** + +**理由:** +- React Hook Form:性能优秀,API 简洁 +- Zod:TypeScript 友好的 schema 验证 + +### 样式方案 +**选择:CSS Modules + Tailwind CSS** + +### 构建工具 +**选择:Vite** + +**理由:** +- 开发服务器极快 +- 原生 ES 模块支持 +- 完美支持 React + TypeScript + +--- + +## 📐 项目结构 + +``` +apps/web/ +├── src/ +│ ├── api/ # API 调用封装 +│ │ ├── auth.ts # 认证相关 API +│ │ ├── workspace.ts # 工作空间 API +│ │ ├── subscription.ts +│ │ └── client.ts # Axios 实例配置 +│ ├── components/ # 可复用组件 +│ │ ├── common/ # 通用组件 +│ │ │ ├── Button/ +│ │ │ ├── Modal/ +│ │ │ └── Table/ +│ │ ├── layout/ # 布局组件 +│ │ │ ├── Header/ +│ │ │ ├── Sidebar/ +│ │ │ └── Footer/ +│ │ └── business/ # 业务组件 +│ │ ├── WorkspaceCard/ +│ │ ├── MemberList/ +│ │ └── SubscriptionPlan/ +│ ├── pages/ # 页面组件 +│ │ ├── auth/ # 认证页面 +│ │ │ ├── Login.tsx +│ │ │ ├── Register.tsx +│ │ │ ├── ForgotPassword.tsx +│ │ │ └── ResetPassword.tsx +│ │ ├── workspace/ # 工作空间页面 +│ │ │ ├── List.tsx +│ │ │ ├── Detail.tsx +│ │ │ └── Members.tsx +│ │ ├── subscription/ # 订阅页面 +│ │ │ ├── Plans.tsx +│ │ │ ├── Upgrade.tsx +│ │ │ └── Billing.tsx +│ │ ├── admin/ # 管理后台 +│ │ │ ├── Dashboard.tsx +│ │ │ ├── Users.tsx +│ │ │ └── Analytics.tsx +│ │ └── profile/ # 个人中心 +│ │ ├── Settings.tsx +│ │ └── Account.tsx +│ ├── hooks/ # 自定义 Hooks +│ │ ├── useAuth.ts +│ │ ├── useWorkspace.ts +│ │ └── useSubscription.ts +│ ├── store/ # 状态管理 +│ │ ├── authStore.ts +│ │ ├── workspaceStore.ts +│ │ └── uiStore.ts +│ ├── types/ # TypeScript 类型定义 +│ │ ├── auth.ts +│ │ ├── workspace.ts +│ │ └── api.ts +│ ├── utils/ # 工具函数 +│ │ ├── request.ts # HTTP 请求封装 +│ │ ├── storage.ts # LocalStorage 封装 +│ │ ├── validator.ts # 表单验证 +│ │ └── format.ts # 格式化函数 +│ ├── router/ # 路由配置 +│ │ └── index.tsx +│ ├── styles/ # 全局样式 +│ │ ├── global.css +│ │ └── variables.css +│ ├── App.tsx +│ ├── main.tsx +│ └── vite-env.d.ts +├── public/ +│ └── assets/ +├── index.html +├── vite.config.ts +├── tsconfig.json +├── tailwind.config.js +└── package.json +``` + +--- + +## 🎨 设计规范 + +### 1. 色彩系统 + +**主色调:** +```css +--primary: #1890ff; /* 品牌蓝 */ +--primary-hover: #40a9ff; +--primary-active: #096dd9; + +--success: #52c41a; /* 成功绿 */ +--warning: #faad14; /* 警告黄 */ +--error: #ff4d4f; /* 错误红 */ +--info: #1890ff; /* 信息蓝 */ +``` + +**中性色:** +```css +--text-primary: #262626; +--text-secondary: #595959; +--text-disabled: #bfbfbf; + +--bg-primary: #ffffff; +--bg-secondary: #fafafa; +--bg-tertiary: #f5f5f5; + +--border: #d9d9d9; +--divider: #f0f0f0; +``` + +### 2. 字体规范 + +**字体家族:** +```css +font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', + 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', + sans-serif; +``` + +**字号:** +```css +--text-xs: 12px; /* 辅助文字 */ +--text-sm: 14px; /* 正文 */ +--text-base: 16px; /* 正文加重 */ +--text-lg: 18px; /* 小标题 */ +--text-xl: 20px; /* 标题 */ +--text-2xl: 24px; /* 大标题 */ +``` + +### 3. 间距系统 + +```css +--space-xs: 4px; +--space-sm: 8px; +--space-md: 16px; +--space-lg: 24px; +--space-xl: 32px; +--space-2xl: 48px; +``` + +### 4. 圆角 + +```css +--radius-sm: 2px; +--radius-md: 4px; +--radius-lg: 8px; +--radius-xl: 12px; +--radius-full: 9999px; +``` + +### 5. 阴影 + +```css +--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.08); +--shadow-md: 0 4px 8px rgba(0, 0, 0, 0.12); +--shadow-lg: 0 8px 16px rgba(0, 0, 0, 0.16); +``` + +--- + +## 🔐 认证流程设计 + +### 1. 注册流程 + +**页面:** `/register` + +**步骤:** +1. 用户填写邮箱、用户名、密码 +2. 前端验证(密码强度、邮箱格式) +3. 调用 `POST /api/v1/auth/register` +4. 显示"验证邮件已发送"提示 +5. 用户点击邮件链接 → 跳转到验证页面 +6. 自动登录 → 跳转到工作空间列表 + +**表单验证:** +```typescript +const registerSchema = z.object({ + email: z.string().email('请输入有效的邮箱地址'), + username: z.string() + .min(3, '用户名至少 3 个字符') + .max(20, '用户名最多 20 个字符') + .regex(/^[a-zA-Z0-9_]+$/, '用户名只能包含字母、数字和下划线'), + password: z.string() + .min(8, '密码至少 8 个字符') + .regex(/[A-Z]/, '密码必须包含大写字母') + .regex(/[a-z]/, '密码必须包含小写字母') + .regex(/[0-9]/, '密码必须包含数字'), + confirmPassword: z.string() +}).refine(data => data.password === data.confirmPassword, { + message: '两次密码输入不一致', + path: ['confirmPassword'], +}); +``` + +### 2. 登录流程 + +**页面:** `/login` + +**步骤:** +1. 用户输入邮箱和密码 +2. 调用 `POST /api/v1/auth/login` +3. 保存 token 到 localStorage +4. 设置 Axios 默认 Authorization header +5. 跳转到工作空间列表或上次访问页面 + +**Remember Me 功能:** +- 勾选时:token 保存 30 天 +- 不勾选:token 保存到 sessionStorage + +### 3. Token 管理 + +**自动刷新:** +```typescript +// axios 拦截器 +axios.interceptors.response.use( + response => response, + async error => { + if (error.response?.status === 401) { + // Token 过期,尝试刷新 + const refreshToken = storage.get('refresh_token'); + if (refreshToken) { + try { + const { access_token } = await refreshAccessToken(refreshToken); + storage.set('access_token', access_token); + // 重试原请求 + return axios(error.config); + } catch { + // 刷新失败,跳转登录 + router.push('/login'); + } + } + } + return Promise.reject(error); + } +); +``` + +--- + +## 🏢 工作空间管理设计 + +### 1. 工作空间列表 + +**页面:** `/workspaces` + +**布局:** +``` +┌─────────────────────────────────────────┐ +│ Header (用户头像、通知、设置) │ +├─────────────────────────────────────────┤ +│ ┌─────────────────────────────────┐ │ +│ │ 我的工作空间 [+ 创建] │ │ +│ ├─────────────────────────────────┤ │ +│ │ ┌──────┐ ┌──────┐ ┌──────┐ │ │ +│ │ │ WS 1 │ │ WS 2 │ │ WS 3 │ │ │ +│ │ │ Free │ │ Pro │ │ Free │ │ │ +│ │ │ 3人 │ │ 12人 │ │ 1人 │ │ │ +│ │ └──────┘ └──────┘ └──────┘ │ │ +│ └─────────────────────────────────┘ │ +└─────────────────────────────────────────┘ +``` + +**功能:** +- 显示所有工作空间 +- 显示订阅计划(Free/Pro/Enterprise) +- 显示成员数量 +- 快速切换工作空间 +- 创建新工作空间 + +### 2. 工作空间详情 + +**页面:** `/workspaces/:id` + +**标签页:** +- **概览** - 基本信息、配额使用情况 +- **成员** - 成员列表、邀请、权限管理 +- **订阅** - 当前计划、升级选项 +- **设置** - 工作空间名称、删除 + +**概览页示例:** +```typescript +interface WorkspaceOverview { + name: string; + plan: 'free' | 'pro' | 'enterprise'; + memberCount: number; + projectCount: number; + storageUsed: number; + storageLimit: number; + quotaStatus: 'normal' | 'warning' | 'critical' | 'exceeded'; +} +``` + +### 3. 成员管理 + +**功能:** +- 邀请成员(输入邮箱 + 选择角色) +- 成员列表(头像、姓名、邮箱、角色、加入时间) +- 修改角色(Owner/Admin/Member/Viewer) +- 移除成员 +- 待处理邀请列表 + +**权限矩阵显示:** +``` +┌────────────┬──────┬───────┬────────┬────────┐ +│ 操作 │ Owner│ Admin │ Member │ Viewer │ +├────────────┼──────┼───────┼────────┼────────┤ +│ 邀请成员 │ ✓ │ ✓ │ ✗ │ ✗ │ +│ 移除成员 │ ✓ │ ✓ │ ✗ │ ✗ │ +│ 创建项目 │ ✓ │ ✓ │ ✓ │ ✗ │ +│ 删除项目 │ ✓ │ ✓ │ 自己 │ ✗ │ +└────────────┴──────┴───────┴────────┴────────┘ +``` + +--- + +## 💳 订阅管理设计 + +### 1. 套餐选择页面 + +**页面:** `/subscription/plans` + +**布局:** +``` +┌───────────┬───────────┬───────────┐ +│ Free │ Pro │ Enterprise│ +├───────────┼───────────┼───────────┤ +│ ¥0/月 │ ¥99/月 │ ¥999/月 │ +│ 3 项目 │ 无限项目 │ 无限项目 │ +│ 10GB │ 100GB │ 1TB │ +│ 邮件支持 │ 优先支持 │ 专属支持 │ +│ │ │ 定制开发 │ +│ [当前] │ [升级] │ [联系] │ +└───────────┴───────────┴───────────┘ +``` + +**对比表格:** +```typescript +interface PlanFeature { + name: string; + free: boolean | string; + pro: boolean | string; + enterprise: boolean | string; +} + +const features: PlanFeature[] = [ + { name: '项目数量', free: '3', pro: '无限', enterprise: '无限' }, + { name: '存储空间', free: '10GB', pro: '100GB', enterprise: '1TB' }, + { name: '成员数量', free: '3', pro: '20', enterprise: '无限' }, + { name: 'API 调用', free: '1000/天', pro: '10000/天', enterprise: '无限' }, + { name: '技术支持', free: '邮件', pro: '邮件+工单', enterprise: '专属客服' }, +]; +``` + +### 2. 升级流程 + +**步骤:** +1. 选择套餐 → 确认升级 +2. 显示订单信息(价格、有效期) +3. 选择支付方式(支付宝/微信/信用卡) +4. 跳转支付页面 +5. 支付成功 → 自动升级 → 显示成功页面 + +### 3. 账单页面 + +**页面:** `/subscription/billing` + +**内容:** +- 当前订阅信息 +- 下次续费日期和金额 +- 历史账单列表 +- 发票申请入口 + +--- + +## 🎛️ Admin 后台设计 + +### 1. Dashboard + +**页面:** `/admin/dashboard` + +**仪表盘指标:** +``` +┌──────────┬──────────┬──────────┬──────────┐ +│ 总用户数 │ 付费用户 │ 月收入 │ 活跃用户 │ +│ 1,234 │ 156 │ ¥15,444 │ 892 │ +└──────────┴──────────┴──────────┴──────────┘ + +┌─────────────────────────────────────────┐ +│ 用户增长趋势图 │ +│ ┌────────────────────────────────────┐ │ +│ │ ╱╲ │ │ +│ │ ╱ ╲ ╱╲ │ │ +│ │ ╱╲ ╱ ╲ ╱ ╲ ╱╲ │ │ +│ │ ╱ ╲╱ ╲ ╱ ╲ ╱ ╲ │ │ +│ │ ╱ ╲╱ ╲╱ ╲ │ │ +│ └────────────────────────────────────┘ │ +└─────────────────────────────────────────┘ +``` + +### 2. 用户管理 + +**页面:** `/admin/users` + +**功能:** +- 用户列表(搜索、筛选、分页) +- 用户详情(基本信息、工作空间、订阅状态) +- 封禁/解封用户 +- 手动验证邮箱 +- 重置密码 + +### 3. 系统监控 + +**页面:** `/admin/monitoring` + +**监控指标:** +- API 响应时间 +- 数据库连接池状态 +- Redis 连接状态 +- 错误日志 +- 慢查询日志 + +--- + +## 📱 响应式设计 + +### 断点定义 + +```css +/* Mobile */ +@media (max-width: 640px) { } + +/* Tablet */ +@media (min-width: 641px) and (max-width: 1024px) { } + +/* Desktop */ +@media (min-width: 1025px) { } +``` + +### 移动端适配 + +**导航:** +- 桌面端:侧边栏 + 顶部栏 +- 移动端:底部导航栏 + 汉堡菜单 + +**表格:** +- 桌面端:完整表格 +- 移动端:卡片列表 + +**表单:** +- 全宽输入框 +- 大号按钮(易于点击) + +--- + +## 🧪 测试策略 + +### 1. 单元测试 + +**工具:** Vitest + Testing Library + +**覆盖范围:** +- 工具函数(100%) +- Hooks(80%+) +- 组件(核心组件 80%+) + +### 2. E2E 测试 + +**工具:** Playwright + +**关键流程:** +- 用户注册 → 邮箱验证 → 登录 +- 创建工作空间 → 邀请成员 +- 升级订阅 + +### 3. 可访问性测试 + +- 键盘导航支持 +- ARIA 标签 +- 颜色对比度(WCAG AA) + +--- + +## 🚀 性能优化 + +### 1. 代码分割 + +```typescript +// 路由懒加载 +const Login = lazy(() => import('./pages/auth/Login')); +const Dashboard = lazy(() => import('./pages/admin/Dashboard')); +``` + +### 2. 图片优化 + +- 使用 WebP 格式 +- 懒加载图片 +- 响应式图片 + +### 3. 缓存策略 + +**React Query 配置:** +```typescript +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + staleTime: 5 * 60 * 1000, // 5 分钟 + cacheTime: 10 * 60 * 1000, // 10 分钟 + refetchOnWindowFocus: false, + }, + }, +}); +``` + +--- + +## 📅 开发排期 + +### Week 1-2: 基础搭建 +- [ ] 项目初始化(Vite + React + TypeScript) +- [ ] 安装配置依赖(Ant Design, React Router, etc.) +- [ ] 搭建基础布局(Header, Sidebar, Footer) +- [ ] API 客户端封装 +- [ ] 路由配置 + +### Week 3: 认证页面 +- [ ] 登录页面 +- [ ] 注册页面 +- [ ] 忘记密码页面 +- [ ] 邮箱验证页面 +- [ ] Token 管理 + +### Week 4: 工作空间管理 +- [ ] 工作空间列表页面 +- [ ] 工作空间详情页面 +- [ ] 成员管理页面 +- [ ] 邀请成员功能 + +### Week 5: 订阅管理 +- [ ] 套餐选择页面 +- [ ] 升级流程 +- [ ] 账单页面 +- [ ] 配额展示 + +### Week 6: Admin 后台 +- [ ] Dashboard 仪表盘 +- [ ] 用户管理 +- [ ] 系统监控 + +### Week 7: 个人中心 +- [ ] 个人设置页面 +- [ ] 账号安全 +- [ ] 通知设置 + +### Week 8: 测试和优化 +- [ ] E2E 测试 +- [ ] 性能优化 +- [ ] 可访问性优化 +- [ ] Bug 修复 + +--- + +## 🎯 成功指标 + +- [ ] 所有页面加载时间 < 2s +- [ ] Lighthouse 性能分数 > 90 +- [ ] 核心流程 E2E 测试覆盖率 100% +- [ ] 移动端体验良好(无横向滚动) +- [ ] 无 Console 错误和警告 + +--- + +## 📝 备注 + +- 优先保证桌面端体验,移动端作为补充 +- UI 设计遵循 Ant Design 规范,保持一致性 +- 所有文字支持国际化(i18n)准备 +- 表单验证使用 Zod,前后端类型一致 + +--- + +**老大确认后,我就开始 Phase 6 的开发工作!** 🦐💪