diff --git a/web/src/pages/app/modules/models.ts b/web/src/pages/app/modules/models.ts index 90b944e..932ddd5 100644 --- a/web/src/pages/app/modules/models.ts +++ b/web/src/pages/app/modules/models.ts @@ -35,6 +35,7 @@ type SceneModelMessagePayload = { type SceneModelMessage = { type?: string; + requestId?: string; payload?: SceneModelMessagePayload; message?: string; }; @@ -42,6 +43,8 @@ type SceneModelMessage = { let dictionariesLoaded = false; let dictionariesLoading: Promise | null = null; let sceneModelBridgeBound = false; +let pendingSceneModelRequestId = ""; +let pendingSceneModelRequestTimer: number | null = null; export function bindModelActions() { const isAdmin = getCurrentUser()?.role === "admin"; @@ -305,13 +308,26 @@ function requestSceneModelImport() { notify("请在 DMT 主程序中使用导入场景模型"); return; } + const requestId = createSceneModelRequestId(); + pendingSceneModelRequestId = requestId; + clearSceneModelRequestTimer(); + pendingSceneModelRequestTimer = window.setTimeout(() => { + if (pendingSceneModelRequestId !== requestId) return; + pendingSceneModelRequestId = ""; + pendingSceneModelRequestTimer = null; + notifyError("主程序未响应导入场景模型请求,请确认模型库是在主程序面板中打开"); + }, 15000); window.parent.postMessage({ - type: requestSceneModelMessageType + type: requestSceneModelMessageType, + requestId }, resolveParentOrigin()); notify("已请求主程序导出当前选中模型"); } async function handleSceneModelMessage(data: SceneModelMessage) { + if (pendingSceneModelRequestId && data.requestId && data.requestId !== pendingSceneModelRequestId) return; + pendingSceneModelRequestId = ""; + clearSceneModelRequestTimer(); if (data.type === sceneModelErrorMessageType) { notifyError(data.message || "主程序导出模型失败"); return; @@ -332,6 +348,16 @@ async function handleSceneModelMessage(data: SceneModelMessage) { }); } +function clearSceneModelRequestTimer() { + if (pendingSceneModelRequestTimer === null) return; + window.clearTimeout(pendingSceneModelRequestTimer); + pendingSceneModelRequestTimer = null; +} + +function createSceneModelRequestId() { + return `scene-model-${Date.now()}-${Math.random().toString(36).slice(2)}`; +} + function isAllowedParentOrigin(origin: string) { const expectedOrigin = resolveParentOrigin(); return expectedOrigin === "*" || origin === expectedOrigin;