import { useCallback, useState } from "react"; import api from "@/shared/api/axios"; interface Material { id: string; name: string; scene: string; size_mb: number; path: string; } interface UseMaterialsOptions { selectedMaterial: string; setSelectedMaterial: React.Dispatch>; } export const useMaterials = ({ selectedMaterial, setSelectedMaterial, }: UseMaterialsOptions) => { const [materials, setMaterials] = useState([]); const [fetchError, setFetchError] = useState(null); const [isUploading, setIsUploading] = useState(false); const [uploadProgress, setUploadProgress] = useState(0); const [uploadError, setUploadError] = useState(null); const fetchMaterials = useCallback(async () => { try { setFetchError(null); const { data } = await api.get(`/api/materials?t=${new Date().getTime()}`); const nextMaterials = data.materials || []; setMaterials(nextMaterials); const nextSelected = nextMaterials.find((item: Material) => item.id === selectedMaterial)?.id || nextMaterials[0]?.id || ""; if (nextSelected !== selectedMaterial) { setSelectedMaterial(nextSelected); } } catch (error) { console.error("获取素材失败:", error); setFetchError(String(error)); } }, [selectedMaterial, setSelectedMaterial]); const deleteMaterial = useCallback(async (materialId: string) => { if (!confirm("确定要删除这个素材吗?")) return; try { await api.delete(`/api/materials/${materialId}`); fetchMaterials(); if (selectedMaterial === materialId) { setSelectedMaterial(""); } } catch (error) { alert("删除失败: " + error); } }, [fetchMaterials, selectedMaterial, setSelectedMaterial]); const handleUpload = useCallback(async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; const validTypes = ['.mp4', '.mov', '.avi']; const ext = file.name.toLowerCase().slice(file.name.lastIndexOf('.')); if (!validTypes.includes(ext)) { setUploadError('仅支持 MP4、MOV、AVI 格式'); return; } setIsUploading(true); setUploadProgress(0); setUploadError(null); try { const formData = new FormData(); formData.append('file', file); await api.post('/api/materials', formData, { headers: { 'Content-Type': 'multipart/form-data' }, onUploadProgress: (progressEvent) => { if (progressEvent.total) { const progress = Math.round((progressEvent.loaded / progressEvent.total) * 100); setUploadProgress(progress); } }, }); setUploadProgress(100); setIsUploading(false); fetchMaterials(); } catch (err: any) { console.error("Upload failed:", err); setIsUploading(false); const errorMsg = err.response?.data?.detail || err.message || String(err); setUploadError(`上传失败: ${errorMsg}`); } e.target.value = ''; }, [fetchMaterials]); return { materials, fetchError, isUploading, uploadProgress, uploadError, setUploadError, fetchMaterials, deleteMaterial, handleUpload, }; };