import JSZip from 'jszip'; import { saveAs } from 'file-saver'; import { ExportProjectQuery, FeatZipSubfix, getNowDateTime, loopHandle, ProjectExportMainConfig, ProjectExportMainFileName, Scene, ComponentCommonConfig, } from '@easytwin/core'; import { storeInfos } from '../DataStore'; import { exportProject } from './api'; import { setRecoilExternalState } from '../../RecoilExternalStatePortal'; import { _globalLoadingInfo } from '../../pages/module'; /** * 导出项目压缩包 * @param { ExportProjectQuery } query * @returns { Promise } */ export async function exportZip(query: ExportProjectQuery): Promise { try { const { id: projectId } = query; const projectInfo = await exportProject(query); if (!projectInfo) return; setRecoilExternalState(_globalLoadingInfo, { loading: true, tip: '文件正在导出...', }); const zip = new JSZip(); const { scenes = [] } = projectInfo; const [defaultScene] = scenes; if (!defaultScene) return; const { name, commonConfig: { config: { thumb, groundImgUrl }, }, } = defaultScene as Scene; // 项目文件夹名称 const folderName = `${name || '未命名'}_${projectId}_${getNowDateTime()}`; zip.file(ProjectExportMainFileName, JSON.stringify(ProjectExportMainConfig)); const allFileInfos: { url: string }[] = []; /** * base methods */ const handleCopyFileAndPushInfo = async (url: string | null) => { if (!url) return; const _url = import.meta.env.VITE_ASSETS_URL + url; allFileInfos.push({ url }); await fetch(_url, { cache: 'no-store', }) .then((res) => { if (res.status === 200) { return res.blob(); } return Promise.reject(new Error('文件下载失败')); }) .then((result) => { zip.file(url!, result); }); }; const handleWriteJsonFile = async (fileName: string, data: any) => { zip.file(`/db/database/${fileName}.json`, JSON.stringify(data)); }; await loopHandle(projectInfo.objs, async (objs) => { const commonConfig = objs.commonConfig as ComponentCommonConfig; if (commonConfig?.fileUrl) { await handleCopyFileAndPushInfo(commonConfig?.fileUrl); } }); /** * project */ // 写入项目预览图文件 await handleCopyFileAndPushInfo(thumb); // 写入项目预览图文件 await handleCopyFileAndPushInfo(groundImgUrl); // 写入 project 数据文件 handleWriteJsonFile(storeInfos.project.name, projectInfo); // 写入静态文件 handleWriteJsonFile(storeInfos.file.name, allFileInfos); // 导出压缩文件 zip.generateAsync({ type: 'blob' }).then((blob) => { saveAs(blob, `${folderName}${FeatZipSubfix}`); }); setRecoilExternalState(_globalLoadingInfo, { loading: false, tip: null, }); } catch (err) { console.error('exportProject:', err); return Promise.reject('导出项目失败!'); } }