e62a5d5e39
CI/CD Pipeline / Validate Code Quality And Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Lint (push) Has been cancelled
Deploy / Deploy Staging (push) Has been cancelled
Deploy / Build Production Runtime Images (push) Has been cancelled
Deploy / Deploy Production (push) Has been cancelled
Deploy / Production Browser E2E (push) Has been cancelled
- 分析现有项目制路由结构和页面文件 - 设计扁平化新路由(去掉 Workspace/Project 层级) - 列出页面改造/删除/新增清单 - API 路由变更映射(前后端对照) - 移动端响应式策略 - 实施计划与风险评估 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
21 KiB
21 KiB
小虾 SaaS 前端页面重构改造计划
版本:v1.0 | 日期:2026-06-28 | 作者:前端编码
状态:规划阶段,暂未改动代码
一、背景与目标
1.1 背景
产品从「项目制」改为「扁平化」结构,去掉 Workspace(工作空间)和 Project(项目)两层嵌套。用户不再需要「先选工作空间 → 再选项目 → 再进入功能页」,而是直接面对各功能模块。
1.2 目标
- 去除 Workspace / Project 层级,所有资源归用户直接所有
- 页面路由扁平化,一级路由直达各功能
- 保留并适配现有功能:素材库、标题库、配音库、模板库、一键生成、生成记录、成品库、订阅管理
- 兼顾移动端响应式体验
二、现有代码结构分析
2.1 当前路由结构
/ → 重定向到 /projects
/login → 登录
/register → 注册
/forgot-password → 忘记密码
/reset-password → 重置密码
/projects → 工作空间/项目列表(WorkspaceList)
/projects/:id/assets → 项目素材库(ProjectAssets)
/projects/:id/titles → 项目标题库(ProjectTitles)
/projects/:id/voices → 项目配音库(ProjectVoices)
/projects/:id/generation → 项目视频剪辑(ProjectGeneration)
/projects/:id/tasks → 项目任务列表(ProjectTasks)
/projects/:id/results → 项目成片库(ProjectResults)
/subscription → 订阅套餐(Plans)
/subscription/upgrade → 升级订阅(UpgradeSubscription)
/subscription/billing → 账单管理(Billing)
/admin → 管理后台(AdminComingSoon)
/admin/users → 用户管理
/admin/analytics → 数据分析
/admin/monitor → 监控面板
/admin/logs → 日志查看
/profile → 个人设置(Settings)
2.2 当前页面文件清单
| 文件路径 | 行数 | 功能 | 改造命运 |
|---|---|---|---|
pages/workspace/WorkspaceList.tsx |
99 | 项目列表 + 工作空间选择 | 删除 |
pages/workspace/ProjectAssets.tsx |
93 | 项目内素材管理 | 改造 → 全局素材库 |
pages/workspace/ProjectTitles.tsx |
110 | 项目内标题管理 | 改造 → 全局标题库 |
pages/workspace/ProjectVoices.tsx |
52 | 项目内配音管理 | 改造 → 全局配音库 |
pages/workspace/ProjectGeneration.tsx |
423 | 项目内视频生成(核心页面) | 改造 → 一键生成 |
pages/workspace/ProjectTasks.tsx |
131 | 项目内任务列表 | 改造 → 生成记录 |
pages/workspace/ProjectResults.tsx |
51 | 项目内成片展示 | 改造 → 成品库 |
pages/subscription/Plans.tsx |
— | 订阅套餐 | 保留 |
pages/subscription/UpgradeSubscription.tsx |
— | 升级订阅 | 保留 |
pages/subscription/Billing.tsx |
— | 账单管理 | 保留 |
pages/admin/AdminComingSoon.tsx |
— | 管理后台占位 | 保留 |
pages/auth/Login.tsx |
— | 登录 | 保留 |
pages/auth/Register.tsx |
— | 注册 | 保留 |
pages/auth/ForgotPassword.tsx |
— | 忘记密码 | 保留 |
pages/auth/ResetPassword.tsx |
— | 重置密码 | 保留 |
pages/profile/Settings.tsx |
— | 个人设置 | 保留 |
2.3 当前 API 层分析
| API 文件 | 接口前缀 | 改造影响 |
|---|---|---|
api/workspace.ts |
/workspaces |
删除 — 不再需要工作空间 CRUD |
api/assets.ts |
/projects/:id/..., /asset-libraries, /assets, /upload |
改造 — 去掉 project_id 参数 |
api/editPlans.ts |
/projects/:id/edit-plans/... |
改造 — 去掉 projectId 前缀 |
api/tasks.ts |
/projects/:id/tasks, /tasks/:type/:id/retry |
改造 — 去掉 projectId |
api/auth.ts |
/auth/... |
不变 |
api/client.ts |
Axios 实例 | 不变 |
2.4 关键组件与 Hook
| 文件 | 功能 | 改造命运 |
|---|---|---|
components/layout/MainLayout.tsx |
布局壳(Outlet) | 保留,微调 |
components/layout/Header.tsx |
顶部导航,动态渲染项目子导航 | 改造 — 去掉 projectId 逻辑,改为固定一级导航 |
hooks/useWorkspace.ts |
工作空间状态管理 | 删除 |
hooks/useAuth.ts |
认证状态管理 | 保留 |
store/authStore.ts |
认证 Zustand store | 保留 |
三、新路由结构设计
3.1 新路由表
/ → 重定向到 /assets(首页即素材库)
/login → 登录(不变)
/register → 注册(不变)
/forgot-password → 忘记密码(不变)
/reset-password → 重置密码(不变)
# ── 以下均在 MainLayout (ProtectedRoute) 内 ──
/assets → 素材库
/titles → 标题库
/voices → 配音库
/templates → 模板库(新增)
/generate → 一键生成
/history → 生成记录
/products → 成品库
/subscription → 订阅套餐(不变)
/subscription/upgrade → 升级订阅(不变)
/subscription/billing → 账单管理(不变)
/admin → 管理后台(不变)
/admin/users → 用户管理(不变)
/admin/analytics → 数据分析(不变)
/admin/monitor → 监控面板(不变)
/admin/logs → 日志查看(不变)
/profile → 个人设置(不变)
3.2 路由设计说明
| 新路由 | 对应旧路由 | 说明 |
|---|---|---|
/assets |
/projects/:id/assets |
去掉 projectId,展示用户所有素材 |
/titles |
/projects/:id/titles |
去掉 projectId,展示用户所有标题 |
/voices |
/projects/:id/voices |
去掉 projectId,展示用户所有配音 |
/templates |
无(新增) | 模板库,从 ProjectGeneration 的模板选择部分独立出来 |
/generate |
/projects/:id/generation |
去掉 projectId,一键生成入口 |
/history |
/projects/:id/tasks |
去掉 projectId,展示用户所有生成任务 |
/products |
/projects/:id/results |
去掉 projectId,展示用户所有成品 |
/subscription |
/subscription |
不变 |
/profile |
/profile |
不变 |
/admin/* |
/admin/* |
不变 |
3.3 默认首页
首页 / 重定向到 /assets(素材库),因为素材是视频制作流程的起点,用户最常访问。
四、页面改造详细方案
4.1 删除页面(1 个)
WorkspaceList.tsx → 删除
- 原因:不再有工作空间/项目概念
- 相关功能(如「创建项目」)迁移到素材库页面的「上传素材」流程中
4.2 改造页面(6 个)
ProjectAssets.tsx → pages/assets/AssetLibrary.tsx
- 重命名 + 移动到
pages/assets/目录 - 去除
projectId参数和路由依赖 - 改造 API 调用:
getAssetLibraries(projectId)→getAssetLibraries()(后端需配合去掉 project_id) - 页面内「新建素材库」表单去掉 project_id 字段
- 上传流程简化:直接上传到用户空间,不再需要先选项目再选素材库
ProjectTitles.tsx → pages/titles/TitleLibrary.tsx
- 重命名 + 移动到
pages/titles/目录 - 去除 projectId 相关逻辑
- API 调用适配(后端需提供无 projectId 的标题列表接口)
ProjectVoices.tsx → pages/voices/VoiceLibrary.tsx
- 重命名 + 移动到
pages/voices/目录 - 去除 projectId 相关逻辑
- API 调用适配
ProjectGeneration.tsx → pages/generate/GeneratePage.tsx
- 重命名 + 移动到
pages/generate/目录 - 这是最复杂的页面(423 行),包含:
- 模板选择 → 部分拆到
/templates模板库 - 素材库选择 → 改为全局素材库下拉
- 标题选择 → 改为全局标题库下拉
- 配音选择 → 改为全局配音库下拉
- 编排计划生成/编辑 → 保留,去掉 projectId
- 生成任务提交 → 保留,去掉 projectId
- 模板选择 → 部分拆到
- 拆分:模板浏览部分独立为
pages/templates/TemplateLibrary.tsx
ProjectTasks.tsx → pages/history/TaskHistory.tsx
- 重命名 + 移动到
pages/history/目录 - 去除 projectId 过滤
- 展示用户所有生成任务(后端需支持按 user_id 查询)
ProjectResults.tsx → pages/products/ProductLibrary.tsx
- 重命名 + 移动到
pages/products/目录 - 去除 projectId 过滤
- 展示用户所有成品视频
4.3 新增页面(1 个)
pages/templates/TemplateLibrary.tsx(新增)
- 模板库,展示所有可用编辑模板
- 功能从 ProjectGeneration.tsx 的模板选择部分抽取
- 支持模板预览、收藏、按类型筛选
- API:需后端提供
/templates全局模板列表接口
4.4 保留不变的页面(11 个)
| 页面 | 说明 |
|---|---|
pages/auth/Login.tsx |
登录 |
pages/auth/Register.tsx |
注册 |
pages/auth/ForgotPassword.tsx |
忘记密码 |
pages/auth/ResetPassword.tsx |
重置密码 |
pages/subscription/Plans.tsx |
订阅套餐 |
pages/subscription/UpgradeSubscription.tsx |
升级订阅 |
pages/subscription/Billing.tsx |
账单管理 |
pages/admin/AdminComingSoon.tsx |
管理后台占位 |
pages/profile/Settings.tsx |
个人设置 |
五、组件与 Hook 改造
5.1 Header.tsx 改造
现状:Header 通过 extractProjectId(pathname) 解析 URL 中的 projectId,动态渲染项目子导航。
改造方案:
- 删除
extractProjectId函数 - 导航项改为固定一级菜单:
const navItems = [
{ key: 'assets', label: '素材库', path: '/assets' },
{ key: 'titles', label: '标题库', path: '/titles' },
{ key: 'voices', label: '配音库', path: '/voices' },
{ key: 'templates', label: '模板库', path: '/templates' },
{ key: 'generate', label: '一键生成', path: '/generate' },
{ key: 'history', label: '生成记录', path: '/history' },
{ key: 'products', label: '成品库', path: '/products' },
{ key: 'subscription', label: '订阅', path: '/subscription' },
];
- 移动端下导航收起为汉堡菜单(Drawer)
5.2 删除 Hook
hooks/useWorkspace.ts— 删除,不再需要工作空间状态
5.3 删除 API 文件
api/workspace.ts— 删除,不再需要工作空间 CRUD API
5.4 改造 API 文件
api/assets.ts
- export const getAssetLibraries = async (projectId: string) => {
- const response = await apiClient.get('/asset-libraries', { params: { project_id: projectId } });
+ export const getAssetLibraries = async () => {
+ const response = await apiClient.get('/asset-libraries');
return response.data.items;
};
- export const createAssetLibrary = async (data: { project_id: string; name: string; kind: '...' }) => {
+ export const createAssetLibrary = async (data: { name: string; kind: '...' }) => {
...
};
- export const uploadAssetDirect = async (data: { file: File; project_id: string; library_id: string }) => {
+ export const uploadAssetDirect = async (data: { file: File; library_id: string }) => {
...
};
api/editPlans.ts
- export const getEditTemplates = async (projectId: string) => {
- const response = await apiClient.get(`/projects/${projectId}/edit-plans/templates`);
+ export const getEditTemplates = async () => {
+ const response = await apiClient.get('/templates');
return response.data;
};
- export const createEditPlan = async ({ projectId, data }) => {
- const response = await apiClient.post(`/projects/${projectId}/edit-plans`, data);
+ export const createEditPlan = async (data: { asset_library_id: string; template_id?: string; title_id?: string }) => {
+ const response = await apiClient.post('/edit-plans', data);
return response.data;
};
// 同理:getEditPlans, getEditPlan, autoGenerateEditPlan, deleteEditPlan, updateEditPlan
// 全部去掉 projectId 参数
api/tasks.ts
- export const getProjectTasks = async (projectId: string) => {
- const response = await apiClient.get(`/projects/${projectId}/tasks`);
+ export const getUserTasks = async () => {
+ const response = await apiClient.get('/tasks');
return response.data.items;
};
六、新目录结构
src/
├── api/
│ ├── assets.ts # 改造:去掉 project_id
│ ├── auth.ts # 不变
│ ├── client.ts # 不变
│ ├── editPlans.ts # 改造:去掉 projectId
│ ├── tasks.ts # 改造:去掉 projectId
│ └── templates.ts # 新增:模板 API
│ ✗ workspace.ts # 删除
├── components/
│ └── layout/
│ ├── Header.tsx # 改造:固定一级导航
│ └── MainLayout.tsx # 微调
├── hooks/
│ ├── useAuth.ts # 不变
│ ✗ useWorkspace.ts # 删除
├── pages/
│ ├── auth/ # 不变
│ ├── assets/ # 新增目录
│ │ └── AssetLibrary.tsx # 改造自 ProjectAssets
│ ├── titles/ # 新增目录
│ │ └── TitleLibrary.tsx # 改造自 ProjectTitles
│ ├── voices/ # 新增目录
│ │ └── VoiceLibrary.tsx # 改造自 ProjectVoices
│ ├── templates/ # 新增目录
│ │ └── TemplateLibrary.tsx # 新增
│ ├── generate/ # 新增目录
│ │ └── GeneratePage.tsx # 改造自 ProjectGeneration
│ ├── history/ # 新增目录
│ │ └── TaskHistory.tsx # 改造自 ProjectTasks
│ ├── products/ # 新增目录
│ │ └── ProductLibrary.tsx # 改造自 ProjectResults
│ ├── subscription/ # 不变
│ ├── admin/ # 不变
│ └── profile/ # 不变
├── store/
│ └── authStore.ts # 不变
├── router/
│ └── index.tsx # 改造:全新路由表
└── test/
└── ... # 更新测试用例
七、API 路由变更映射(前后端对照)
需后端同步改造,以下为建议的新 API 路由
| 旧 API | 新 API | 说明 |
|---|---|---|
GET /workspaces |
— | 删除 |
GET /workspaces/:id |
— | 删除 |
POST /workspaces |
— | 删除 |
GET /workspaces/:id/members |
— | 删除 |
POST /workspaces/:id/members/invite |
— | 删除 |
DELETE /workspaces/:id/members/:mid |
— | 删除 |
PATCH /workspaces/:id/members/:mid/role |
— | 删除 |
GET /asset-libraries?project_id=X |
GET /asset-libraries |
按当前用户查询 |
POST /asset-libraries {project_id,...} |
POST /asset-libraries {name, kind} |
去掉 project_id |
GET /assets?library_id=X |
GET /assets?library_id=X |
不变 |
POST /upload |
POST /upload |
不变 |
POST /upload/direct/prepare {project_id,...} |
POST /upload/direct/prepare {library_id,...} |
去掉 project_id |
POST /upload/direct/complete {project_id,...} |
POST /upload/direct/complete {library_id,...} |
去掉 project_id |
GET /projects/:id/asset-diagnosis |
GET /asset-diagnosis |
按当前用户查询 |
POST /classification-jobs {project_id,...} |
POST /classification-jobs {asset_id} |
去掉 project_id |
GET /projects/:id/edit-plans/templates |
GET /templates |
全局模板列表 |
GET /projects/:id/edit-plans |
GET /edit-plans |
按当前用户查询 |
POST /projects/:id/edit-plans |
POST /edit-plans |
去掉 projectId |
GET /projects/:id/edit-plans/:pid |
GET /edit-plans/:pid |
去掉 projectId |
POST /projects/:id/edit-plans/auto-generate |
POST /edit-plans/auto-generate |
去掉 projectId |
PATCH /projects/:id/edit-plans/:pid |
PATCH /edit-plans/:pid |
去掉 projectId |
DELETE /projects/:id/edit-plans/:pid |
DELETE /edit-plans/:pid |
去掉 projectId |
GET /projects/:id/tasks |
GET /tasks |
按当前用户查询 |
POST /tasks/:type/:id/retry |
POST /tasks/:type/:id/retry |
不变 |
八、移动端响应式策略
8.1 现状
- 当前使用 Ant Design v5,内置 Grid 系统和响应式工具
- Header 导航在移动端无适配(水平排列,小屏会溢出)
- 页面内容区基本为单列布局,移动端兼容性尚可
8.2 改造方案
导航层
- 顶部导航(Header):
- 桌面端(≥768px):水平导航,全部菜单项平铺
- 移动端(<768px):隐藏导航文字,显示汉堡菜单图标,点击展开侧边 Drawer
- Logo 始终可见
- 底部 Tab 栏(可选,Phase 2):
- 移动端增加底部固定 Tab 栏,包含 5 个核心入口:素材库、一键生成、生成记录、成品库、我的
- 使用 Ant Design
TabBar或自定义实现
内容层
- 素材库:
- 桌面端:卡片网格(4 列),支持拖拽上传
- 移动端:单列卡片,底部固定「上传」按钮,调用手机相机/相册
- 标题库 / 配音库:
- 桌面端:表格视图
- 移动端:列表视图,卡片样式
- 一键生成:
- 桌面端:左右分栏(左侧配置,右侧预览)
- 移动端:步骤条(Steps)纵向流程,分步填写
- 生成记录 / 成品库:
- 桌面端:表格 + 视频预览弹窗
- 移动端:卡片列表 + 全屏视频播放器
- 订阅管理:
- 桌面端:套餐对比表格
- 移动端:卡片式套餐展示,纵向排列
技术实现
- 使用 CSS 媒体查询 + Ant Design
useBreakpointHook - 关键断点:
xs: 480px,sm: 576px,md: 768px,lg: 992px,xl: 1200px - 图片/视频缩略图使用响应式
srcset或统一使用较小尺寸 + CSS 缩放 - 上传组件使用 Ant Design
Upload.Dragger(桌面)和自定义移动端上传按钮
8.3 分阶段实施
- Phase 1(本次重构):Header 响应式改造 + 页面基本移动端适配
- Phase 2(后续):底部 Tab 栏 + 移动端专属交互优化(手势、滑动等)
九、实施计划与优先级
Phase 1:基础重构(本次核心工作)
| 序号 | 任务 | 涉及文件 | 预估工时 |
|---|---|---|---|
| 1 | 路由表重构 | router/index.tsx |
0.5h |
| 2 | Header 导航改造 | Header.tsx |
1h |
| 3 | 素材库页面改造 | ProjectAssets → AssetLibrary |
2h |
| 4 | 标题库页面改造 | ProjectTitles → TitleLibrary |
1h |
| 5 | 配音库页面改造 | ProjectVoices → VoiceLibrary |
1h |
| 6 | 一键生成页面改造 | ProjectGeneration → GeneratePage |
4h |
| 7 | 生成记录页面改造 | ProjectTasks → TaskHistory |
1h |
| 8 | 成品库页面改造 | ProjectResults → ProductLibrary |
1h |
| 9 | API 层改造 | assets.ts, editPlans.ts, tasks.ts |
2h |
| 10 | 删除废弃代码 | workspace.ts, useWorkspace.ts, WorkspaceList.tsx |
0.5h |
| 11 | 模板库页面新建 | TemplateLibrary.tsx, templates.ts |
2h |
| 12 | 更新测试用例 | test/ 目录 |
2h |
合计:约 18h
Phase 2:移动端优化(后续)
- 底部 Tab 栏
- 移动端上传优化
- 手势交互
Phase 3:功能增强(后续)
- AI 配音集成
- 高级时间线编辑器
- 模板市场
十、风险与注意事项
10.1 前后端协同
- API 路由变更需要后端同步改造,建议前后端并行开发
- 过渡期可保留旧 API 兼容层(后端同时支持带/不带 projectId 的接口)
- 前端可通过 feature flag 切换新旧路由
10.2 数据迁移
- 后端需将现有
project_id关联的数据迁移到user_id直接关联 - 素材、标题、配音、编辑计划、任务、成品均需迁移
- 建议后端提供迁移脚本,前端无需关心
10.3 向后兼容
- 旧路由
/projects/:id/*设置 301 重定向到新路由(前端Navigate组件实现) - 重定向逻辑保留 1-2 个版本后移除
10.4 测试覆盖
- 现有
WorkspaceList.test.tsx需删除或重写 - 每个改造页面需更新对应的 E2E / 集成测试
- 路由跳转测试需全面更新
附录 A:新旧路由快速对照表
| 旧路由 | 新路由 | 页面 |
|---|---|---|
/projects |
/assets |
素材库(原项目列表→素材库首页) |
/projects/:id/assets |
/assets |
素材库 |
/projects/:id/titles |
/titles |
标题库 |
/projects/:id/voices |
/voices |
配音库 |
/projects/:id/generation |
/generate |
一键生成 |
/projects/:id/tasks |
/history |
生成记录 |
/projects/:id/results |
/products |
成品库 |
| — | /templates |
模板库(新增) |
/subscription |
/subscription |
订阅管理(不变) |
/profile |
/profile |
个人设置(不变) |
/admin/* |
/admin/* |
管理后台(不变) |
本文档为规划阶段产出,待评审通过后进入实施阶段。