# 异常中心页面优化 — 设计规格 > 创建日期: 2026-05-07 > 状态: 设计中 ## 概述 对 MusicWorkshop 异常中心页面(`ExceptionPage.jsx`)进行全面的视觉、交互、流程和代码结构优化。 ### 核心痛点 - 页面不够美观(首要痛点) - 操作太繁琐 - 向导流程太长(保留 5 步但优化界面) - 代码维护困难(800+ 行单文件) ## 设计决策 | 维度 | 决策 | |------|------| | 视觉风格 | 深色专业(Dark Professional)— 暗色主题 + 靛蓝高亮 + 微弱边框 | | 页面布局 | 向导聚焦布局(Wizard Focus)— 顶部步骤条 + 左侧队列 + 右侧操作区 | | 向导步骤 | 保持 5 步(确保入库数据精准性) | | 代码重构 | 按功能区拆分组件 + 提取自定义 hooks | | 后端改动 | 无需改动(API 和数据结构不变) | ## 视觉设计 ### 配色方案 ``` 背景: #0f172a (slate-900) — 主背景 卡片: #1e293b (slate-800) — 面板/卡片背景 边框: #334155 (slate-700) — 微弱的组件边框 文字: #e2e8f0 (slate-200) — 主文字 次要: #94a3b8 (slate-400) — 辅助文字/标签 高亮: #6366f1 (indigo-500) — 主要操作/选中状态 成功: #22c55e (green-500) — 完成/入库操作 警告: #f59e0b (amber-500) — 需注意的异常 错误: #ef4444 (red-500) — 失败状态 ``` ### 异常类型标签色 ``` 元数据缺失: amber (amber-700 背景, amber-400 文字) 匹配失败: red (red-900 背景, red-400 文字) 匹配分过低: amber 转码失败: red 文件重复: slate 入库失败: red ``` ### 排版 - 字体: 继承项目现有 Tailwind 配置(系统字体栈) - 步骤标题: text-lg font-semibold - 歌曲名称: text-sm font-medium - 元数据标签: text-xs text-slate-400 - 按钮: text-sm font-medium rounded-lg ## 页面布局 ``` ┌──────────────────────────────────────────────────┐ │ 🏠 异常中心 [高级视图] │ ├──────────────────────────────────────────────────┤ │ ①选择歌曲 ── ②试听确认 ── ③推荐匹配 ── ④手动编│ │ 辑 ── ⑤入库确认 │ ├────────────┬─────────────────────────────────────┤ │ 队列 (12) │ 🎵 01 - 夜曲.mp3 │ │ │ ┌─────────────────────────────────┐│ │ ▸ 01-夜曲 │ │ 匹配候选: ││ │ track_02 │ │ ▸ 夜曲 / 周杰伦 · 十一月的萧邦 ││ │ unknown │ │ 95% · MusicBrainz ││ │ │ │ Nocturne / Jay Chou ││ │ │ │ 78% · Spotify ││ │ │ └─────────────────────────────────┘│ │ │ [确认选择] [手动编辑] [跳过 →] │ ├────────────┴─────────────────────────────────────┤ │ ⚡ 修复任务: 3/12 完成 · running │ └──────────────────────────────────────────────────┘ ``` ## 组件架构 ``` src/ ├── pages/ │ └── ExceptionPage.jsx # 页面容器(路由入口 + 顶层状态协调) ├── components/exceptions/ │ ├── ExceptionStatsBar.jsx # 顶部统计概览条 │ ├── ExceptionTypeNav.jsx # 异常类型筛选标签 │ ├── ExceptionWizard.jsx # 5步向导主控制器 │ ├── ExceptionListView.jsx # 高级列表视图(备用,对应高级模式) │ ├── steps/ │ │ ├── StepSelect.jsx # 步骤1:选择歌曲 │ │ ├── StepListen.jsx # 步骤2:试听确认 │ │ ├── StepMatch.jsx # 步骤3:推荐匹配 │ │ ├── StepEdit.jsx # 步骤4:手动编辑 │ │ └── StepConfirm.jsx # 步骤5:入库确认 │ ├── RepairTaskPanel.jsx # 修复任务实时状态面板 │ └── ActionPreviewModal.jsx # 操作预览/确认弹窗 ├── hooks/ │ ├── useExceptionSummary.js # 异常概览数据获取 │ ├── useExceptionList.js # 异常列表(分页/筛选/队列) │ ├── useExceptionDetail.js # 单条异常详情 │ ├── useRepairTask.js # WebSocket 修复任务跟踪 │ └── useWizardState.js # 向导步骤状态管理 ``` ### 组件职责 **ExceptionPage** — 页面容器,轻量级 - 仅持有顶层路由和视图模式切换(wizard / advanced) - 通过 props 传递共享状态 - 不包含任何步骤逻辑或 UI 细节 **ExceptionStatsBar** — 顶部统计概览 - Props: summary (总数/分类统计) - 显示:开放中 / 处理中 / 已解决 三个统计卡片 - 深色主题:渐变靛蓝背景卡片 **ExceptionTypeNav** — 类型筛选标签 - Props: activeFilter, onFilterChange, counts - 水平滚动的胶囊标签,显示各类型数量 - 深色主题:选中靛蓝填充,未选中 slate 边框 **ExceptionWizard** — 5步向导控制器 - 管理 5 个步骤的切换(由 useWizardState hook 驱动) - 渲染当前步骤组件,传递必要的 props - 步骤条 UI:圆形步骤编号 + 连接线,已完成绿色/当前靛蓝/待完成 slate **步骤组件 (StepSelect, StepListen, StepMatch, StepEdit, StepConfirm)** - 每个步骤是独立组件 - 通过 props 接收:detailRecord, action, params, previewState - 通过回调通知:onActionChange, onParamsChange, onPreview, onExecute **RepairTaskPanel** — 修复任务面板 - 显示当前修复任务的进度 - WebSocket 实时日志流 - 可折叠设计 **ActionPreviewModal** — 操作预览弹窗 - 显示批量操作的预览结果 - 风险等级标识(低/中/高) - 确认/取消操作 ### 自定义 Hooks **useExceptionSummary** - 封装 fetchExceptionSummary API 调用 - 返回 { summary, error, refresh } **useExceptionList** - 封装 fetchExceptionItems API(分页/筛选/队列模式) - 管理 items, total, page, filter 状态 - 返回 { items, total, page, filter, setFilter, setPage, refresh, loading, error } **useExceptionDetail** - 封装 fetchExceptionItem API - 由 selectedExceptionId 驱动自动获取 - 返回 { detail, loading, error, refresh } **useRepairTask** - 封装 WebSocket 连接 + repair task 状态 - 管理 repairTask, repairLogs - 自动处理重连 **useWizardState** - 管理:wizardStep, selectedAction, actionParams, previewState, executeError - 步骤切换逻辑:inferDefaultAction, buildDefaultParams - 返回 { wizardStep, setWizardStep, selectedAction, setSelectedAction, ... } ### 数据流 ``` ExceptionPage (顶层) │ ├─ useExceptionSummary() ──→ ExceptionStatsBar ├─ useExceptionList() ──→ 左侧歌曲队列 ├─ useExceptionDetail() ──→ 当前选中歌曲详情 ├─ useWizardState() ──→ ExceptionWizard → 5 步骤组件 └─ useRepairTask() ──→ RepairTaskPanel ``` 数据通过 props 向下流动,回调通过 props 向上通知。不使用 Context(避免不必要的心智负担)。 ## 交互优化 ### 平滑过渡 - 步骤切换:CSS transition 淡入淡出(150ms) - 列表项选择:背景色过渡(150ms) - 弹窗:fade + scale 动画(200ms) ### 微交互 - 悬停状态:列表项 hover 时背景微亮(slate-700) - 操作按钮:hover 时颜色加深 10% - 统计卡片:hover 时轻微上浮 (translateY -2px) - 加载状态:骨架屏替代纯 spinner ### 键盘导航 - ← → 键切换向导步骤 - ↑ ↓ 键在歌曲队列中导航 - Enter 确认当前操作 - Escape 关闭弹窗 ## 5步向导流程(保持现有逻辑) | 步骤 | 名称 | 功能 | 可操作 | |------|------|------|--------| | 1 | 选择歌曲 | 从异常队列选择歌曲 | 点击选中 | | 2 | 试听确认 | 播放音频确认文件正确 | 播放/暂停 | | 3 | 推荐匹配 | 查看元数据候选列表 | 选择候选/确认 | | 4 | 手动编辑 | 编辑元数据字段 | 修改字段值 | | 5 | 入库确认 | 确认目标路径并入库 | 预览/执行 | 步骤可自由前进后退(已确认的操作不丢失)。 ## 兼容性 ### 保留功能 - 高级列表视图模式(通过右上角切换入口) - 批量操作(在高级列表模式下) - 所有现有 API 端点不变 - 所有现有异常类型和操作动作 ### 浏览器支持 - Chrome, Firefox, Safari, Edge 最近 2 个主版本 - 不需要 IE 支持 ## 非目标(不在本次范围) - 后端 API 修改 - 新增异常类型 - 新增修复操作类型 - 国际化(i18n) - 移动端适配(保持桌面端优先,响应式布局兜底) ## 实现顺序 1. **Phase 1**: 提取自定义 hooks(纯逻辑层,不改变 UI) 2. **Phase 2**: 拆分步骤组件(保持原有 5 步逻辑) 3. **Phase 3**: 重构 ExceptionPage 容器(集成 hooks + 组件) 4. **Phase 4**: 应用深色专业主题样式 5. **Phase 5**: 添加过渡动画和微交互 6. **Phase 6**: 更新高级列表视图样式 7. **Phase 7**: 测试与验证 每个 Phase 完成后进行功能验证,确保不引入回归。