Some checks failed
CI Check / check (push) Has been cancelled
- 替换所有浏览器原生弹窗(confirm/alert/prompt) - 创建 ConfirmDialog、AlertDialog、PromptDialog 组件 - 创建 DialogProvider 和 useDialog Hook - 替换所有 admin 组件、首页、分享页面中的原生弹窗 - 素材预览面板统一 - 创建 MaterialPreviewModal 组件 - 使用统一弹窗组件,统一退出逻辑 - 首页UI统一到三层架构 - 迁移主要按钮和输入框样式 - 迁移筛选弹窗中的所有按钮样式 - 使用 useThemeStyles() Hook - 更新文档 - 更新优化记录、优化计划、后续修改、更新日志
19 KiB
19 KiB
Admin 页面优化建议和问题修复记录
✅ 已完成的修复
1. 类型定义统一化
- ✅ 创建了
types.ts统一管理所有类型定义 - ✅ 移除了
page.tsx中的重复类型定义(User, Material, Category, Scene, Platform, Invitation, UserTreeNode, DepartmentNode, DepartmentUserGrouping) - ✅ 移除了
TemplateManager.tsx中的重复ToastFn定义 - ✅ 添加了
AdminTab类型统一管理 Tab 类型 - ✅ 添加了
DashboardData接口用于监控仪表板数据 - ✅ 修复了
TemplateManager.tsx中DragHoverState的类型错误(fallback 对象的position属性需要明确类型为'before' | 'after') - ✅ 修复了
TemplateFieldsEditor.tsx中onFieldDragOver回调签名,添加缺失的surface参数 - ✅ 修复了
UsersTab.tsx中showTransferButton在使用前未定义的问题,将其改为useMemo并移到使用前定义
2. UI 样式统一化 - 三层架构重构
- ✅ 创建了三层架构的样式系统:
- 基础层:
lib/ui-styles-base.ts- 包含布局、大小、动画等非颜色样式 - 颜色层:
lib/ui-theme-colors-light.ts/dark.ts- 仅包含颜色配置 - 组合层:
lib/ui-styles-composer.ts- 自动组合基础样式和颜色主题 - 导出层:
lib/ui-styles-light.ts/dark.ts- 最终导出的样式(由组合器生成)
- 基础层:
- ✅ 创建了
lib/hooks/useThemeStyles.ts- 主题感知的样式 HookuseThemeStyles()- 根据当前主题自动返回对应的样式配置useTheme()- 获取当前主题状态
- ✅ 保持了向后兼容性:
- 原有的
lib/ui-styles.ts仍然保留(包含dark:前缀的样式) - 新组件推荐使用
useThemeStyles()Hook - 旧组件可以继续使用原有导入,逐步迁移
- 原有的
核心优势:
- ✅ 统一视觉设计:修改布局、大小、动画时,只需修改
ui-styles-base.ts一处,浅色和深色模式自动同步 - ✅ 独立颜色适配:颜色配置完全分离,可以独立调整浅色或深色模式的颜色
- ✅ 易于维护:清晰的职责分离,修改时不会遗漏或出错
- ✅ 类型安全:TypeScript 类型检查确保配置正确
修改指南:
- 修改布局/大小/动画 → 修改
lib/ui-styles-base.ts(一处修改,两套主题自动同步) - 修改浅色模式颜色 → 修改
lib/ui-theme-colors-light.ts - 修改深色模式颜色 → 修改
lib/ui-theme-colors-dark.ts
架构文档: 详见 docs/guides/UI_STYLES_ARCHITECTURE.md
使用示例:
'use client'
import { useThemeStyles } from '@/lib/ui-styles'
export default function MyComponent() {
const styles = useThemeStyles()
return (
<div className={styles.cardStyles.base}>
<button className={styles.buttonStyles.primary}>点击</button>
</div>
)
}
迁移进度:
- ✅ 基础 UI 组件已迁移:
LoadingState.tsx- 使用useThemeStyles()和useTheme()ErrorState.tsx- 使用useThemeStyles()和useTheme()EmptyState.tsx- 使用useTheme()根据主题选择文字颜色
- ✅ Tab 组件迁移(全部完成):
MaterialsTab.tsx- 完全迁移到新样式系统,移除了所有dark:前缀CategoriesTab.tsx- 完全迁移到新样式系统,移除了所有dark:前缀InvitationsTab.tsx- 完全迁移到新样式系统,移除了所有dark:前缀DepartmentsTab.tsx- 完全迁移到新样式系统,移除了所有dark:前缀UsersTab.tsx- 完全迁移到新样式系统,移除了所有dark:前缀MonitorTab.tsx- 完全迁移到新样式系统,移除了所有dark:前缀
- ✅ 其他组件迁移(已完成):
TemplateManager.tsx- 完全迁移到新样式系统,移除了所有dark:前缀page.tsx- 完全迁移到新样式系统,移除了所有dark:前缀AppearanceSettingsPanel.tsx- 完全迁移到新样式系统,移除了所有dark:前缀
3. UI 样式统一化(历史)
- ✅ 修复了
card-apple类名,改为使用cardStyles.base - ✅ 统一了边框颜色:
border-gray-*→border-slate-*(与设计系统一致) - ✅ Admin 目录中的
text-gray-* / bg-gray-* / border-gray-*类已全部替换为slate系列,浅色与深色模式的视觉基调保持一致
🔍 发现的问题和建议
1. 代码结构问题
问题:page.tsx 文件过大(3795 行)
影响:
- 难以维护和调试
- 代码复用性差
- 性能可能受影响(组件过大)
建议:
- ✅ 已创建
MonitorTab.tsx组件 - ✅ 已拆分
UsersTab.tsx(用户管理) - ✅ 已拆分
DepartmentsTab.tsx(架构管理) - ⏳ 继续拆分其他 Tab 组件:
- ✅
CategoriesTab.tsx- 分类管理 - ✅
InvitationsTab.tsx- 邀请管理 - ✅
MaterialsTab.tsx- 素材管理 - ✅
TemplateManager.tsx:已提取 Header / Built-in Grid / Custom Templates 等 UI 子组件,为后续拆出编辑器面板铺路 - ✅ TemplateManager 编辑弹窗:基础信息、预设选择、JSON 高级配置抽象为
TemplateBasicsForm+TemplateAdvancedConfigPanel,编辑逻辑逐步下沉 - ✅ TemplateManager 字段区、底部操作:
TemplateFieldsEditor承载字段配置 + 拖拽 UI,TemplateEditorFooter统一处理提示与按钮状态 - ✅ TemplateManager 预览面板:
TemplatePreviewPanel独立封装上传预览 UI 与 DnD 状态,主组件仅处理回调
- ✅
问题:状态管理分散
当前状态:
- 每个 Tab 的状态都在主组件中管理
- 状态之间可能存在不必要的依赖
建议:
- ✅
UsersTab/DepartmentsTab已将本地 UI 状态与交互逻辑下沉到各自组件 - 只保留共享状态在主组件(如
activeTab,toast)
4. UI 统一性问题
问题:部分地方仍使用旧的样式类
发现:
- ✅ 基础文字/背景/边框色已统一为
slate系列(含浅色与深色) - ✅ 深浅色样式已分离为两套独立配置,解决适配问题
- ⏳ 部分按钮样式未使用
buttonStyles.*(建议逐步迁移到useThemeStyles()) - ⏳ 部分输入框仍未使用
inputStyles.*(建议逐步迁移到useThemeStyles())
建议:
- 全局搜索替换
gray-→slate-(在 admin 目录中) - ⏳ 确保所有按钮都使用
buttonStyles.*(InvitationsTab、CategoriesTab、MaterialsTab、UsersTab、DepartmentsTab ✅;其它 Tab 持续中) - ⏳ 确保所有输入框都使用
inputStyles.*(DepartmentsTab 重命名输入已调整) - ✅ 补充
buttonStyles.success以覆盖绿色状态按钮场景 - ✅ 新增
buttonModifiers(compact / compactXs / icon / block)辅助类,方便统一尺寸与布局 - ✅ MaterialsTab 搜索操作、卡片操作按钮已统一到
buttonStyles + buttonModifiers,并将<img>替换为next/image - ✅ UsersTab 搜索清空与用户操作按钮统一引用
buttonStyles + buttonModifiers - ✅ DepartmentsTab 搜索清空、操作按钮接入
buttonStyles + buttonModifiers; 新增inputModifiers并应用到重命名输入 - ✅ TemplateManager 顶部搜索、预制/自定义模板动作按钮接入设计系统;新增
buttonModifiers.pill - ✅ TemplateManager 基础信息 / JSON 配置表单统一使用
inputStyles + inputModifiers,并抽离复用组件 - ✅ TemplateManager 字段配置 / 底部操作按钮接入设计系统(字段编辑区统一控件样式,弹窗底部按钮使用
buttonStyles.secondary/primary+buttonModifiers.compact) - ✅ TemplateManager 预览面板 UI 与拖拽交互抽象为
TemplatePreviewPanel,复用设计系统控件 - ✅ 清理 TemplatePreviewPanel 与
page.tsx残留的gray-*渐变/分隔线/焦点样式,统一替换为slate-*调色 - ✅
page.tsx移除历史 Invitations UI、状态与数据请求,统一由InvitationsTab自主管理 - ✅
page.tsx移除重复的监控仪表板代码,统一使用MonitorTab组件
3. 逻辑优化建议
问题:数据获取逻辑重复
当前:
- ✅
useDataFetchHook 已抽离loadUsersData/fetchDepartments/fetchTabData,主页面只关心状态驱动 - ⏳ 更进一步的缓存(React Query / SWR)尚未落地
建议:
- 后续可引入 React Query 或 SWR 进行跨 Tab 缓存与自动刷新
- 或者在各 Tab 内使用独立数据源,减少主页面耦合
问题:权限检查分散
当前:
- 权限检查在多个地方重复
canManageUser等函数在主组件中定义
建议:
- ✅ 已创建
usePermissionsHook,统一canManageUser/ 超管判定等权限逻辑 - 后续可将其他权限相关逻辑继续提取到工具函数或 Hook 中
4. 性能优化建议
问题:大量 useMemo 和 useCallback
当前:
- 主组件中有很多
useMemo和useCallback - 某些计算可能不需要缓存
建议:
- ✅ 审查了每个
useMemo和useCallback的必要性departmentCollator- 使用useMemo合理(创建 Intl.Collator 对象)userLookup- 使用useMemo合理(从数组创建 Map,避免重复计算)fetchData,renameDepartment,createDepartment,deleteDepartment,findDepartmentManagers- 使用useCallback合理(作为 props 传递给子组件)
- ✅ 创建了
_utils/api.ts统一处理 API 错误,减少了重复的错误处理代码 - ⏳ 将复杂的计算逻辑移到子组件中
- ✅ 使用 React.memo 优化子组件渲染(
UserTree已实现)
问题:模态框状态管理
当前:
- ✅ 分类/场景/平台新增、素材编辑相关模态已移交给各自 Tab 组件,
page.tsx清理全部遗留状态与 UI - ✅ 新增
useModalStateHook(app/admin/_hooks/useModalState.ts),统一管理用户编辑/转移最高权限模态的开合与状态,移除散落的showPasswordModal、editingUser布尔控制 - ⏳ 用户信息编辑、转移最高权限 UI 仍托管在
page.tsx,可进一步下放到UsersTab
建议:
- 为剩余模态编写统一的模态管理 hook
- 或者继续将模态迁移到对应的 Tab/组件内部
5. 代码质量建议
建议:添加错误边界
- ✅ 新增
TabErrorBoundary组件(app/admin/_components/TabErrorBoundary.tsx),并在page.tsx为各个 Tab 包裹,提供统一的 fallback + 重试 - ⏳ 可进一步将
TabErrorBoundary提炼到全局组件库,或为特定 Tab 定制更详细的错误提示
建议:添加加载状态统一管理
- ✅ 创建统一的加载状态组件(
LoadingState、ErrorState、EmptyState) - ✅ 统一错误提示样式,替换所有重复的加载/错误 UI
- ✅
MonitorTab、MaterialsTab、page.tsx已统一使用新的状态组件
建议:提取公共逻辑
- ✅ 创建
hooks/useToast.ts统一管理 Toast(page.tsx已接入) - ✅ 创建
hooks/useDataFetch.ts统一管理数据获取 - ✅ 创建
_utils/api.ts统一处理 API 错误响应和类型安全parseErrorResponse()- 安全解析错误响应parseSuccessResponse()- 安全解析成功响应apiRequest()- 统一的 API 请求函数getErrorMessage()- 获取错误消息的辅助函数
- ✅ 提取表单验证逻辑到工具函数
- 创建了
_utils/validators.ts统一管理表单验证 validateNotEmpty()- 验证非空字符串validateDepartmentName()- 验证部门名称validateEmail()- 验证邮箱格式validateFieldKey()- 验证字段键名(标识符规则)validateUniqueKeys()- 验证字段键名唯一性validateTemplateName()- 验证模板名称validatePassword()- 验证密码combineValidationResults()- 组合多个验证结果page.tsx和TemplateManager.tsx已使用新的验证函数
- 创建了
- ✅ 创建格式化工具函数
- 创建了
_utils/formatters.ts统一管理格式化逻辑 formatDateTime()- 格式化日期时间(完整格式)formatDate()- 格式化日期(仅日期部分)formatTime()- 格式化时间(仅时间部分)formatDateTimeShort()- 格式化日期时间(简短格式)formatDateTimeLocale()- 使用本地化格式格式化日期时间formatRelativeTime()- 格式化相对时间formatFileSize()- 格式化文件大小formatNumber()- 格式化数字(添加千位分隔符)formatPercent()- 格式化百分比MonitorTab.tsx、InvitationsTab.tsx、UserEditModal.tsx、TemplateManager.tsx已使用新的格式化函数
- 创建了
- ✅ 提取用户操作逻辑到 Hook
- 创建了
_hooks/useUserOperations.ts统一管理用户相关操作 updateUser()- 更新用户信息deleteUser()- 删除用户toggleDownload()- 切换下载权限toggleActive()- 切换激活状态setRole()- 设置用户角色transferSuperAdmin()- 转移最高权限page.tsx已使用新的 Hook,代码更简洁
- 创建了
- ✅ 提取部门操作逻辑到 Hook
- 创建了
_hooks/useDepartmentOperations.ts统一管理部门相关操作 createDepartment()- 创建部门deleteDepartment()- 删除部门renameDepartment()- 重命名部门page.tsx已使用新的 Hook,移除了重复的部门操作代码,代码更简洁- 创建了
_utils/validators.ts统一管理表单验证 validateNotEmpty()- 验证非空字符串validateDepartmentName()- 验证部门名称validateEmail()- 验证邮箱格式validateFieldKey()- 验证字段键名(标识符规则)validateUniqueKeys()- 验证字段键名唯一性validateTemplateName()- 验证模板名称validatePassword()- 验证密码combineValidationResults()- 组合多个验证结果page.tsx和TemplateManager.tsx已使用新的验证函数
- 创建了
6. 类型安全建议
问题:使用 any 类型
发现:
session?.user as any多处使用dashboardData使用any类型
建议:
- ✅ 定义完整的 Session 类型(
SessionUser接口) - ✅ 使用
DashboardData类型替代any(已在 types.ts 中定义) - ✅ 添加类型断言函数(
getSessionUser) - ✅ 定义 API 响应类型(
ApiErrorResponse,ApiSuccessResponse) - ✅ 移除
page.tsx中所有as any使用 - ✅ 更新
AppearanceSettingsPanel使用SessionUser类型
7. 可访问性建议
建议:添加 ARIA 标签
- ✅ 为 Tab 导航添加了完整的 ARIA 标签(
role="tablist",role="tab",role="tabpanel") - ✅ 为所有 Tab 按钮添加了
aria-selected,aria-controls,id属性 - ✅ 为返回主页按钮和关闭 Toast 按钮添加了
aria-label - ✅ 为 Toast 通知添加了
role="status"和aria-live="polite" - ✅ 添加了键盘导航支持(Enter 和 Space 键)
- ✅ 添加了焦点样式(
focus:outline-none focus:ring-2) - ⏳ 继续为其他交互元素添加 ARIA 标签和键盘支持
8. 测试建议
建议:添加单元测试
- 为工具函数添加测试
- 为权限检查逻辑添加测试
- 为数据转换逻辑添加测试
📋 下一步行动计划
注意:详细的优化计划和优先级已移至
优化计划与优先级.md,请参考该文档进行后续开发。
当前阶段:基础组件与UI统一
优先级 1:基础组件与UI统一(核心基础设施)
-
✅ 创建统一弹窗组件(
components/ui/Modal.tsx)- ✅ 使用三层架构设计(基础层、颜色层、组合层)
- ✅ 提供
useModalHook(hooks/useModal.ts) - ✅ 支持多种尺寸(small, medium, large, xlarge, fullscreen)
- ✅ 支持ESC键关闭、点击遮罩关闭
- ✅ 完整的ARIA标签和键盘导航支持
- ✅ 替换所有浏览器原生弹窗(confirm/alert/prompt)
- ✅ 创建了 ConfirmDialog、AlertDialog、PromptDialog 组件
- ✅ 创建了 DialogProvider 和 useDialog Hook
- ✅ 替换了所有 admin 组件、首页、分享页面中的原生弹窗
-
✅ 素材预览面板统一
- ✅ 创建了 MaterialPreviewModal 组件
- ✅ 使用统一弹窗组件
- ✅ 统一退出逻辑(ESC键、点击遮罩、关闭按钮)
- ✅ 使用三层架构样式系统
-
✅ 首页素材展示响应式优化
- ✅ 修复卡片比例固定问题(使用
aspect-[3/4]替代固定高度h-[400px]) - ✅ 添加容器边距(
px-4 sm:px-6 lg:px-8)避免卡片贴到浏览器边界 - ✅ 使用三层架构样式系统(
useThemeStyles()和cardStyles.base) - ✅ 优化图片 sizes 属性,提升响应式性能
- ✅ 统一使用
slate系列颜色,确保深浅色模式适配
- ✅ 修复卡片比例固定问题(使用
-
✅ 首页UI统一到三层架构(主要部分)
- ✅ 迁移了主要按钮样式(上传按钮、筛选按钮)
- ✅ 迁移了搜索输入框样式
- ✅ 迁移了筛选弹窗中的所有按钮样式
- ✅ 迁移了筛选弹窗容器样式
- ✅ 迁移了筛选弹窗关闭按钮样式
- ⏳ 部分文本颜色和标签样式仍使用直接 Tailwind 类(可后续继续优化)
优先级 2:数据一致性与核心功能 5. ⏳ 用户信息修改后同步素材信息
- 在
useUserOperations中扩展
- ⏳ 模板管理整合到上传和分类
- 严格检查模板管理面板逻辑
- 将模板系统串起前后端
详细计划:请查看 优化计划与优先级.md
📝 代码规范建议
命名规范
- 组件文件:PascalCase(如
UsersTab.tsx) - Hook 文件:camelCase with
useprefix(如usePermissions.ts) - 工具函数:camelCase(如
formatDate.ts) - 类型文件:
types.ts或types/index.ts
文件组织
app/admin/
├── _components/
│ ├── types.ts # 类型定义
│ ├── MonitorTab.tsx # 监控仪表板
│ ├── UsersTab.tsx # 用户管理
│ ├── DepartmentsTab.tsx # 架构管理
│ ├── CategoriesTab.tsx # 分类管理
│ ├── InvitationsTab.tsx # 邀请管理
│ ├── MaterialsTab.tsx # 素材管理
│ ├── TemplateManager.tsx # 模板管理
│ └── AppearanceSettingsPanel.tsx
├── _hooks/ # 自定义 hooks
│ ├── useToast.ts
│ ├── usePermissions.ts
│ └── useDataFetch.ts
├── _utils/ # 工具函数
│ ├── validators.ts
│ └── formatters.ts
└── page.tsx # 主页面(简化后)
🎯 最终目标
- 代码可维护性:每个组件职责单一,易于理解和修改
- 代码复用性:公共逻辑提取到 hooks 和工具函数
- 类型安全:完整的 TypeScript 类型定义,减少运行时错误
- UI 一致性:统一使用设计系统,确保视觉一致性
- 性能优化:减少不必要的渲染,优化数据获取
- 用户体验:流畅的交互,清晰的错误提示