diff --git a/components/scene-fusion-view.tsx b/components/scene-fusion-view.tsx index 1587d74..249a458 100644 --- a/components/scene-fusion-view.tsx +++ b/components/scene-fusion-view.tsx @@ -88,6 +88,7 @@ export function SceneFusionView({ onBack, initialProductImage, initialProductNam // 状态管理 const [productImage, setProductImage] = useState(null); + const [productImagePreview, setProductImagePreview] = useState(null); const [productName, setProductName] = useState(initialProductName || ""); // 产品名称(如"沙发") const [scenes, setScenes] = useState([]); const [isProcessing, setIsProcessing] = useState(false); @@ -97,14 +98,41 @@ export function SceneFusionView({ onBack, initialProductImage, initialProductNam // 文件上传 Input 引用 const productInputRef = useRef(null); const sceneInputRef = useRef(null); + const productPreviewObjectUrlRef = useRef(null); // 如果外部传入了初始产品图,则在首次挂载或传入值变化时自动带入 + const updateProductPreview = (previewUrl: string | null, isObjectUrl = false) => { + if (productPreviewObjectUrlRef.current) { + URL.revokeObjectURL(productPreviewObjectUrlRef.current); + productPreviewObjectUrlRef.current = null; + } + setProductImagePreview(previewUrl); + if (isObjectUrl && previewUrl) { + productPreviewObjectUrlRef.current = previewUrl; + } + }; + + const clearProductImage = () => { + setProductImage(null); + updateProductPreview(null); + }; + useEffect(() => { if (initialProductImage) { setProductImage(initialProductImage); + updateProductPreview(initialProductImage); } }, [initialProductImage]); + useEffect(() => { + return () => { + if (productPreviewObjectUrlRef.current) { + URL.revokeObjectURL(productPreviewObjectUrlRef.current); + productPreviewObjectUrlRef.current = null; + } + }; + }, []); + // 处理产品图上传 const handleProductUpload = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; @@ -115,9 +143,23 @@ export function SceneFusionView({ onBack, initialProductImage, initialProductNam return; } + setProductImage(null); + const previewUrl = URL.createObjectURL(file); + updateProductPreview(previewUrl, true); + const reader = new FileReader(); reader.onload = (e) => { - setProductImage(e.target?.result as string); + const result = e.target?.result; + if (typeof result === "string") { + setProductImage(result); + } else { + toast.error("图片读取失败,请重试"); + clearProductImage(); + } + }; + reader.onerror = () => { + toast.error("图片读取失败,请重试"); + clearProductImage(); }; reader.readAsDataURL(file); // 重置 input,允许重复选择同一文件 @@ -590,8 +632,8 @@ export function SceneFusionView({ onBack, initialProductImage, initialProductNam
- {productImage && ( - )} @@ -600,9 +642,9 @@ export function SceneFusionView({ onBack, initialProductImage, initialProductNam
!productImage && productInputRef.current?.click()} + onClick={() => !(productImagePreview || productImage) && productInputRef.current?.click()} > - {productImage ? ( + {(productImagePreview || productImage) ? (
- 产品图 + 产品图
{/* 产品名称输入 */} - {productImage && ( + {(productImagePreview || productImage) && (
); -} \ No newline at end of file +}