# 设计文档 - UI修复和功能还原 ## 概述 本设计文档描述了由壹点3D素材平台UI修复和功能还原的技术实现方案。系统需要修复当前版本中存在的UI问题和功能缺失,包括筛选条件显示、榜单面板交互、页面滚动管理、头部菜单导航、网络诊断工具、素材卡片样式和素材详情页面一致性等方面。 ## 架构 ### 整体架构 系统采用Next.js 13+ App Router架构,使用React Server Components和Client Components混合模式。UI修复主要涉及以下层次: 1. **页面层** (`app/page.tsx`): 首页主逻辑,包含筛选状态管理和素材展示 2. **组件层** (`components/`): 可复用的UI组件,如Header、RankingPanel、NetworkDiagnoseModal等 3. **状态管理层**: 使用React Hooks进行本地状态管理,使用localStorage/sessionStorage进行持久化 4. **样式层**: 使用Tailwind CSS进行样式管理 ### 关键设计决策 1. **筛选条件显示**: Material_Type不应出现在"当前筛选"区域,因为它是页面的主要分类维度,不是筛选条件 2. **状态持久化**: 使用localStorage保存用户偏好(如榜单面板状态和位置),使用sessionStorage保存临时状态(如滚动位置) 3. **拖拽实现**: 使用原生DOM事件实现拖拽,避免引入额外的库 4. **滚动管理**: 移除强制滚动位置恢复逻辑,允许浏览器自然处理滚动 ## 组件和接口 ### 1. 首页筛选组件 (app/page.tsx) #### 状态接口 ```typescript interface FilterState { searchKeyword: string selectedCategory: string selectedScene: string selectedMaterialType: string // 不显示在"当前筛选"中 selectedPlatform: string selectedProductCategory: string selectedMonth: string } ``` #### 关键函数 - `renderActiveFilters()`: 渲染"当前筛选"区域,排除Material_Type - `clearFilter(filterName: string)`: 清除单个筛选条件 - `clearAllFilters()`: 清除所有筛选条件 ### 2. 榜单面板组件 (components/RankingPanel.tsx) #### 状态接口 ```typescript interface RankingPanelState { isVisible: boolean position: { x: number; y: number } isDragging: boolean } ``` #### 关键函数 - `handleDragStart(e: MouseEvent)`: 开始拖拽 - `handleDrag(e: MouseEvent)`: 拖拽中 - `handleDragEnd(e: MouseEvent)`: 结束拖拽 - `constrainPosition(pos: {x, y})`: 限制位置在视口内 - `saveState()`: 保存状态到localStorage - `restoreState()`: 从localStorage恢复状态 - `toggleVisibility()`: 切换可见性 #### 迷你按钮组件 ```typescript interface MiniButtonProps { onClick: () => void position: { x: number; y: number } } ``` ### 3. 头部菜单组件 (components/Header.tsx) #### 菜单项接口 ```typescript interface MenuItem { label: string icon: ReactNode onClick: () => void visible: boolean // 基于权限控制 } ``` #### 关键函数 - `handleProfileClick()`: 导航到个人中心 - `handleUpdateLogClick()`: 显示更新记录弹窗 - `handleSystemSettingsClick()`: 导航到系统设置(仅管理员) - `handleNetworkDiagnoseClick()`: 显示网络诊断弹窗 ### 4. 网络诊断组件 (components/NetworkDiagnoseModal.tsx) #### 诊断结果接口 ```typescript interface DiagnosticResult { timestamp: string downloadSpeed: number // MB/s uploadSpeed: number // MB/s storageConnectivity: boolean storageLatency: number // ms networkType: 'intranet' | 'internet' } ``` #### 关键函数 - `runDiagnostic()`: 执行完整诊断 - `testDownloadSpeed()`: 测试下载速度 - `testUploadSpeed()`: 测试上传速度 - `testStorageConnectivity()`: 测试存储连通性 - `cancelDiagnostic()`: 取消诊断 - `copyResult()`: 复制诊断结果 ### 5. 素材卡片组件 #### 样式接口 ```typescript interface MaterialCardStyle { buttonHeight: string buttonAlignment: 'vertical' | 'horizontal' hoverEffect: boolean } ``` ## 数据模型 ### LocalStorage数据结构 ```typescript // 榜单面板状态 interface RankingPanelStorage { isVisible: boolean position: { x: number; y: number } } // 键名: 'ranking_panel_state' ``` ### SessionStorage数据结构 ```typescript // 首页滚动位置和状态缓存 interface HomePageCache { scrollPosition: number materials: Material[] filters: FilterState timestamp: number } // 键名: 'home_scroll_position', 'home_materials_cache' ``` ## 正确性属性 *属性是一个特征或行为,应该在系统的所有有效执行中保持为真——本质上是关于系统应该做什么的形式化陈述。属性作为人类可读规范和机器可验证正确性保证之间的桥梁。* ### 属性 1: Material_Type排除规则 *对于任何*筛选状态,当Material_Type被选中时,"当前筛选"区域不应该显示Material_Type标签 **验证: 需求 1.2** ### 属性 2: 筛选条件显示完整性 *对于任何*非Material_Type的筛选条件,当该筛选条件被激活时,"当前筛选"区域应该显示该筛选条件 **验证: 需求 1.1** ### 属性 3: 筛选条件清除即时性 *对于任何*筛选条件,当用户清除该筛选条件时,该筛选条件应该立即从"当前筛选"区域移除 **验证: 需求 1.3** ### 属性 4: 空筛选隐藏规则 *对于任何*页面状态,当没有任何筛选条件激活时,"当前筛选"区域不应该显示 **验证: 需求 1.4** ### 属性 5: 品类筛选持久性 *对于任何*品类筛选,在执行任何其他操作(页面状态更新、页面内导航、添加其他筛选)后,品类筛选应该保持不变,直到被明确清除 **验证: 需求 2.1, 2.2, 2.3, 2.4** ### 属性 6: 榜单面板和迷你按钮互斥性 *对于任何*榜单面板状态,榜单面板可见时迷你按钮应该隐藏,榜单面板隐藏时迷你按钮应该可见 **验证: 需求 3.1, 3.3** ### 属性 7: 榜单面板状态往返 *对于任何*榜单面板状态,保存到localStorage然后恢复应该产生相同的状态 **验证: 需求 3.4, 3.5** ### 属性 8: 迷你按钮打开面板 *对于任何*隐藏的榜单面板,点击迷你按钮应该打开榜单面板 **验证: 需求 3.2** ### 属性 9: 拖拽跟随光标 *对于任何*拖拽操作,榜单面板的位置应该跟随鼠标光标移动 **验证: 需求 4.1** ### 属性 10: 拖拽结束固定位置 *对于任何*拖拽操作,释放鼠标后榜单面板应该固定在新位置 **验证: 需求 4.2** ### 属性 11: 榜单面板位置往返 *对于任何*榜单面板位置,保存到localStorage然后恢复应该产生相同的位置 **验证: 需求 4.3, 4.4** ### 属性 12: 拖拽边界约束 *对于任何*拖拽操作,当面板被拖到视口外时,面板位置应该被约束在视口边界内 **验证: 需求 4.5** ### 属性 13: 滚动自由性 *对于任何*页面状态(包括刷新后),用户应该能够自由滚动页面,不受任何锁定或干扰 **验证: 需求 5.1, 5.2, 5.3** ### 属性 14: 滚动恢复性能 *对于任何*滚动位置恢复操作,恢复应该在100ms内完成 **验证: 需求 5.4** ### 属性 15: 系统设置菜单权限控制 *对于任何*用户,当用户不是管理员时,系统设置菜单项不应该显示 **验证: 需求 6.4** ### 属性 16: 网络诊断选项完整性 *对于任何*网络诊断弹窗,弹窗应该显示所有诊断选项(下载速度、上传速度、存储连通性) **验证: 需求 7.2** ### 属性 17: 网络诊断结果完整性 *对于任何*成功的诊断测试,结果应该包含连接状态和延迟信息 **验证: 需求 7.4** ### 属性 18: 网络诊断错误处理 *对于任何*失败的诊断测试,系统应该显示错误信息和故障排除建议 **验证: 需求 7.5** ### 属性 19: 素材卡片按钮布局一致性 *对于任何*素材卡片,编辑、分享和下载按钮应该有正确的高度、垂直对齐,并在卡片大小改变时保持比例 **验证: 需求 8.1, 8.3, 8.4** ### 属性 20: 素材卡片hover效果 *对于任何*素材卡片,鼠标悬停时应该高亮操作按钮 **验证: 需求 8.2** ### 属性 21: 素材详情页面一致性 *对于任何*素材类型,详情页面应该有一致的布局、样式、UI模式、字体和间距 **验证: 需求 9.1, 9.2, 9.3, 9.4** ## 错误处理 ### 1. 筛选条件错误 - **场景**: 筛选条件状态不一致 - **处理**: 重置所有筛选条件到默认状态 - **用户反馈**: 显示提示信息"筛选条件已重置" ### 2. LocalStorage错误 - **场景**: LocalStorage读写失败或数据损坏 - **处理**: 使用默认值,清除损坏的数据 - **用户反馈**: 静默处理,不影响用户体验 ### 3. 拖拽错误 - **场景**: 拖拽过程中发生异常 - **处理**: 重置面板到默认位置 - **用户反馈**: 无需提示,面板回到默认位置 ### 4. 网络诊断错误 - **场景**: 诊断测试失败或超时 - **处理**: 显示错误信息和建议 - **用户反馈**: 显示详细的错误信息和故障排除步骤 ### 5. 导航错误 - **场景**: 路由导航失败 - **处理**: 显示错误提示,保持在当前页面 - **用户反馈**: 显示Toast提示"导航失败,请重试" ## 测试策略 ### 单元测试 单元测试用于验证特定示例、边缘情况和错误条件: 1. **筛选条件显示测试** - 测试Material_Type不出现在"当前筛选"中 - 测试其他筛选条件正确显示 - 测试清除筛选条件的功能 2. **榜单面板测试** - 测试面板显示/隐藏切换 - 测试迷你按钮显示/隐藏 - 测试localStorage保存和恢复 3. **拖拽功能测试** - 测试拖拽事件处理 - 测试边界约束逻辑 - 测试位置保存 4. **头部菜单测试** - 测试菜单项点击事件 - 测试权限控制逻辑 - 测试弹窗显示 5. **网络诊断测试** - 测试诊断流程 - 测试结果显示 - 测试错误处理 ### 属性测试 属性测试用于验证通用属性在所有输入下都成立: 1. **筛选条件属性测试** - 属性1-5: 测试筛选条件的显示、清除和持久性 - 最少100次迭代,使用随机筛选条件组合 2. **榜单面板属性测试** - 属性6-12: 测试面板状态、拖拽和位置管理 - 最少100次迭代,使用随机位置和状态 3. **滚动管理属性测试** - 属性13-14: 测试滚动自由性和性能 - 最少100次迭代,使用随机滚动位置 4. **UI一致性属性测试** - 属性15-21: 测试UI组件的一致性和正确性 - 最少100次迭代,使用随机素材数据 ### 测试框架 - **单元测试**: Jest + React Testing Library - **属性测试**: fast-check (JavaScript/TypeScript的属性测试库) - **E2E测试**: Playwright (用于完整的用户流程测试) ### 测试标签格式 每个属性测试必须使用以下格式标记: ```typescript // Feature: ui-fixes, Property 1: Material_Type排除规则 test.prop([fc.record({...})])('Material_Type should not appear in active filters', ...) ```