fix(scene-editor): 优化场景加载逻辑,增加导入状态管理,改善用户体验

This commit is contained in:
xudan 2025-10-27 16:59:06 +08:00
parent f7cd51c679
commit 85f7b94313

View File

@ -60,43 +60,48 @@ const normalizeSceneJson = (raw: unknown): unknown => {
//#region
const readScene = async () => {
const res = await getSceneById(props.id);
title.value = res?.label ?? '';
const sceneJson = normalizeSceneJson(res?.json);
isImporting.value = true;
try {
const res = await getSceneById(props.id);
title.value = res?.label ?? '';
const sceneJson = normalizeSceneJson(res?.json);
requireImportTransform.value = false;
//
if (Array.isArray(sceneJson)) {
if (sceneJson.length > 0) {
//
floorScenes.value = sceneJson;
floorImportFlags.value = new Array(sceneJson.length).fill(false);
requireImportTransform.value = false;
//
if (Array.isArray(sceneJson)) {
if (sceneJson.length > 0) {
//
floorScenes.value = sceneJson;
floorImportFlags.value = new Array(sceneJson.length).fill(false);
currentFloorIndex.value = 0;
previousFloorIndex.value = 0;
editor.value?.load(floorScenes.value[0], editable.value, undefined, floorImportFlags.value[0] ?? false);
} else {
//
message.warn('场景文件为空数组');
floorScenes.value = [{}]; //
floorImportFlags.value = [false];
currentFloorIndex.value = 0;
previousFloorIndex.value = 0;
editor.value?.load('{}', editable.value, undefined, false);
}
} else if (sceneJson && typeof sceneJson === 'object' && Object.keys(sceneJson).length > 0) {
//
floorScenes.value = [sceneJson];
floorImportFlags.value = [false];
currentFloorIndex.value = 0;
previousFloorIndex.value = 0;
editor.value?.load(floorScenes.value[0], editable.value, undefined, floorImportFlags.value[0] ?? false);
} else {
//
message.warn('场景文件为空数组');
message.warn('场景文件为空或格式不正确');
floorScenes.value = [{}]; //
floorImportFlags.value = [false];
currentFloorIndex.value = 0;
previousFloorIndex.value = 0;
editor.value?.load('{}', editable.value, undefined, false);
}
} else if (sceneJson && typeof sceneJson === 'object' && Object.keys(sceneJson).length > 0) {
//
floorScenes.value = [sceneJson];
floorImportFlags.value = [false];
currentFloorIndex.value = 0;
previousFloorIndex.value = 0;
editor.value?.load(floorScenes.value[0], editable.value, undefined, floorImportFlags.value[0] ?? false);
} else {
message.warn('场景文件为空或格式不正确');
floorScenes.value = [{}]; //
floorImportFlags.value = [false];
currentFloorIndex.value = 0;
previousFloorIndex.value = 0;
editor.value?.load('{}', editable.value, undefined, false);
} finally {
isImporting.value = false;
}
};
@ -208,6 +213,8 @@ const isMultiFloor = computed(() => floorScenes.value.length > 1);
const requireImportTransform = ref(false);
// floorScenes
const floorImportFlags = ref<boolean[]>([]);
//
const isImporting = ref(false);
onMounted(() => {
document.title = '场景编辑器';
@ -345,6 +352,7 @@ const openImportModal = () => {
};
const handleImportConfirm = async () => {
isImporting.value = true;
try {
/* NORMAL_IMPORT_DISABLED
if (importMode.value === 'normal') {
@ -417,7 +425,7 @@ const handleImportConfirm = async () => {
console.log('[MapConverter] OriginalProperties by floor:', OriginalProperties.value);
console.log('[MapConverter] Request payload (object):', payload);
console.log('[MapConverter] Request payload (JSON):', JSON.stringify(payload, null, 2));
message.info('已在控制台打印请求参数');
// message.info('');
} catch {
//
}
@ -496,10 +504,13 @@ const handleImportConfirm = async () => {
} catch (error) {
console.error('导入失败:', error);
message.error(`导入失败: ${(error as Error).message || '请检查文件格式或内容。'}`);
} finally {
isImporting.value = false;
}
};
const processAndLoadSceneData = async (sceneData: any) => {
isImporting.value = true;
try {
//
if (Array.isArray(sceneData)) {
@ -552,33 +563,43 @@ const processAndLoadSceneData = async (sceneData: any) => {
message.error('导入失败文件不是有效的JSON格式或数据无法加载。');
//
throw error;
} finally {
isImporting.value = false;
}
};
const importSmapModalVisible = ref(false);
const handleImportSmapConfirm = async ({ smapFile, keepProperties }: { smapFile: File; keepProperties: boolean }) => {
let sceneJson: string | null = null;
if (keepProperties) {
// Update mode
const currentSceneJson = editor.value?.save();
if (!currentSceneJson) {
message.error('无法获取当前场景数据,请确保场景不为空');
return;
isImporting.value = true;
try {
let sceneJson: string | null = null;
if (keepProperties) {
// Update mode
const currentSceneJson = editor.value?.save();
if (!currentSceneJson) {
message.error('无法获取当前场景数据,请确保场景不为空');
return;
}
const sceneBlob = new Blob([currentSceneJson], { type: 'application/json' });
const sceneFile = new File([sceneBlob], `${title.value || 'current'}.scene`, {
type: 'application/json',
});
sceneJson = await convertSmapToScene(smapFile, sceneFile);
} else {
// Create mode
sceneJson = await convertSmapToScene(smapFile);
}
const sceneBlob = new Blob([currentSceneJson], { type: 'application/json' });
const sceneFile = new File([sceneBlob], `${title.value || 'current'}.scene`, {
type: 'application/json',
});
sceneJson = await convertSmapToScene(smapFile, sceneFile);
} else {
// Create mode
sceneJson = await convertSmapToScene(smapFile);
}
if (sceneJson) {
requireImportTransform.value = true;
editor.value?.load(sceneJson, editable.value, undefined, requireImportTransform.value);
if (sceneJson) {
requireImportTransform.value = true;
editor.value?.load(sceneJson, editable.value, undefined, requireImportTransform.value);
}
} catch (error) {
console.error('导入 SMAP 文件失败:', error);
message.error('导入 SMAP 文件失败');
} finally {
isImporting.value = false;
}
};
@ -748,7 +769,7 @@ const handleFloorChange = async (value: any) => {
</a-button>
<a-button @click="toPush">{{ $t('推送') }}</a-button>
<a-dropdown-button @click="openImportModal" :loading="isConverting">
<a-dropdown-button @click="openImportModal" :loading="isConverting || isImporting">
{{ $t('导入') }}
<template #overlay>
<a-menu>
@ -929,7 +950,7 @@ const handleFloorChange = async (value: any) => {
<span class="hint-text">* 多文件仅支持 smap请确保 floors 连续且类型与后缀一致</span>
<a-space>
<a-button @click="importModalVisible = false">取消</a-button>
<a-button type="primary" @click="handleImportConfirm">导入</a-button>
<a-button type="primary" @click="handleImportConfirm" :loading="isImporting">导入</a-button>
</a-space>
</div>
</div>
@ -1079,6 +1100,7 @@ const handleFloorChange = async (value: any) => {
padding: 16px;
border-radius: 4px;
margin-bottom: 16px;
&:last-child {
margin-bottom: 0;
}
@ -1087,5 +1109,8 @@ html[theme='dark'] {
.sider-toggle {
background-color: #5a5d5e;
}
.floor-uploader-item {
border: 1px solid #141414;
}
}
</style>