281 lines
8.6 KiB
TypeScript
281 lines
8.6 KiB
TypeScript
/**
|
|
* 上传状态管理 Hook
|
|
* 封装 UploadModal 组件的所有状态定义
|
|
*/
|
|
|
|
import { useState, useRef } from 'react'
|
|
import type { BatchFileItem, BatchUploadStatus } from '@/components/upload/upload-types'
|
|
|
|
/**
|
|
* 上传状态接口
|
|
*/
|
|
export 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
|
|
|
|
// 新建分类输入
|
|
showNewCategoryInput: boolean
|
|
newCategoryName: string
|
|
showNewSceneInput: boolean
|
|
newSceneName: string
|
|
|
|
// 上传状态
|
|
uploading: boolean
|
|
uploadProgress: number
|
|
uploadSpeed: number
|
|
isProcessing: boolean
|
|
error: string
|
|
retryCount: number
|
|
|
|
// 批量上传
|
|
batchFiles: BatchFileItem[]
|
|
isBatchMode: boolean
|
|
batchUploadStatus: BatchUploadStatus | null
|
|
|
|
// 拖拽状态
|
|
isDragging: boolean
|
|
isDisplayImageDragging: boolean
|
|
isPreviewDragging: boolean
|
|
batchPreviewDragging: Record<string, boolean>
|
|
}
|
|
|
|
/**
|
|
* 上传状态操作接口
|
|
*/
|
|
export interface UploadStateActions {
|
|
// 预览图片操作
|
|
setPreviewImages: React.Dispatch<React.SetStateAction<File[]>>
|
|
setPreviewUrls: React.Dispatch<React.SetStateAction<string[]>>
|
|
|
|
// 详情页展示图片操作
|
|
setDisplayImage: React.Dispatch<React.SetStateAction<File | null>>
|
|
setDisplayImageUrl: React.Dispatch<React.SetStateAction<string>>
|
|
|
|
// 模特图片操作
|
|
setModelImages: React.Dispatch<React.SetStateAction<File[]>>
|
|
setModelImageUrls: React.Dispatch<React.SetStateAction<string[]>>
|
|
|
|
// 素材文件操作
|
|
setZipFile: React.Dispatch<React.SetStateAction<File | null>>
|
|
|
|
// 表单字段操作
|
|
setProductModel: React.Dispatch<React.SetStateAction<string>>
|
|
setCategoryName: React.Dispatch<React.SetStateAction<string>>
|
|
setSceneName: React.Dispatch<React.SetStateAction<string>>
|
|
setPlatformName: React.Dispatch<React.SetStateAction<string>>
|
|
setProductCategoryName: React.Dispatch<React.SetStateAction<string>>
|
|
setMaterialType: React.Dispatch<React.SetStateAction<string>>
|
|
setRenderer: React.Dispatch<React.SetStateAction<string>>
|
|
|
|
// 新建分类输入操作
|
|
setShowNewCategoryInput: React.Dispatch<React.SetStateAction<boolean>>
|
|
setNewCategoryName: React.Dispatch<React.SetStateAction<string>>
|
|
setShowNewSceneInput: React.Dispatch<React.SetStateAction<boolean>>
|
|
setNewSceneName: React.Dispatch<React.SetStateAction<string>>
|
|
|
|
// 上传状态操作
|
|
setUploading: React.Dispatch<React.SetStateAction<boolean>>
|
|
setUploadProgress: React.Dispatch<React.SetStateAction<number>>
|
|
setUploadSpeed: React.Dispatch<React.SetStateAction<number>>
|
|
setIsProcessing: React.Dispatch<React.SetStateAction<boolean>>
|
|
setError: React.Dispatch<React.SetStateAction<string>>
|
|
setRetryCount: React.Dispatch<React.SetStateAction<number>>
|
|
|
|
// 批量上传操作
|
|
setBatchFiles: React.Dispatch<React.SetStateAction<BatchFileItem[]>>
|
|
setIsBatchMode: React.Dispatch<React.SetStateAction<boolean>>
|
|
setBatchUploadStatus: React.Dispatch<React.SetStateAction<BatchUploadStatus | null>>
|
|
|
|
// 拖拽状态操作
|
|
setIsDragging: React.Dispatch<React.SetStateAction<boolean>>
|
|
setIsDisplayImageDragging: React.Dispatch<React.SetStateAction<boolean>>
|
|
setIsPreviewDragging: React.Dispatch<React.SetStateAction<boolean>>
|
|
setBatchPreviewDragging: React.Dispatch<React.SetStateAction<Record<string, boolean>>>
|
|
}
|
|
|
|
/**
|
|
* Refs 接口
|
|
*/
|
|
export interface UploadRefs {
|
|
previewInputRef: React.RefObject<HTMLInputElement>
|
|
zipInputRef: React.RefObject<HTMLInputElement>
|
|
dropZoneRef: React.RefObject<HTMLDivElement>
|
|
displayImageDropZoneRef: React.RefObject<HTMLDivElement>
|
|
previewDropZoneRef: React.RefObject<HTMLDivElement>
|
|
xhrRef: React.MutableRefObject<XMLHttpRequest | null>
|
|
batchFileInputRef: React.RefObject<HTMLInputElement>
|
|
batchUploadCancelRef: React.MutableRefObject<{ cancelled: boolean }>
|
|
batchUploadXhrRefs: React.MutableRefObject<Map<string, XMLHttpRequest>>
|
|
batchUploadIdsRef: React.MutableRefObject<Map<string, string>>
|
|
}
|
|
|
|
/**
|
|
* 上传状态管理 Hook
|
|
*/
|
|
export function useUploadState() {
|
|
// 预览图片
|
|
const [previewImages, setPreviewImages] = useState<File[]>([])
|
|
const [previewUrls, setPreviewUrls] = useState<string[]>([])
|
|
|
|
// 详情页展示图片
|
|
const [displayImage, setDisplayImage] = useState<File | null>(null)
|
|
const [displayImageUrl, setDisplayImageUrl] = useState<string>('')
|
|
|
|
// 模特图片
|
|
const [modelImages, setModelImages] = useState<File[]>([])
|
|
const [modelImageUrls, setModelImageUrls] = useState<string[]>([])
|
|
|
|
// 素材文件
|
|
const [zipFile, setZipFile] = useState<File | null>(null)
|
|
|
|
// 表单字段
|
|
const [productModel, setProductModel] = useState('')
|
|
const [categoryName, setCategoryName] = useState('')
|
|
const [sceneName, setSceneName] = useState('')
|
|
const [platformName, setPlatformName] = useState('')
|
|
const [productCategoryName, setProductCategoryName] = useState('')
|
|
const [materialType, setMaterialType] = useState('3D场景')
|
|
const [renderer, setRenderer] = useState('CR')
|
|
|
|
// 新建分类输入
|
|
const [showNewCategoryInput, setShowNewCategoryInput] = useState(false)
|
|
const [newCategoryName, setNewCategoryName] = useState('')
|
|
const [showNewSceneInput, setShowNewSceneInput] = useState(false)
|
|
const [newSceneName, setNewSceneName] = useState('')
|
|
|
|
// 上传状态
|
|
const [uploading, setUploading] = useState(false)
|
|
const [uploadProgress, setUploadProgress] = useState(0)
|
|
const [uploadSpeed, setUploadSpeed] = useState(0)
|
|
const [isProcessing, setIsProcessing] = useState(false)
|
|
const [error, setError] = useState('')
|
|
const [retryCount, setRetryCount] = useState(0)
|
|
|
|
// 批量上传
|
|
const [batchFiles, setBatchFiles] = useState<BatchFileItem[]>([])
|
|
const [isBatchMode, setIsBatchMode] = useState(false)
|
|
const [batchUploadStatus, setBatchUploadStatus] = useState<BatchUploadStatus | null>(null)
|
|
|
|
// 拖拽状态
|
|
const [isDragging, setIsDragging] = useState(false)
|
|
const [isDisplayImageDragging, setIsDisplayImageDragging] = useState(false)
|
|
const [isPreviewDragging, setIsPreviewDragging] = useState(false)
|
|
const [batchPreviewDragging, setBatchPreviewDragging] = useState<Record<string, boolean>>({})
|
|
|
|
// Refs
|
|
const previewInputRef = useRef<HTMLInputElement>(null)
|
|
const zipInputRef = useRef<HTMLInputElement>(null)
|
|
const dropZoneRef = useRef<HTMLDivElement>(null)
|
|
const displayImageDropZoneRef = useRef<HTMLDivElement>(null)
|
|
const previewDropZoneRef = useRef<HTMLDivElement>(null)
|
|
const xhrRef = useRef<XMLHttpRequest | null>(null)
|
|
const batchFileInputRef = useRef<HTMLInputElement>(null)
|
|
const batchUploadCancelRef = useRef<{ cancelled: boolean }>({ cancelled: false })
|
|
const batchUploadXhrRefs = useRef<Map<string, XMLHttpRequest>>(new Map())
|
|
const batchUploadIdsRef = useRef<Map<string, string>>(new Map())
|
|
|
|
const state: UploadState = {
|
|
previewImages,
|
|
previewUrls,
|
|
displayImage,
|
|
displayImageUrl,
|
|
modelImages,
|
|
modelImageUrls,
|
|
zipFile,
|
|
productModel,
|
|
categoryName,
|
|
sceneName,
|
|
platformName,
|
|
productCategoryName,
|
|
materialType,
|
|
renderer,
|
|
showNewCategoryInput,
|
|
newCategoryName,
|
|
showNewSceneInput,
|
|
newSceneName,
|
|
uploading,
|
|
uploadProgress,
|
|
uploadSpeed,
|
|
isProcessing,
|
|
error,
|
|
retryCount,
|
|
batchFiles,
|
|
isBatchMode,
|
|
batchUploadStatus,
|
|
isDragging,
|
|
isDisplayImageDragging,
|
|
isPreviewDragging,
|
|
batchPreviewDragging,
|
|
}
|
|
|
|
const actions: UploadStateActions = {
|
|
setPreviewImages,
|
|
setPreviewUrls,
|
|
setDisplayImage,
|
|
setDisplayImageUrl,
|
|
setModelImages,
|
|
setModelImageUrls,
|
|
setZipFile,
|
|
setProductModel,
|
|
setCategoryName,
|
|
setSceneName,
|
|
setPlatformName,
|
|
setProductCategoryName,
|
|
setMaterialType,
|
|
setRenderer,
|
|
setShowNewCategoryInput,
|
|
setNewCategoryName,
|
|
setShowNewSceneInput,
|
|
setNewSceneName,
|
|
setUploading,
|
|
setUploadProgress,
|
|
setUploadSpeed,
|
|
setIsProcessing,
|
|
setError,
|
|
setRetryCount,
|
|
setBatchFiles,
|
|
setIsBatchMode,
|
|
setBatchUploadStatus,
|
|
setIsDragging,
|
|
setIsDisplayImageDragging,
|
|
setIsPreviewDragging,
|
|
setBatchPreviewDragging,
|
|
}
|
|
|
|
const refs: UploadRefs = {
|
|
previewInputRef,
|
|
zipInputRef,
|
|
dropZoneRef,
|
|
displayImageDropZoneRef,
|
|
previewDropZoneRef,
|
|
xhrRef,
|
|
batchFileInputRef,
|
|
batchUploadCancelRef,
|
|
batchUploadXhrRefs,
|
|
batchUploadIdsRef,
|
|
}
|
|
|
|
return { state, actions, refs }
|
|
}
|