feat(all): 离线包迁移

This commit is contained in:
plum 2026-04-08 21:54:54 +08:00
parent 404e804143
commit 151bc7c8a2
6 changed files with 52 additions and 16 deletions

View File

@ -2,7 +2,7 @@
import {nextTick} from "vue"; import {nextTick} from "vue";
import {Save} from "@vicons/carbon"; import {Save} from "@vicons/carbon";
import {t} from "@/language"; import {t} from "@/language";
import {App,Package} from "@astral3d/engine"; import {App} from "@astral3d/engine";
import { useGlobalConfigStore } from '@/store/modules/globalConfig'; import { useGlobalConfigStore } from '@/store/modules/globalConfig';
import {fetchUpload} from "@/http/api/sys"; import {fetchUpload} from "@/http/api/sys";
import {filterSize} from "@/utils/common/file"; import {filterSize} from "@/utils/common/file";
@ -59,7 +59,7 @@ function save(){
globalConfigStore.loadingText = window.$t("scene['Scene is being compressed...']"); globalConfigStore.loadingText = window.$t("scene['Scene is being compressed...']");
const p = new Package(window.viewer); const p = window.viewer.package;
p.pack({ p.pack({
// //
name:`${sceneInfo.sceneName}`, name:`${sceneInfo.sceneName}`,
@ -96,8 +96,6 @@ function save(){
setTimeout(() => { setTimeout(() => {
globalConfigStore.loading = false; globalConfigStore.loading = false;
p.dispose();
}, 500) }, 500)
}) })
} }

View File

@ -1,6 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import {ref, onMounted, nextTick,provide} from 'vue'; import {ref, onMounted, nextTick,provide} from 'vue';
import {Hooks,App,Package,defaultProjectInfo} from "@astral3d/engine"; import {Hooks,App,defaultProjectInfo} from "@astral3d/engine";
import * as Layout from './layouts'; import * as Layout from './layouts';
import {connectWebSocket} from "@/hooks/useWebSocket"; import {connectWebSocket} from "@/hooks/useWebSocket";
import {useRoute} from "vue-router"; import {useRoute} from "vue-router";
@ -82,8 +82,7 @@ function getScene(sceneInfo) {
closable: false, closable: false,
}) })
const p = new Package(window.viewer); window.viewer.package.unpack({
p.unpack({
url: sceneInfo.zip, url: sceneInfo.zip,
onSceneLoad: () => { onSceneLoad: () => {
drawingInfo.value = App.project.getKey("drawing"); drawingInfo.value = App.project.getKey("drawing");
@ -94,8 +93,6 @@ function getScene(sceneInfo) {
Hooks.useDispatchSignal("sceneLoadComplete"); Hooks.useDispatchSignal("sceneLoadComplete");
notice.destroy(); notice.destroy();
p.dispose();
} }
}) })
return; return;

View File

@ -3,7 +3,7 @@ import {nextTick, onMounted, provide, ref} from "vue";
import {useRoute} from 'vue-router'; import {useRoute} from 'vue-router';
import {t} from "@/language"; import {t} from "@/language";
import {fetchGetOneScene} from "@/http/api/scenes"; import {fetchGetOneScene} from "@/http/api/scenes";
import {App,Viewer,Hooks,Package,defaultProjectInfo} from "@astral3d/engine"; import {App,Viewer,Hooks,defaultProjectInfo} from "@astral3d/engine";
import {usePreviewOperationStore} from "@/store/modules/previewOperation"; import {usePreviewOperationStore} from "@/store/modules/previewOperation";
import EsCubeLoading from "@/components/es/EsCubeLoading.vue"; import EsCubeLoading from "@/components/es/EsCubeLoading.vue";
import PreviewSceneTree from "@/views/preview/components/PreviewSceneTree.vue"; import PreviewSceneTree from "@/views/preview/components/PreviewSceneTree.vue";
@ -97,8 +97,7 @@ function getScene(sceneInfo) {
closable: false, closable: false,
}) })
const p = new Package(window.viewer); window.viewer.package.unpack({
p.unpack({
url: sceneInfo.zip, url: sceneInfo.zip,
onSceneLoad: (sceneJson: ISceneJson) => { onSceneLoad: (sceneJson: ISceneJson) => {
if (sceneJson.controls?.state) { if (sceneJson.controls?.state) {

View File

@ -457,7 +457,7 @@ export class Package {
}); });
// 首包上传 // 首包上传
const firstUploadResult = await this.zip(sceneZipData, packConfig.name, packConfig.zipUploadFun); const firstUploadResult = await this.zip(sceneZipData, packConfig.name, packConfig.zipUploadFun, packConfig.rawUploadFun);
// 进度 // 进度
let progress = 0; let progress = 0;
@ -520,7 +520,7 @@ export class Package {
const content = JSON.stringify(json); const content = JSON.stringify(json);
zipData.push({ name, json: content }); zipData.push({ name, json: content });
await this.zip(zipData, group.uuid, packConfig.zipUploadFun); await this.zip(zipData, group.uuid, packConfig.zipUploadFun, packConfig.rawUploadFun);
progress++; progress++;
packConfig.onProgress && packConfig.onProgress(parseFloat((progress / groupArr.length * 100).toFixed(2))); packConfig.onProgress && packConfig.onProgress(parseFloat((progress / groupArr.length * 100).toFixed(2)));
@ -544,7 +544,43 @@ export class Package {
* @param {string | number} zipName * @param {string | number} zipName
* @return {Promise<any>} * @return {Promise<any>}
*/ */
private async zip(sourceData: SourceData[], zipName: string | number, zipUploadFun: (zip: File) => Promise<any>): Promise<any> { private toUint8(data: string | ArrayBuffer | Uint8Array): Uint8Array {
if (data instanceof Uint8Array) return data;
if (typeof data === "string") return strToU8(data);
return new Uint8Array(data);
}
private buildFilesMapFromSourceData(sourceData: SourceData[]): Record<string, Uint8Array> {
const files: Record<string, Uint8Array> = {};
sourceData.forEach((item) => {
if (item.texture) {
files[`Textures/${item.name}`] = this.toUint8(item.texture);
} else if (item.geometry) {
files[`Geometries/${item.name}`] = this.toUint8(item.geometry);
} else if (item.json) {
files[item.name] = this.toUint8(item.json);
} else if (item.drawing) {
files[`Drawing/${item.name}`] = this.toUint8(item.drawing);
}
})
return files;
}
private async zip(
sourceData: SourceData[],
zipName: string | number,
zipUploadFun: (zip: File) => Promise<any>,
rawUploadFun?: (raw: { name: string; files: Record<string, Uint8Array> }) => Promise<any>
): Promise<any> {
if (rawUploadFun) {
const files = this.buildFilesMapFromSourceData(sourceData);
const size = Object.values(files).reduce((sum, data) => sum + data.byteLength, 0);
this.totalSize += size;
return await rawUploadFun({ name: String(zipName), files });
}
const jszip = new JSZip(); const jszip = new JSZip();
const imgFolder = jszip.folder("Textures") as JSZip; // 贴图文件夹 const imgFolder = jszip.folder("Textures") as JSZip; // 贴图文件夹
const geometriesFolder = jszip.folder("Geometries") as JSZip; // 几何数据文件夹 const geometriesFolder = jszip.folder("Geometries") as JSZip; // 几何数据文件夹

View File

@ -32,6 +32,7 @@ import ParticleEmitter from "@/core/objects/ParticleEmitter.ts";
import {ViewerPathTracer} from "@/core/viewer/ViewerPathTracer.ts"; import {ViewerPathTracer} from "@/core/viewer/ViewerPathTracer.ts";
import {Helper as ScriptHelper} from "../script"; import {Helper as ScriptHelper} from "../script";
import Tiles from "../objects/Tile.ts"; import Tiles from "../objects/Tile.ts";
import {Package} from "@/core/loader/Package";
export interface ViewerEventMap { export interface ViewerEventMap {
// 场景加载完成时执行,仅执行一次 // 场景加载完成时执行,仅执行一次
@ -198,6 +199,7 @@ export default class Viewer extends THREE.EventDispatcher<ViewerEventMap> {
public timer = new Timer(); public timer = new Timer();
//整个主场景的box3 //整个主场景的box3
public sceneBox3 = new THREE.Box3(); public sceneBox3 = new THREE.Box3();
public package: Package;
constructor(options: IViewerSetting) { constructor(options: IViewerSetting) {
super(); super();
@ -216,6 +218,7 @@ export default class Viewer extends THREE.EventDispatcher<ViewerEventMap> {
this.renderer = this.createEngine(); this.renderer = this.createEngine();
this.modules = this.initModules(); this.modules = this.initModules();
this.package = new Package(this);
/** helpers **/ /** helpers **/
if (this.options.grid.enabled) { if (this.options.grid.enabled) {
@ -1148,6 +1151,8 @@ export default class Viewer extends THREE.EventDispatcher<ViewerEventMap> {
this.dispatchEvent({type: "afterDestroy"}); this.dispatchEvent({type: "afterDestroy"});
this.unInstallScripts(); this.unInstallScripts();
this.package?.dispose();
this.package = null as any;
} }
/* -----------------暂时放在Viewer下的工具方法-------------------- */ /* -----------------暂时放在Viewer下的工具方法-------------------- */

View File

@ -28,7 +28,8 @@ export default defineConfig(async ({mode, command}) => {
root, root,
compress: { compress: {
compress: VITE_BUILD_COMPRESS, compress: VITE_BUILD_COMPRESS,
deleteOriginFile: VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE, // SDK 作为 workspace 依赖需要保留原始产物package.json 的 main/module/exports 依赖这些文件
deleteOriginFile: false,
}, },
enableAnalyze: VITE_ENABLE_ANALYZE, enableAnalyze: VITE_ENABLE_ANALYZE,
enableConfig:VITE_ENABLE_CONFIG_GENERATE enableConfig:VITE_ENABLE_CONFIG_GENERATE