11 KiB
设计文档 - UI修复和功能还原
概述
本设计文档描述了由壹点3D素材平台UI修复和功能还原的技术实现方案。系统需要修复当前版本中存在的UI问题和功能缺失,包括筛选条件显示、榜单面板交互、页面滚动管理、头部菜单导航、网络诊断工具、素材卡片样式和素材详情页面一致性等方面。
架构
整体架构
系统采用Next.js 13+ App Router架构,使用React Server Components和Client Components混合模式。UI修复主要涉及以下层次:
- 页面层 (
app/page.tsx): 首页主逻辑,包含筛选状态管理和素材展示 - 组件层 (
components/): 可复用的UI组件,如Header、RankingPanel、NetworkDiagnoseModal等 - 状态管理层: 使用React Hooks进行本地状态管理,使用localStorage/sessionStorage进行持久化
- 样式层: 使用Tailwind CSS进行样式管理
关键设计决策
- 筛选条件显示: Material_Type不应出现在"当前筛选"区域,因为它是页面的主要分类维度,不是筛选条件
- 状态持久化: 使用localStorage保存用户偏好(如榜单面板状态和位置),使用sessionStorage保存临时状态(如滚动位置)
- 拖拽实现: 使用原生DOM事件实现拖拽,避免引入额外的库
- 滚动管理: 移除强制滚动位置恢复逻辑,允许浏览器自然处理滚动
组件和接口
1. 首页筛选组件 (app/page.tsx)
状态接口
interface FilterState {
searchKeyword: string
selectedCategory: string
selectedScene: string
selectedMaterialType: string // 不显示在"当前筛选"中
selectedPlatform: string
selectedProductCategory: string
selectedMonth: string
}
关键函数
renderActiveFilters(): 渲染"当前筛选"区域,排除Material_TypeclearFilter(filterName: string): 清除单个筛选条件clearAllFilters(): 清除所有筛选条件
2. 榜单面板组件 (components/RankingPanel.tsx)
状态接口
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(): 保存状态到localStoragerestoreState(): 从localStorage恢复状态toggleVisibility(): 切换可见性
迷你按钮组件
interface MiniButtonProps {
onClick: () => void
position: { x: number; y: number }
}
3. 头部菜单组件 (components/Header.tsx)
菜单项接口
interface MenuItem {
label: string
icon: ReactNode
onClick: () => void
visible: boolean // 基于权限控制
}
关键函数
handleProfileClick(): 导航到个人中心handleUpdateLogClick(): 显示更新记录弹窗handleSystemSettingsClick(): 导航到系统设置(仅管理员)handleNetworkDiagnoseClick(): 显示网络诊断弹窗
4. 网络诊断组件 (components/NetworkDiagnoseModal.tsx)
诊断结果接口
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. 素材卡片组件
样式接口
interface MaterialCardStyle {
buttonHeight: string
buttonAlignment: 'vertical' | 'horizontal'
hoverEffect: boolean
}
数据模型
LocalStorage数据结构
// 榜单面板状态
interface RankingPanelStorage {
isVisible: boolean
position: { x: number; y: number }
}
// 键名: 'ranking_panel_state'
SessionStorage数据结构
// 首页滚动位置和状态缓存
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提示"导航失败,请重试"
测试策略
单元测试
单元测试用于验证特定示例、边缘情况和错误条件:
-
筛选条件显示测试
- 测试Material_Type不出现在"当前筛选"中
- 测试其他筛选条件正确显示
- 测试清除筛选条件的功能
-
榜单面板测试
- 测试面板显示/隐藏切换
- 测试迷你按钮显示/隐藏
- 测试localStorage保存和恢复
-
拖拽功能测试
- 测试拖拽事件处理
- 测试边界约束逻辑
- 测试位置保存
-
头部菜单测试
- 测试菜单项点击事件
- 测试权限控制逻辑
- 测试弹窗显示
-
网络诊断测试
- 测试诊断流程
- 测试结果显示
- 测试错误处理
属性测试
属性测试用于验证通用属性在所有输入下都成立:
-
筛选条件属性测试
- 属性1-5: 测试筛选条件的显示、清除和持久性
- 最少100次迭代,使用随机筛选条件组合
-
榜单面板属性测试
- 属性6-12: 测试面板状态、拖拽和位置管理
- 最少100次迭代,使用随机位置和状态
-
滚动管理属性测试
- 属性13-14: 测试滚动自由性和性能
- 最少100次迭代,使用随机滚动位置
-
UI一致性属性测试
- 属性15-21: 测试UI组件的一致性和正确性
- 最少100次迭代,使用随机素材数据
测试框架
- 单元测试: Jest + React Testing Library
- 属性测试: fast-check (JavaScript/TypeScript的属性测试库)
- E2E测试: Playwright (用于完整的用户流程测试)
测试标签格式
每个属性测试必须使用以下格式标记:
// Feature: ui-fixes, Property 1: Material_Type排除规则
test.prop([fc.record({...})])('Material_Type should not appear in active filters', ...)