feat(scene-editor): 新增对接 JSZip 库以支持 ZIP 文件导入,优化导入逻辑
This commit is contained in:
parent
11cdde454c
commit
259c881469
@ -17,6 +17,7 @@
|
||||
"ant-design-vue": "^4.2.6",
|
||||
"axios": "^1.8.4",
|
||||
"dayjs": "^1.11.13",
|
||||
"jszip": "^3.10.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
"pinia": "^3.0.3",
|
||||
"rxjs": "^7.8.2",
|
||||
|
||||
70
pnpm-lock.yaml
generated
70
pnpm-lock.yaml
generated
@ -29,6 +29,9 @@ importers:
|
||||
dayjs:
|
||||
specifier: ^1.11.13
|
||||
version: 1.11.13
|
||||
jszip:
|
||||
specifier: ^3.10.1
|
||||
version: 3.10.1
|
||||
lodash-es:
|
||||
specifier: ^4.17.21
|
||||
version: 4.17.21
|
||||
@ -1004,6 +1007,9 @@ packages:
|
||||
core-js@3.45.1:
|
||||
resolution: {integrity: sha512-L4NPsJlCfZsPeXukyzHFlg/i7IIVwHSItR0wg0FLNqYClJ4MQYTYLbC7EkjKYRLZF2iof2MUgN0EGy7MdQFChg==}
|
||||
|
||||
core-util-is@1.0.3:
|
||||
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
|
||||
|
||||
cosmiconfig@9.0.0:
|
||||
resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==}
|
||||
engines: {node: '>=14'}
|
||||
@ -1380,6 +1386,9 @@ packages:
|
||||
resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
|
||||
engines: {node: '>= 4'}
|
||||
|
||||
immediate@3.0.6:
|
||||
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
|
||||
|
||||
immutable@5.1.3:
|
||||
resolution: {integrity: sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==}
|
||||
|
||||
@ -1436,6 +1445,9 @@ packages:
|
||||
resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
|
||||
engines: {node: '>=12.13'}
|
||||
|
||||
isarray@1.0.0:
|
||||
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
|
||||
|
||||
isexe@2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
|
||||
@ -1467,6 +1479,9 @@ packages:
|
||||
json-stable-stringify-without-jsonify@1.0.1:
|
||||
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
|
||||
|
||||
jszip@3.10.1:
|
||||
resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==}
|
||||
|
||||
keyv@4.5.4:
|
||||
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
|
||||
|
||||
@ -1491,6 +1506,9 @@ packages:
|
||||
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
||||
lie@3.3.0:
|
||||
resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
|
||||
|
||||
lines-and-columns@1.2.4:
|
||||
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
|
||||
|
||||
@ -1630,6 +1648,9 @@ packages:
|
||||
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
pako@1.0.11:
|
||||
resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
|
||||
|
||||
parent-module@1.0.1:
|
||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||
engines: {node: '>=6'}
|
||||
@ -1765,6 +1786,9 @@ packages:
|
||||
queue-microtask@1.2.3:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
|
||||
readable-stream@2.3.8:
|
||||
resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
|
||||
|
||||
readable-stream@3.6.2:
|
||||
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
|
||||
engines: {node: '>= 6'}
|
||||
@ -1813,6 +1837,9 @@ packages:
|
||||
rxjs@7.8.2:
|
||||
resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==}
|
||||
|
||||
safe-buffer@5.1.2:
|
||||
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
|
||||
|
||||
safe-buffer@5.2.1:
|
||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||
|
||||
@ -1946,6 +1973,9 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
setimmediate@1.0.5:
|
||||
resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
|
||||
|
||||
shallow-equal@1.2.1:
|
||||
resolution: {integrity: sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==}
|
||||
|
||||
@ -1987,6 +2017,9 @@ packages:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
string_decoder@1.1.1:
|
||||
resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
|
||||
|
||||
string_decoder@1.3.0:
|
||||
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
||||
|
||||
@ -3128,6 +3161,8 @@ snapshots:
|
||||
|
||||
core-js@3.45.1: {}
|
||||
|
||||
core-util-is@1.0.3: {}
|
||||
|
||||
cosmiconfig@9.0.0(typescript@5.7.3):
|
||||
dependencies:
|
||||
env-paths: 2.2.1
|
||||
@ -3535,6 +3570,8 @@ snapshots:
|
||||
|
||||
ignore@7.0.5: {}
|
||||
|
||||
immediate@3.0.6: {}
|
||||
|
||||
immutable@5.1.3: {}
|
||||
|
||||
import-fresh@3.3.1:
|
||||
@ -3575,6 +3612,8 @@ snapshots:
|
||||
|
||||
is-what@4.1.16: {}
|
||||
|
||||
isarray@1.0.0: {}
|
||||
|
||||
isexe@2.0.0: {}
|
||||
|
||||
js-sdsl@4.3.0: {}
|
||||
@ -3597,6 +3636,13 @@ snapshots:
|
||||
|
||||
json-stable-stringify-without-jsonify@1.0.1: {}
|
||||
|
||||
jszip@3.10.1:
|
||||
dependencies:
|
||||
lie: 3.3.0
|
||||
pako: 1.0.11
|
||||
readable-stream: 2.3.8
|
||||
setimmediate: 1.0.5
|
||||
|
||||
keyv@4.5.4:
|
||||
dependencies:
|
||||
json-buffer: 3.0.1
|
||||
@ -3618,6 +3664,10 @@ snapshots:
|
||||
prelude-ls: 1.2.1
|
||||
type-check: 0.4.0
|
||||
|
||||
lie@3.3.0:
|
||||
dependencies:
|
||||
immediate: 3.0.6
|
||||
|
||||
lines-and-columns@1.2.4: {}
|
||||
|
||||
local-pkg@1.1.2:
|
||||
@ -3773,6 +3823,8 @@ snapshots:
|
||||
dependencies:
|
||||
p-limit: 3.1.0
|
||||
|
||||
pako@1.0.11: {}
|
||||
|
||||
parent-module@1.0.1:
|
||||
dependencies:
|
||||
callsites: 3.1.0
|
||||
@ -3887,6 +3939,16 @@ snapshots:
|
||||
|
||||
queue-microtask@1.2.3: {}
|
||||
|
||||
readable-stream@2.3.8:
|
||||
dependencies:
|
||||
core-util-is: 1.0.3
|
||||
inherits: 2.0.4
|
||||
isarray: 1.0.0
|
||||
process-nextick-args: 2.0.1
|
||||
safe-buffer: 5.1.2
|
||||
string_decoder: 1.1.1
|
||||
util-deprecate: 1.0.2
|
||||
|
||||
readable-stream@3.6.2:
|
||||
dependencies:
|
||||
inherits: 2.0.4
|
||||
@ -3948,6 +4010,8 @@ snapshots:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
safe-buffer@5.1.2: {}
|
||||
|
||||
safe-buffer@5.2.1: {}
|
||||
|
||||
sass-embedded-all-unknown@1.91.0:
|
||||
@ -4053,6 +4117,8 @@ snapshots:
|
||||
|
||||
semver@7.7.2: {}
|
||||
|
||||
setimmediate@1.0.5: {}
|
||||
|
||||
shallow-equal@1.2.1: {}
|
||||
|
||||
shebang-command@2.0.0:
|
||||
@ -4087,6 +4153,10 @@ snapshots:
|
||||
is-fullwidth-code-point: 3.0.0
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
string_decoder@1.1.1:
|
||||
dependencies:
|
||||
safe-buffer: 5.1.2
|
||||
|
||||
string_decoder@1.3.0:
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
// 门区域功能改造:由助手自动插入
|
||||
import { DOOR_AREA_TYPE } from '@api/map/door-area';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import JSZip from 'jszip';
|
||||
import { computed, onMounted, onUnmounted, provide, ref, type ShallowRef, shallowRef, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
@ -287,7 +288,7 @@ const toPush = () => {
|
||||
|
||||
// --- Import/Update Logic ---
|
||||
const importModalVisible = ref(false);
|
||||
const importMode = ref<'normal' | 'floor'>('normal');
|
||||
const importMode = ref<'normal' | 'floor'>('floor');
|
||||
const normalImportFileList = ref([]);
|
||||
const normalImportKeepProperties = ref(true);
|
||||
const floorImportList = ref([{ name: 'F1', fileList: [], keepProperties: true }]);
|
||||
@ -319,13 +320,16 @@ const addFloor = () => {
|
||||
};
|
||||
|
||||
const openImportModal = () => {
|
||||
importMode.value = 'normal';
|
||||
importMode.value = 'floor'; // 默认使用分区域模式
|
||||
importModalVisible.value = true;
|
||||
// 打开时重置为文件选择界面
|
||||
floorImportList.value = [{ name: 'F1', fileList: [], keepProperties: true }];
|
||||
OriginalProperties.value = [];
|
||||
};
|
||||
|
||||
const handleImportConfirm = async () => {
|
||||
try {
|
||||
/* NORMAL_IMPORT_DISABLED
|
||||
if (importMode.value === 'normal') {
|
||||
if (normalImportFileList.value.length === 0) {
|
||||
message.warn('请选择一个文件');
|
||||
@ -366,7 +370,9 @@ const handleImportConfirm = async () => {
|
||||
return;
|
||||
}
|
||||
await processAndLoadSceneData(JSON.parse(sceneJsonString));
|
||||
} else if (importMode.value === 'floor') {
|
||||
}
|
||||
NORMAL_IMPORT_DISABLED */
|
||||
if (importMode.value === 'floor') {
|
||||
// === 新增:对接地图转换服务(含 OriginalProperties 采集) ===
|
||||
try {
|
||||
if (floorImportList.value.some((f) => f.fileList.length === 0)) {
|
||||
@ -402,11 +408,30 @@ const handleImportConfirm = async () => {
|
||||
// 3) 调用转换服务
|
||||
const result = await postProcessJsonList(payload);
|
||||
if (result.kind === 'zip') {
|
||||
const url = URL.createObjectURL(result.blob);
|
||||
const filename = result.filename || 'converted_map.zip';
|
||||
downloadFile(url, filename);
|
||||
URL.revokeObjectURL(url);
|
||||
message.success('转换成功,已下载ZIP结果');
|
||||
try {
|
||||
const zip = await JSZip.loadAsync(result.blob);
|
||||
const sceneFile = Object.values(zip.files).find((file) => file.name.toLowerCase().endsWith('.scene'));
|
||||
|
||||
if (sceneFile) {
|
||||
const sceneJsonString = await sceneFile.async('string');
|
||||
if (!sceneJsonString) {
|
||||
message.error('ZIP中的 .scene 文件内容为空');
|
||||
return;
|
||||
}
|
||||
await processAndLoadSceneData(JSON.parse(sceneJsonString));
|
||||
message.success('已成功从ZIP包中解压并导入场景');
|
||||
} else {
|
||||
message.error('ZIP文件中未找到 .scene 格式的场景文件');
|
||||
// 作为回退,仍然提供下载功能
|
||||
const url = URL.createObjectURL(result.blob);
|
||||
const filename = result.filename || 'converted_map.zip';
|
||||
downloadFile(url, filename);
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
} catch (zipError) {
|
||||
console.error('处理ZIP文件失败:', zipError);
|
||||
message.error('自动解压导入失败,请检查ZIP文件是否有效');
|
||||
}
|
||||
} else {
|
||||
message.success(result?.data?.message || '转换成功');
|
||||
console.log('MapConverter JSON 响应:', result.data);
|
||||
@ -765,12 +790,12 @@ const handleFloorChange = async (value: any) => {
|
||||
|
||||
<a-modal v-model:visible="importModalVisible" title="导入场景" :footer="null" width="800px">
|
||||
<div class="import-modal-content">
|
||||
<div class="mode-switcher">
|
||||
<!-- <div class="mode-switcher">
|
||||
<div :class="['mode-tab', { active: importMode === 'normal' }]" @click="importMode = 'normal'">普通导入</div>
|
||||
<div :class="['mode-tab', { active: importMode === 'floor' }]" @click="importMode = 'floor'">分区域/楼层</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="core-content">
|
||||
<div v-if="importMode === 'normal'">
|
||||
<!-- <div v-if="importMode === 'normal'">
|
||||
<a-upload-dragger
|
||||
v-model:fileList="normalImportFileList"
|
||||
name="file"
|
||||
@ -808,9 +833,9 @@ const handleFloorChange = async (value: any) => {
|
||||
<div style="margin-top: 8px; color: #999; font-size: 12px">
|
||||
提示:支持 .scene 或 .smap。若需上传多个文件,请使用“分楼层/批量”模式。
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- 分区域/楼层模式的内容将在这里添加 -->
|
||||
<div v-else>
|
||||
<div>
|
||||
<div v-for="(floor, index) in floorImportList" :key="index" class="floor-uploader-item">
|
||||
<a-input v-model:value="floor.name" placeholder="楼层/区域名称" style="width: 120px; margin-bottom: 8px" />
|
||||
<a-upload-dragger
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user