/** * 上传状态管理 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 } /** * 上传状态操作接口 */ export interface UploadStateActions { // 预览图片操作 setPreviewImages: React.Dispatch> setPreviewUrls: React.Dispatch> // 详情页展示图片操作 setDisplayImage: React.Dispatch> setDisplayImageUrl: React.Dispatch> // 模特图片操作 setModelImages: React.Dispatch> setModelImageUrls: React.Dispatch> // 素材文件操作 setZipFile: React.Dispatch> // 表单字段操作 setProductModel: React.Dispatch> setCategoryName: React.Dispatch> setSceneName: React.Dispatch> setPlatformName: React.Dispatch> setProductCategoryName: React.Dispatch> setMaterialType: React.Dispatch> setRenderer: React.Dispatch> // 新建分类输入操作 setShowNewCategoryInput: React.Dispatch> setNewCategoryName: React.Dispatch> setShowNewSceneInput: React.Dispatch> setNewSceneName: React.Dispatch> // 上传状态操作 setUploading: React.Dispatch> setUploadProgress: React.Dispatch> setUploadSpeed: React.Dispatch> setIsProcessing: React.Dispatch> setError: React.Dispatch> setRetryCount: React.Dispatch> // 批量上传操作 setBatchFiles: React.Dispatch> setIsBatchMode: React.Dispatch> setBatchUploadStatus: React.Dispatch> // 拖拽状态操作 setIsDragging: React.Dispatch> setIsDisplayImageDragging: React.Dispatch> setIsPreviewDragging: React.Dispatch> setBatchPreviewDragging: React.Dispatch>> } /** * Refs 接口 */ export interface UploadRefs { previewInputRef: React.RefObject zipInputRef: React.RefObject dropZoneRef: React.RefObject displayImageDropZoneRef: React.RefObject previewDropZoneRef: React.RefObject xhrRef: React.MutableRefObject batchFileInputRef: React.RefObject batchUploadCancelRef: React.MutableRefObject<{ cancelled: boolean }> batchUploadXhrRefs: React.MutableRefObject> batchUploadIdsRef: React.MutableRefObject> } /** * 上传状态管理 Hook */ export function useUploadState() { // 预览图片 const [previewImages, setPreviewImages] = useState([]) const [previewUrls, setPreviewUrls] = useState([]) // 详情页展示图片 const [displayImage, setDisplayImage] = useState(null) const [displayImageUrl, setDisplayImageUrl] = useState('') // 模特图片 const [modelImages, setModelImages] = useState([]) const [modelImageUrls, setModelImageUrls] = useState([]) // 素材文件 const [zipFile, setZipFile] = useState(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([]) const [isBatchMode, setIsBatchMode] = useState(false) const [batchUploadStatus, setBatchUploadStatus] = useState(null) // 拖拽状态 const [isDragging, setIsDragging] = useState(false) const [isDisplayImageDragging, setIsDisplayImageDragging] = useState(false) const [isPreviewDragging, setIsPreviewDragging] = useState(false) const [batchPreviewDragging, setBatchPreviewDragging] = useState>({}) // Refs const previewInputRef = useRef(null) const zipInputRef = useRef(null) const dropZoneRef = useRef(null) const displayImageDropZoneRef = useRef(null) const previewDropZoneRef = useRef(null) const xhrRef = useRef(null) const batchFileInputRef = useRef(null) const batchUploadCancelRef = useRef<{ cancelled: boolean }>({ cancelled: false }) const batchUploadXhrRefs = useRef>(new Map()) const batchUploadIdsRef = useRef>(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 } }