chenpei 0ce59be34e 备份:组织架构设计方案讨论前的代码快照
- 包含所有当前修改和新功能
- 准备开始组织架构优化实施方案
2025-12-30 13:20:26 +08:00

366 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Design Document: 代码拆分重构
## Overview
本设计文档描述如何将三个大型代码文件拆分为更小、更可维护的模块。采用 React 自定义 Hooks 和组件拆分的方式,遵循单一职责原则。
## Architecture
```
components/
├── upload/ # 上传相关组件(已有部分)
│ ├── UploadModal.tsx # 主组件(重构后)
│ ├── UploadForm.tsx # 新增:表单字段组件
│ ├── SpecialBatchUploadUI.tsx # 新增:特殊批量上传UI
│ └── ... (已有文件保持不变)
├── admin/ # 新增:管理后台组件
│ ├── UserManagement.tsx
│ ├── MaterialManagement.tsx
│ ├── CategoryManagement.tsx
│ ├── SystemSettings.tsx
│ └── AdminStats.tsx
└── home/ # 新增:首页组件
├── FilterPanel.tsx
├── MaterialGrid.tsx
├── MaterialDetailModal.tsx
├── SearchBar.tsx
└── Pagination.tsx
hooks/
├── useUploadState.ts # 新增:上传状态管理
├── useCategoryData.ts # 新增:分类数据获取
├── useBatchUpload.ts # 新增:批量上传逻辑
├── useDragHandlers.ts # 新增:拖拽处理
├── useAdminState.ts # 新增:管理后台状态
├── useHomeState.ts # 新增:首页状态
└── useMaterials.ts # 新增:素材数据获取
```
## Components and Interfaces
### 1. UploadModal 拆分
#### useUploadState Hook
```typescript
// hooks/useUploadState.ts
interface UploadState {
// 文件状态
previewImages: File[]
previewUrls: string[]
displayImage: File | null
displayImageUrl: string
modelImages: File[]
modelImageUrls: string[]
zipFile: File | null
// 表单状态
productModel: string
categoryName: string
sceneName: string
platformName: string
productCategoryName: string
materialType: string
renderer: string
// 上传状态
uploading: boolean
uploadProgress: number
uploadSpeed: number
isProcessing: boolean
error: string
// 批量上传状态
batchFiles: BatchFileItem[]
isBatchMode: boolean
batchUploadStatus: BatchUploadStatus | null
}
export function useUploadState(): {
state: UploadState
actions: UploadStateActions
}
```
#### useCategoryData Hook
```typescript
// hooks/useCategoryData.ts
interface CategoryData {
categories: Array<{ id: string; name: string }>
scenes: Array<{ id: string; name: string }>
platforms: Array<{ id: string; name: string }>
productCategories: Array<{ id: string; name: string }>
}
export function useCategoryData(): {
data: CategoryData
loading: boolean
refresh: () => Promise<void>
}
```
#### useBatchUpload Hook
```typescript
// hooks/useBatchUpload.ts
export function useBatchUpload(materialType: string): {
// 特殊类型批量文件
batchMusicFiles: Array<{ file: File; productModel: string }>
batchVideoFiles: Array<{ file: File; productModel: string }>
batch3DFiles: Array<{ file: File; productModel: string; previewImage?: File }>
batchBrandVIFiles: Array<{ file: File; productModel: string }>
batchBuyerShowFiles: Array<{ productModel: string; images: File[] }>
batchXiaohongshuFiles: Array<{ productModel: string; images: File[] }>
// 操作函数
handleBatchFileSelect: (e: React.ChangeEvent<HTMLInputElement>) => void
handleBatchMusicUpload: () => Promise<void>
handleCancelBatchUpload: () => Promise<void>
// ... 其他批量上传函数
}
```
#### useDragHandlers Hook
```typescript
// hooks/useDragHandlers.ts
export function useDragHandlers(): {
isDragging: boolean
isPreviewDragging: boolean
isDisplayImageDragging: boolean
handleDragEnter: (e: React.DragEvent) => void
handleDragLeave: (e: React.DragEvent) => void
handleDragOver: (e: React.DragEvent) => void
handleDrop: (e: React.DragEvent) => void
handlePreviewDrop: (e: React.DragEvent) => void
handleDisplayImageDrop: (e: React.DragEvent) => void
}
```
#### UploadForm Component
```typescript
// components/upload/UploadForm.tsx
interface UploadFormProps {
materialType: string
productModel: string
categoryName: string
sceneName: string
platformName: string
productCategoryName: string
renderer: string
categories: Array<{ id: string; name: string }>
scenes: Array<{ id: string; name: string }>
platforms: Array<{ id: string; name: string }>
productCategories: Array<{ id: string; name: string }>
onProductModelChange: (value: string) => void
onCategoryChange: (value: string) => void
onSceneChange: (value: string) => void
onPlatformChange: (value: string) => void
onProductCategoryChange: (value: string) => void
onRendererChange: (value: string) => void
onAddCategory: (name: string) => Promise<void>
onAddScene: (name: string) => Promise<void>
}
```
### 2. AdminPage 拆分
#### useAdminState Hook
```typescript
// hooks/useAdminState.ts
interface AdminState {
activeTab: 'materials' | 'users' | 'categories' | 'departments' | 'permissions' | 'superAdmins'
materials: Material[]
users: User[]
categories: Category[]
scenes: Scene[]
platforms: Platform[]
productCategories: ProductCategory[]
loading: boolean
// ... 其他状态
}
export function useAdminState(): {
state: AdminState
actions: AdminStateActions
}
```
#### Admin Components
```typescript
// components/admin/UserManagement.tsx
interface UserManagementProps {
users: User[]
departments: Department[]
onUpdateUser: (userId: string, data: Partial<User>) => Promise<void>
onDeleteUser: (userId: string) => Promise<void>
}
// components/admin/MaterialManagement.tsx
interface MaterialManagementProps {
materials: Material[]
showRecycleBin: boolean
onDelete: (ids: string[]) => Promise<void>
onRestore: (ids: string[]) => Promise<void>
onSearch: (keyword: string) => void
}
// components/admin/CategoryManagement.tsx
interface CategoryManagementProps {
categories: Category[]
scenes: Scene[]
platforms: Platform[]
productCategories: ProductCategory[]
onAdd: (type: string, name: string) => Promise<void>
onEdit: (type: string, id: string, name: string) => Promise<void>
onDelete: (type: string, id: string) => Promise<void>
}
```
### 3. HomePage 拆分
#### useHomeState Hook
```typescript
// hooks/useHomeState.ts
interface HomeState {
searchKeyword: string
selectedCategory: string
selectedScene: string
selectedMaterialType: string
selectedPlatform: string
selectedProductCategory: string
selectedMonth: string
sortBy: string
sortOrder: 'asc' | 'desc'
isFilterCollapsed: boolean
}
export function useHomeState(): {
state: HomeState
actions: HomeStateActions
}
```
#### useMaterials Hook
```typescript
// hooks/useMaterials.ts
interface UseMaterialsOptions {
searchKeyword: string
selectedCategory: string
selectedScene: string
selectedMaterialType: string
selectedPlatform: string
selectedProductCategory: string
selectedMonth: string
sortBy: string
sortOrder: 'asc' | 'desc'
}
export function useMaterials(options: UseMaterialsOptions): {
materials: Material[]
loading: boolean
hasMore: boolean
totalCount: number
loadMore: () => Promise<void>
refresh: () => Promise<void>
}
```
#### Home Components
```typescript
// components/home/FilterPanel.tsx
interface FilterPanelProps {
categories: Category[]
scenes: Scene[]
platforms: Platform[]
productCategories: ProductCategory[]
materialTypes: MaterialType[]
months: Month[]
selectedCategory: string
selectedScene: string
selectedMaterialType: string
selectedPlatform: string
selectedProductCategory: string
selectedMonth: string
sortBy: string
sortOrder: 'asc' | 'desc'
isCollapsed: boolean
onCategoryChange: (value: string) => void
onSceneChange: (value: string) => void
onMaterialTypeChange: (value: string) => void
onPlatformChange: (value: string) => void
onProductCategoryChange: (value: string) => void
onMonthChange: (value: string) => void
onSortByChange: (value: string) => void
onSortOrderChange: (value: 'asc' | 'desc') => void
onToggleCollapse: () => void
}
// components/home/MaterialGrid.tsx
interface MaterialGridProps {
materials: Material[]
loading: boolean
onMaterialClick: (material: Material) => void
onDownload: (material: Material) => void
onLike: (material: Material) => void
onFavorite: (material: Material) => void
onShare: (material: Material) => void
}
// components/home/SearchBar.tsx
interface SearchBarProps {
value: string
onChange: (value: string) => void
placeholder?: string
}
// components/home/Pagination.tsx
interface PaginationProps {
hasMore: boolean
isLoading: boolean
onLoadMore: () => void
}
```
## Data Models
数据模型保持不变,继续使用现有的 Prisma 模型和 TypeScript 接口。
## Correctness Properties
*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*
由于本次重构主要是代码组织优化,不涉及业务逻辑变更,因此主要通过以下方式验证正确性:
1. **构建验证**: 重构后代码能够成功通过 TypeScript 编译和 Next.js 构建
2. **行数验证**: 主文件行数符合目标要求
3. **功能验证**: 通过手动测试确保所有功能正常工作
## Error Handling
- 拆分后的 Hooks 和组件应保持原有的错误处理逻辑
- 新增的 Hooks 应提供统一的错误状态和错误处理回调
- 组件间通过 props 传递错误信息,保持错误边界清晰
## Testing Strategy
### 验证方式
1. **TypeScript 类型检查**: 运行 `npx tsc --noEmit` 确保无类型错误
2. **ESLint 检查**: 运行 `npm run lint` 确保代码风格一致
3. **构建测试**: 运行 `npm run build` 确保能够成功构建
4. **手动功能测试**:
- 测试上传弹窗的所有上传类型
- 测试管理后台的所有功能标签页
- 测试首页的筛选、搜索、分页功能
### 回归测试清单
- [ ] 单个文件上传(各种素材类型)
- [ ] 批量文件上传(音乐、视频、3D场景等)
- [ ] 拖拽上传
- [ ] 分类/场景/平台筛选
- [ ] 搜索功能
- [ ] 分页加载
- [ ] 用户管理
- [ ] 素材管理(删除、恢复)
- [ ] 分类管理(增删改)