fix: fix upload bug 3d
This commit is contained in:
@@ -3,6 +3,78 @@ import { OrbitControls, Stage, useGLTF } from "@react-three/drei";
|
||||
import { useEffect, Suspense } from "react";
|
||||
import { Box, CircularProgress, Typography } from "@mui/material";
|
||||
|
||||
// Утилита для очистки кеша GLTF
|
||||
const clearGLTFCache = (url?: string) => {
|
||||
try {
|
||||
if (url) {
|
||||
// Если это blob URL, очищаем его из кеша
|
||||
if (url.startsWith("blob:")) {
|
||||
useGLTF.clear(url);
|
||||
console.log("🧹 clearGLTFCache: Очистка blob URL из кеша GLTF", {
|
||||
url,
|
||||
});
|
||||
} else {
|
||||
useGLTF.clear(url);
|
||||
console.log("🧹 clearGLTFCache: Очистка кеша для URL", { url });
|
||||
}
|
||||
} else {
|
||||
// Очищаем весь кеш GLTF
|
||||
useGLTF.clear();
|
||||
console.log("🧹 clearGLTFCache: Очистка всего кеша GLTF");
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("⚠️ clearGLTFCache: Ошибка при очистке кеша", error);
|
||||
}
|
||||
};
|
||||
|
||||
// Утилита для проверки типа файла
|
||||
const isValid3DFile = (url: string): boolean => {
|
||||
try {
|
||||
const urlObj = new URL(url);
|
||||
const pathname = urlObj.pathname.toLowerCase();
|
||||
const searchParams = urlObj.searchParams;
|
||||
|
||||
// Проверяем расширение файла в пути
|
||||
const validExtensions = [".glb", ".gltf"];
|
||||
const hasValidExtension = validExtensions.some((ext) =>
|
||||
pathname.endsWith(ext)
|
||||
);
|
||||
|
||||
// Проверяем параметры запроса на наличие типа файла
|
||||
const fileType = searchParams.get("type") || searchParams.get("format");
|
||||
const hasValidType =
|
||||
fileType && ["glb", "gltf"].includes(fileType.toLowerCase());
|
||||
|
||||
// Если это blob URL, считаем его валидным (пользователь выбрал файл)
|
||||
const isBlobUrl = url.startsWith("blob:");
|
||||
|
||||
// Если это URL с токеном и нет явного расширения, считаем валидным
|
||||
// (предполагаем что сервер вернет правильный файл)
|
||||
const hasToken = searchParams.has("token");
|
||||
const isServerUrl = hasToken && !hasValidExtension;
|
||||
|
||||
const isValid =
|
||||
hasValidExtension || hasValidType || isBlobUrl || isServerUrl;
|
||||
|
||||
console.log("🔍 isValid3DFile: Проверка файла", {
|
||||
url,
|
||||
pathname,
|
||||
hasValidExtension,
|
||||
fileType,
|
||||
hasValidType,
|
||||
isBlobUrl,
|
||||
isServerUrl,
|
||||
isValid,
|
||||
});
|
||||
|
||||
return isValid;
|
||||
} catch (error) {
|
||||
console.warn("⚠️ isValid3DFile: Ошибка при проверке URL", error);
|
||||
// В случае ошибки парсинга URL, считаем валидным (пусть useGLTF сам разберется)
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
type ModelViewerProps = {
|
||||
width?: string;
|
||||
fileUrl: string;
|
||||
@@ -10,6 +82,18 @@ type ModelViewerProps = {
|
||||
};
|
||||
|
||||
const Model = ({ fileUrl }: { fileUrl: string }) => {
|
||||
// Очищаем кеш перед загрузкой новой модели
|
||||
useEffect(() => {
|
||||
// Очищаем кеш для текущего URL
|
||||
clearGLTFCache(fileUrl);
|
||||
}, [fileUrl]);
|
||||
|
||||
// Проверяем валидность файла перед загрузкой (только для blob URL)
|
||||
if (fileUrl.startsWith("blob:") && !isValid3DFile(fileUrl)) {
|
||||
console.warn("⚠️ Model: Попытка загрузить невалидный 3D файл", { fileUrl });
|
||||
throw new Error(`Файл не является корректной 3D моделью: ${fileUrl}`);
|
||||
}
|
||||
|
||||
const { scene } = useGLTF(fileUrl);
|
||||
return <primitive object={scene} />;
|
||||
};
|
||||
@@ -49,11 +133,26 @@ export const ThreeView = ({
|
||||
height = "100%",
|
||||
width = "100%",
|
||||
}: ModelViewerProps) => {
|
||||
// Очищаем кеш при размонтировании
|
||||
// Проверяем валидность файла (только для blob URL)
|
||||
useEffect(() => {
|
||||
if (fileUrl.startsWith("blob:") && !isValid3DFile(fileUrl)) {
|
||||
console.warn("⚠️ ThreeView: Невалидный 3D файл", { fileUrl });
|
||||
}
|
||||
}, [fileUrl]);
|
||||
|
||||
// Очищаем кеш при размонтировании и при смене URL
|
||||
useEffect(() => {
|
||||
// Очищаем кеш сразу при монтировании компонента
|
||||
clearGLTFCache(fileUrl);
|
||||
console.log("🧹 ThreeView: Очистка кеша модели при монтировании", {
|
||||
fileUrl,
|
||||
});
|
||||
|
||||
return () => {
|
||||
useGLTF.clear(fileUrl);
|
||||
console.log("🧹 ThreeView: Очистка кеша модели", { fileUrl });
|
||||
clearGLTFCache(fileUrl);
|
||||
console.log("🧹 ThreeView: Очистка кеша модели при размонтировании", {
|
||||
fileUrl,
|
||||
});
|
||||
};
|
||||
}, [fileUrl]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user