download.ts 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972
  1. import { cdn, upCdn } from '@/services/api';
  2. import { checkData } from '@/services/utils';
  3. import axios from 'axios';
  4. // import { MessagePlugin } from 'tdesign-vue-next';
  5. import { useUser } from '@/services/user';
  6. import JSZip from 'jszip';
  7. import { Pen, getGlobalColor, isShowChild } from '@meta2d/core';
  8. export const img_cdn = 'https://assets.le5lecdn.com';
  9. export const img_upCdn = 'https://drive.le5lecdn.com';
  10. const { user, signout } = useUser();
  11. const components = [
  12. 'inputDom',
  13. 'selectDom',
  14. 'menuDom',
  15. 'headMenuDom',
  16. 'sliderVerifyDom',
  17. 'dropdownDom',
  18. 'flvPlayerDom',
  19. 'countdown',
  20. 'swiperDom',
  21. 'threeDSence',
  22. 'rtspPlayerDom',
  23. 'timeline',
  24. 'swiperline',
  25. 'tab',
  26. 'radio',
  27. 'checkbox',
  28. 'calendar',
  29. 'indicator',
  30. 'progress',
  31. 'pagination',
  32. 'steps',
  33. 'notification',
  34. 'list',
  35. 'tree',
  36. 'rockerSwitch',
  37. 'roundSwitch',
  38. 'breadcrumb',
  39. 'transferSwitch',
  40. 'pie3D',
  41. 'hikVideo',
  42. 'thermometer',
  43. 'watermeter',
  44. 'indicatorLight',
  45. 'toggleSwitch',
  46. 'knifeSwitch',
  47. 'compass',
  48. 'thermometer1',
  49. 'airSwitch',
  50. 'waterTank',
  51. ];
  52. export const getDownloadList = (meta2dData: any, path: string = 'v') => {
  53. const lists = new Set();
  54. //TODO 加一个type区分是数据/还是接口
  55. //背景图片
  56. // const meta2dData = meta2d.data();
  57. let img = meta2dData.bkImage;
  58. if (img) {
  59. if (
  60. img.startsWith('/') ||
  61. img.startsWith(img_cdn) ||
  62. img.startsWith(img_upCdn)
  63. ) {
  64. let _img = img.replace(img_cdn, '').replace(img_upCdn, '');
  65. if (_img.startsWith('/v/')) {
  66. _img = _img.slice(2);
  67. }
  68. lists.add({
  69. url: img,
  70. path: `/view/projects/assets` + _img,
  71. });
  72. meta2dData.bkImage = `projects/assets` + _img;
  73. }
  74. }
  75. //图片图元(image strokeImage backgroundImage)
  76. const imageKeys = ['image', 'strokeImage', 'backgroundImage'];
  77. const images: string[] = [];
  78. for (const pen of meta2dData.pens) {
  79. for (const i of imageKeys) {
  80. const image = pen[i];
  81. if (image) {
  82. if (
  83. image.startsWith('/') ||
  84. image.startsWith(img_cdn) ||
  85. image.startsWith(img_upCdn)
  86. ) {
  87. // 只考虑相对路径下的 image ,绝对路径图片无需下载
  88. let _img = image.replace(img_cdn, '').replace(img_upCdn, '');
  89. if (_img.startsWith('/v/')) {
  90. _img = _img.slice(2);
  91. }
  92. if (!images.includes(image)) {
  93. // let _img = image.replace(cdn, '').replace(upCdn, '');
  94. lists.add({
  95. url: image,
  96. path: `/view/projects/assets` + _img,
  97. });
  98. }
  99. pen[i] = `projects/assets` + _img;
  100. }
  101. }
  102. }
  103. }
  104. if(path === 'v'){ //iframe嵌入的页面无需再次下载
  105. //其他文件
  106. const files = [
  107. '/view/assets/index.js',
  108. '/view/assets/index.css',
  109. '/view/css/index.css',
  110. '/view/css/t/font_2395018_nng9x1qhat.css',
  111. '/view/css/t/font_2073009_teagntehxt.css',
  112. '/view/js/marked.min.js',
  113. '/view/js/echarts.min.js',
  114. '/view/js/lcjs.iife.js',
  115. '/view/js/highcharts.js',
  116. '/view/js/highcharts-more.js',
  117. '/view/js/r.js',
  118. '/view/index.html',
  119. '/view/favicon.ico',
  120. '/view/view.conf',
  121. '/view/离线部署包使用说明.pdf',
  122. '/view/assets/cloudy.env',
  123. '/view/assets/default.env',
  124. '/view/assets/dusk.env',
  125. '/view/assets/night.env',
  126. '/view/assets/sunny.env',
  127. '/view/assets/cloudy.jpg',
  128. '/view/assets/dusk.jpg',
  129. '/view/assets/night.jpg',
  130. '/view/assets/sunny.jpg',
  131. '/view/assets/luopan.png',
  132. '/view/assets/Rain.png',
  133. '/view/assets/zhizhen.png',
  134. '/view/assets/默认环境光.png',
  135. '/view/assets/draco_decoder_gltf.js',
  136. '/view/assets/draco_wasm_wrapper_gltf.js',
  137. '/view/assets/draco_decoder_gltf.wasm',
  138. ];
  139. files.forEach((file) => {
  140. lists.add({
  141. url: (cdn ? cdn : '') + file,
  142. path: file,
  143. });
  144. });
  145. }
  146. //数据
  147. // const data: any = meta2d.data();
  148. if (meta2dData._id) delete meta2dData._id;
  149. if (meta2dData.id) delete meta2dData.id;
  150. if ((meta2dData as any).image) delete (meta2dData as any).image;
  151. checkData(meta2dData);
  152. lists.add({
  153. data: JSON.stringify(meta2dData)
  154. .replaceAll(img_cdn, '')
  155. .replaceAll(img_upCdn, ''),
  156. path: `/view/projects/${path}`,
  157. });
  158. return lists;
  159. };
  160. export const getPayList = (meta2dData: any) => {
  161. const pngs = new Set<string>();
  162. const jsPens = new Set<string>();
  163. const iotPens = new Set<string>();
  164. const svgPens = new Set<string>();
  165. for (const pen of meta2dData.pens) {
  166. if (pen.image) {
  167. if (
  168. pen.image.startsWith(`${img_cdn}/png/`) ||
  169. pen.image.startsWith('/png/')
  170. ) {
  171. pngs.add(pen.image.replace(img_cdn, ''));
  172. }
  173. } else if (pen.subClassName && pen.fullname) {
  174. if(!['箭头','拓扑图未分类','工具'].includes(pen.subClassName)){
  175. jsPens.add(pen.name);
  176. }
  177. } else if (components.includes(pen.name)) {
  178. iotPens.add(pen.name);
  179. } else if (pen.svgUrl) {
  180. if (
  181. pen.svgUrl.startsWith(`${img_cdn}/svg/`) ||
  182. pen.svgUrl.startsWith('/svg/')
  183. ) {
  184. svgPens.add(pen.svgUrl.replace(img_cdn, ''));
  185. }
  186. }
  187. }
  188. if (![...svgPens].length) {
  189. //判断是否为老数据
  190. if (meta2dData.paths) {
  191. let keys = [];
  192. for (let key of Object.keys(meta2dData.paths)) {
  193. let path = meta2dData.paths[key];
  194. if (
  195. path.indexOf('-1.18Zm4-1') !== -1 ||
  196. path.indexOf('-1.19Zm4-1') !== -1 ||
  197. path.indexOf('2.85ZM') !== -1 ||
  198. path.indexOf('-1-2.39.3') !== -1
  199. ) {
  200. keys.push(key);
  201. }
  202. }
  203. let flag = meta2dData.pens.some(
  204. (pen) => pen.name === 'svgPath' && keys.includes(pen.pathId)
  205. );
  206. if (flag) {
  207. svgPens.add('*'); //需要购买所有
  208. }
  209. }
  210. }
  211. return {
  212. pngs: [...pngs],
  213. jsPens: [...jsPens],
  214. iotPens: [...iotPens],
  215. svgPens: [...svgPens],
  216. };
  217. };
  218. //获取已购买
  219. export const getComponentPurchased = async (list: any) => {
  220. let _list = [];
  221. list.pngs.forEach((item) => {
  222. _list.push({
  223. type: '图片图元',
  224. name: item,
  225. });
  226. });
  227. list.jsPens.forEach((item) => {
  228. _list.push({
  229. type: 'JS线性图元',
  230. name: item,
  231. });
  232. });
  233. list.iotPens.forEach((item) => {
  234. _list.push({
  235. type: '控件',
  236. name: item,
  237. });
  238. });
  239. if ([...list.svgPens].includes('*')) {
  240. _list.push({
  241. type: 'SVG线性图元',
  242. });
  243. } else {
  244. list.svgPens.forEach((item) => {
  245. _list.push({
  246. type: 'SVG线性图元',
  247. name: item,
  248. });
  249. });
  250. }
  251. if(!_list.length){
  252. return [];
  253. }
  254. const res: any = await axios.post('/api/paid/2d/component?pageSize=1000', {
  255. list: _list,
  256. });
  257. if (res.error) {
  258. return [];
  259. }
  260. // let purchasedPngs = res.list.filter((item) => list.pngs.has(item));
  261. // let purchasedJs = res.list.filter((item) => list.jsPens.has(item));
  262. // let purchasedIot = res.list.filter((item) => list.iotPens.has(item));
  263. // let purchasedSvg = res.list.filter((item) => list.svgPens.has(item));
  264. // let price =
  265. // ([...list.pngs].length - purchasedPngs.length) * 50 +
  266. // ([...list.jsPens].length - purchasedJs.length) * 10 +
  267. // ([...list.iotPens].length - purchasedIot.length) * 70+
  268. // ([...list.svgPens].length - purchasedSvg.length) * 10;
  269. return res.list;
  270. };
  271. export const get2dComponentJs = async (names: string[] = components) => {
  272. let list = [];
  273. names.forEach((item) => {
  274. list.push({
  275. type: '控件',
  276. name: item,
  277. });
  278. });
  279. const res: any = await axios.post(
  280. '/api/2d-component.js',
  281. {
  282. // list,
  283. },
  284. {
  285. responseType: 'blob',
  286. }
  287. );
  288. return res;
  289. };
  290. export const getTemPngs = async (names: string[]) => {
  291. const res: any = await axios.post('/api/file/presign', {
  292. names,
  293. });
  294. return res;
  295. };
  296. export const getGoods = async () => {
  297. const res: any = await axios.get('/api/goods/2d/component/types');
  298. // console.log("res",res);
  299. return res;
  300. };
  301. export const getDeployGoods = async () => {
  302. const ret:any = await axios.post('/api/goods/list',{
  303. type:'私有部署'
  304. });
  305. return ret.list;
  306. }
  307. export enum Frame {
  308. vue2,
  309. vue3,
  310. react,
  311. html,
  312. zip
  313. }
  314. // export const _preFrameDownload = async (type: Frame) => {
  315. // frameFlag = type;
  316. // // MessagePlugin.info('正在下载打包中,可能需要几分钟,请耐心等待...');
  317. // zip3D(
  318. // type === Frame.vue3 ? 'toVue3' : type === Frame.vue2 ? 'toVue2' : 'toReact'
  319. // );
  320. // zip2D(
  321. // type === Frame.vue3
  322. // ? 'downloadVue3'
  323. // : type === Frame.vue2
  324. // ? 'downloadVue2'
  325. // : 'downloadReact'
  326. // );
  327. // const data: any = meta2d.data();
  328. // if (data._id) delete data._id;
  329. // if (data.id) delete data.id;
  330. // if (data.image) delete data.image;
  331. // data.userId = user.id;
  332. // checkData(data);
  333. // const [{ default: JSZip }, { saveAs }] = await Promise.all([
  334. // import('jszip'),
  335. // import('file-saver'),
  336. // ]);
  337. // const zip = new JSZip();
  338. // let _fileName =
  339. // (data.name && data.name.replace(/\//g, '_').replace(/:/g, '_')) ||
  340. // 'le5le.meta2d';
  341. // //处理付费svg
  342. // if (Object.keys(data.paths).length >= 3) {
  343. // //简单判断有无svg图元
  344. // const res: any = await axios.post('/api/paid/2d/component?pageSize=1000', {
  345. // type: 'SVG线性图元',
  346. // });
  347. // if (res.list.length === 1 && !res.list[0].name) {
  348. // //已经购买全部
  349. // for (let key of Object.keys(data.paths)) {
  350. // let path = data.paths[key];
  351. // if (
  352. // path.indexOf('-1.18Zm4-1') !== -1 ||
  353. // path.indexOf('-1.19Zm4-1') !== -1 ||
  354. // path.indexOf('2.85ZM') !== -1 ||
  355. // path.indexOf('-1-2.39.3') !== -1
  356. // ) {
  357. // data.paths[key] = '';
  358. // }
  359. // }
  360. // } else {
  361. // //购买部分
  362. // let purchasedList = res.list.map((i) => i.name);
  363. // data.pens.forEach((pen) => {
  364. // if (pen.name === 'svgPath' && pen.svgUrl) {
  365. // if (purchasedList.includes(pen.svgUrl.replace(img_cdn, ''))) {
  366. // pen.pathId = null;
  367. // }
  368. // }
  369. // });
  370. // }
  371. // }
  372. // const _zip: any = zip.folder(`${_fileName}`);
  373. // _zip.file(
  374. // `${
  375. // type === Frame.vue3
  376. // ? 'meta2d-vue3'
  377. // : type === Frame.vue2
  378. // ? 'meta2d-vue2'
  379. // : 'meta2d-react'
  380. // }/public/json/data.json`,
  381. // JSON.stringify(data).replaceAll(img_cdn, '').replaceAll(img_upCdn, '')
  382. // );
  383. // await Promise.all([
  384. // zipJs(_zip),
  385. // zipBkImg(_zip),
  386. // zipImages(_zip, meta2d.store.data.pens),
  387. // type === Frame.vue3
  388. // ? zipVue3Files(_zip)
  389. // : type === Frame.vue2
  390. // ? zipVue2Files(_zip)
  391. // : zipReactFiles(_zip),
  392. // zipIotPens(_zip),
  393. // ]);
  394. // const blob = await zip.generateAsync({ type: 'blob' });
  395. // saveAs(blob, `${_fileName}.zip`);
  396. // frameFlag = -1;
  397. // };
  398. // async function zipIotPens(zip: JSZip) {
  399. // //处理控件
  400. // const js = await get2dComponentJs();
  401. // zip.file(
  402. // `${
  403. // frameFlag === Frame.vue3
  404. // ? 'meta2d-vue3'
  405. // : frameFlag === Frame.vue2
  406. // ? 'meta2d-vue2'
  407. // : 'meta2d-react'
  408. // }/public/js/2d-components.js`,
  409. // js,
  410. // { createFolders: true }
  411. // );
  412. // const res: Blob = await axios.get( cdn+'/view/js/r.js', {
  413. // responseType: 'blob',
  414. // });
  415. // zip.file(
  416. // `${
  417. // frameFlag === Frame.vue3
  418. // ? 'meta2d-vue3'
  419. // : frameFlag === Frame.vue2
  420. // ? 'meta2d-vue2'
  421. // : 'meta2d-react'
  422. // }/public/js/r.js`,
  423. // res,
  424. // { createFolders: true }
  425. // );
  426. // }
  427. // async function zipJs(zip: JSZip) {
  428. // const files = ['/view/js/marked.min.js', '/view/js/lcjs.iife.js'];
  429. // await Promise.all(
  430. // files.map(async (filePath) => {
  431. // const res: Blob = await axios.get(cdn+filePath, {
  432. // responseType: 'blob',
  433. // });
  434. // zip.file(
  435. // `${
  436. // frameFlag === Frame.vue3
  437. // ? 'meta2d-vue3'
  438. // : frameFlag === Frame.vue2
  439. // ? 'meta2d-vue2'
  440. // : 'meta2d-react'
  441. // }/public` + filePath.replace('/view', ''),
  442. // res,
  443. // { createFolders: true }
  444. // );
  445. // })
  446. // );
  447. // }
  448. export async function zipBkImg(zip: JSZip) {
  449. let img = meta2d.store.data.bkImage;
  450. if (img) {
  451. if (img.startsWith('/') || img.startsWith(img_cdn) || img.startsWith(img_upCdn)) {
  452. const pngs = await getTemPngs([img.replace(img_cdn, '').replace(img_upCdn, '')]);
  453. await zipImage(zip, img, pngs[img.replace(img_cdn, '').replace(img_upCdn, '')]);
  454. }
  455. }
  456. }
  457. async function zipImage(zip: JSZip, image: string, temImage?: string) {
  458. const res: Blob = await axios.get(temImage || image, {
  459. responseType: 'blob',
  460. // params: {
  461. // isZip: true,
  462. // },
  463. });
  464. zip.file(
  465. (cdn ? image.replace(cdn, '').replace(upCdn, '') : image),
  466. res,
  467. {
  468. createFolders: true,
  469. }
  470. );
  471. }
  472. // const zip3D = (name: string) => {
  473. // const pen_3d = meta2d.store.data.pens.filter(
  474. // (pen) =>
  475. // pen.name === 'iframe' &&
  476. // (pen.tags.includes('meta3d') || pen.iframe.indexOf('/3d') !== -1)
  477. // );
  478. // if (pen_3d && pen_3d.length) {
  479. // //存在3d场景
  480. // pen_3d.forEach((pen) => {
  481. // //发送消息
  482. // // let params = queryURLParams(pen.iframe.split('?')[1]);
  483. // (
  484. // pen.calculative.singleton.div.children[0] as HTMLIFrameElement
  485. // ).contentWindow.postMessage(
  486. // JSON.stringify({
  487. // type: 1,
  488. // name,
  489. // // id: params.id,
  490. // }),
  491. // '*'
  492. // );
  493. // });
  494. // }
  495. // };
  496. // const zip2D = (name: string) => {
  497. // const pen_2d = meta2d.store.data.pens.filter(
  498. // (pen) =>
  499. // pen.name === 'iframe' &&
  500. // pen.iframe.indexOf('/2d') !== -1 || pen.iframe.indexOf('data=2d') !== -1 ||
  501. // pen.iframe.indexOf('/view/v') !== -1 ||pen.iframe.indexOf('data=v') !== -1||
  502. // pen.iframe.indexOf('/preview') !== -1)
  503. // );
  504. // if (pen_2d && pen_2d.length) {
  505. // //存在3d场景
  506. // pen_2d.forEach((pen) => {
  507. // //发送消息
  508. // // let params = queryURLParams(pen.iframe.split('?')[1]);
  509. // (
  510. // pen.calculative.singleton.div.children[0] as HTMLIFrameElement
  511. // ).contentWindow.postMessage(
  512. // JSON.stringify({
  513. // name,
  514. // type: 1,
  515. // }),
  516. // '*'
  517. // );
  518. // });
  519. // }
  520. // };
  521. /**
  522. * 图片放到 zip 里
  523. * @param pens 可以是非具有 calculative 的 pen
  524. */
  525. export async function zipImages(zip: JSZip, pens: Pen[]) {
  526. if (!pens) {
  527. return;
  528. }
  529. // 不止 image 上有图片, strokeImage ,backgroundImage 也有图片
  530. const imageKeys = [
  531. {
  532. string: 'image',
  533. },
  534. { string: 'strokeImage' },
  535. { string: 'backgroundImage' },
  536. ] as const;
  537. const images: string[] = [];
  538. for (const pen of pens) {
  539. for (const i of imageKeys) {
  540. const image = pen[i.string];
  541. if (image) {
  542. // HTMLImageElement 无法精确控制图片格式
  543. if (
  544. image.startsWith('/') ||
  545. image.startsWith(cdn) ||
  546. image.startsWith(upCdn)
  547. ) {
  548. // 只考虑相对路径下的 image ,绝对路径图片无需下载
  549. if (!images.includes(image)) {
  550. images.push(image);
  551. }
  552. }
  553. }
  554. }
  555. // 无需递归遍历子节点,现在所有的节点都在外层
  556. }
  557. //付费pngs
  558. const pngs = await getTemPngs(
  559. images.map((i) => i.replace(img_cdn, '').replace(img_upCdn, ''))
  560. );
  561. await Promise.all(
  562. images.map((image) =>
  563. zipImage(zip, image, pngs[image.replace(img_cdn, '').replace(img_upCdn, '')])
  564. )
  565. );
  566. }
  567. //新
  568. // async function zipVue3Files(zip: JSZip) {
  569. // const files = [
  570. // '/view/meta2d-vue3/src/components/Meta2d.vue',
  571. // '/view/meta2d-vue3/src/App.vue',
  572. // '/view/meta2d-vue3/src/main.js',
  573. // '/view/meta2d-vue3/src/style.css',
  574. // '/view/meta2d-vue3/index.html',
  575. // '/view/meta2d-vue3/package.json',
  576. // '/view/meta2d-vue3/README.md',
  577. // '/view/meta2d-vue3/vite.config.js',
  578. // ] as const;
  579. // // 文件同时加载
  580. // await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
  581. // }
  582. // async function zipVue2Files(zip: JSZip) {
  583. // const files = [
  584. // '/view/meta2d-vue2/src/components/Meta2d.vue',
  585. // '/view/meta2d-vue2/src/App.vue',
  586. // '/view/meta2d-vue2/src/main.js',
  587. // // '/view/meta2d-vue2/src/style.css',
  588. // '/view/meta2d-vue2/public/index.html',
  589. // '/view/meta2d-vue2/package.json',
  590. // '/view/meta2d-vue2/README.md',
  591. // // '/view/meta2d-vue3/vite.config.js',
  592. // ] as const;
  593. // // 文件同时加载
  594. // await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
  595. // }
  596. // async function zipReactFiles(zip: JSZip) {
  597. // const files = [
  598. // '/view/meta2d-react/src/index.css',
  599. // '/view/meta2d-react/src/index.js',
  600. // '/view/meta2d-react/src/Meta2d.css',
  601. // '/view/meta2d-react/src/Meta2d.jsx',
  602. // '/view/meta2d-react/package.json',
  603. // '/view/meta2d-react/README.md',
  604. // '/view/meta2d-react/public/index.html',
  605. // ] as const;
  606. // // 文件同时加载
  607. // await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
  608. // }
  609. // async function zipFile(zip: JSZip, filePath: string) {
  610. // const res: Blob = await axios.get(
  611. // (cdn ? cdn + '/v' : import.meta.env.BASE_URL.slice(0, -1)) + filePath,
  612. // {
  613. // responseType: 'blob',
  614. // }
  615. // );
  616. // zip.file(filePath.replace('/view', ''), res, { createFolders: true });
  617. // }
  618. export const getFrameDownloadList =(meta2dData: any, path: string = 'v',type:Frame, flag_3d=false) => {
  619. const lists = new Set();
  620. let img = meta2dData.bkImage;
  621. if (img) {
  622. if (
  623. img.startsWith('/') ||
  624. img.startsWith(img_cdn) ||
  625. img.startsWith(img_upCdn)
  626. ) {
  627. let _img = img.replace(img_cdn, '').replace(img_upCdn, '');
  628. if (_img.startsWith('/v/')) {
  629. _img = _img.slice(2);
  630. }
  631. lists.add({
  632. url: img,
  633. path: (`${
  634. type === Frame.vue3
  635. ? 'meta2d-vue3'
  636. : type === Frame.vue2
  637. ? 'meta2d-vue2'
  638. : 'meta2d-react'
  639. }/public`) + _img,
  640. });
  641. meta2dData.bkImage = _img;
  642. }
  643. }
  644. //图片图元(image strokeImage backgroundImage)
  645. const imageKeys = ['image', 'strokeImage', 'backgroundImage'];
  646. const images: string[] = [];
  647. for (const pen of meta2dData.pens) {
  648. for (const i of imageKeys) {
  649. const image = pen[i];
  650. if (image) {
  651. if (
  652. image.startsWith('/') ||
  653. image.startsWith(img_cdn) ||
  654. image.startsWith(img_upCdn)
  655. ) {
  656. // 只考虑相对路径下的 image ,绝对路径图片无需下载
  657. let _img = image.replace(img_cdn, '').replace(img_upCdn, '');
  658. if (_img.startsWith('/v/')) {
  659. _img = _img.slice(2);
  660. }
  661. let path = (`${
  662. type === Frame.vue3
  663. ? 'meta2d-vue3'
  664. : type === Frame.vue2
  665. ? 'meta2d-vue2'
  666. : 'meta2d-react'
  667. }/public`) + _img
  668. if (!images.includes(image)) {
  669. // let _img = image.replace(cdn, '').replace(upCdn, '');
  670. lists.add({
  671. url: image,
  672. path,
  673. });
  674. }
  675. pen[i] = _img;
  676. }
  677. }
  678. }
  679. }
  680. let folderName =type===Frame.vue3?'meta2d-vue3':type===Frame.vue2?'meta2d-vue2': 'meta2d-react';
  681. if(path === 'v'){ //iframe嵌入的页面无需再次下载
  682. //其他文件
  683. let files = [];
  684. let files_3d = [
  685. '/view/index.html',
  686. '/view/favicon.ico',
  687. '/view/view.conf',
  688. '/view/离线部署包使用说明.pdf',
  689. '/view/css/index.css',
  690. '/view/assets/index.js',
  691. '/view/assets/index.css',
  692. '/view/assets/cloudy.env',
  693. '/view/assets/default.env',
  694. '/view/assets/dusk.env',
  695. '/view/assets/night.env',
  696. '/view/assets/sunny.env',
  697. '/view/assets/cloudy.jpg',
  698. '/view/assets/dusk.jpg',
  699. '/view/assets/night.jpg',
  700. '/view/assets/sunny.jpg',
  701. '/view/assets/luopan.png',
  702. '/view/assets/Rain.png',
  703. '/view/assets/zhizhen.png',
  704. '/view/assets/默认环境光.png',
  705. '/view/assets/draco_decoder_gltf.js',
  706. '/view/assets/draco_wasm_wrapper_gltf.js',
  707. '/view/assets/draco_decoder_gltf.wasm',
  708. ];
  709. switch (type) {
  710. case Frame.vue3:
  711. files =[
  712. '/view/meta2d-vue3/src/router/index.ts',
  713. '/view/meta2d-vue3/src/views/2d/Meta2d.vue',
  714. '/view/meta2d-vue3/src/App.vue',
  715. '/view/meta2d-vue3/src/main.ts',
  716. '/view/meta2d-vue3/src/style.css',
  717. '/view/meta2d-vue3/index.html',
  718. '/view/meta2d-vue3/package.json',
  719. '/view/meta2d-vue3/README.md',
  720. '/view/meta2d-vue3/tsconfig.json',
  721. '/view/meta2d-vue3/tsconfig.node.json',
  722. '/view/meta2d-vue3/vite.config.ts',
  723. ];
  724. // if(flag_3d){
  725. // //存在3d场景
  726. // files_3d.push(...[
  727. // '/meta2d-vue3/src/plugins/meta3d/index.ts',
  728. // '/meta2d-vue3/src/plugins/meta3d/meta3d.css',
  729. // '/meta2d-vue3/src/plugins/meta3d/meta3d.js',
  730. // // '/view/meta2d-vue3/src/views/3d/Meta3d.vue',
  731. // // '/meta2d-vue3/public/meta3d/js/draco_decoder_gltf.js',
  732. // // '/meta2d-vue3/public/meta3d/js/draco_decoder_gltf.wasm',
  733. // // '/meta2d-vue3/public/meta3d/js/draco_wasm_wrapper_gltf.js',
  734. // ]);
  735. // files.push( '/view/meta2d-vue3/src/views/3d/Meta3d.vue',)
  736. // }
  737. break;
  738. case Frame.vue2:
  739. files =[
  740. '/view/meta2d-vue2/src/router/index.js',
  741. '/view/meta2d-vue2/src/views/2d/Meta2d.vue',
  742. '/view/meta2d-vue2/src/App.vue',
  743. '/view/meta2d-vue2/src/main.js',
  744. '/view/meta2d-vue2/index.html',
  745. '/view/meta2d-vue2/package.json',
  746. '/view/meta2d-vue2/README.md',
  747. '/view/meta2d-vue2/vite.config.js'
  748. ];
  749. // if(flag_3d){
  750. // files_3d.push(...[
  751. // '/meta2d-vue2/src/plugins/meta3d/index.js',
  752. // '/meta2d-vue2/src/plugins/meta3d/meta3d.css',
  753. // '/meta2d-vue2/src/plugins/meta3d/meta3d.js',
  754. // // '/meta2d-vue2/src/views/3d/Meta3d.vue',
  755. // // '/meta2d-vue2/public/meta3d/js/draco_decoder_gltf.js',
  756. // // '/meta2d-vue2/public/meta3d/js/draco_decoder_gltf.wasm',
  757. // // '/meta2d-vue2/public/meta3d/js/draco_wasm_wrapper_gltf.js',
  758. // ]);
  759. // files.push( '/view/meta2d-vue2/src/views/3d/Meta3d.vue',)
  760. // }
  761. // break;
  762. case Frame.react:
  763. files =[
  764. '/view/meta2d-react/src/router/index.tsx',
  765. '/view/meta2d-react/src/views/2d/Meta2d.tsx',
  766. '/view/meta2d-react/src/App.tsx',
  767. '/view/meta2d-react/src/index.css',
  768. '/view/meta2d-react/src/main.tsx',
  769. '/view/meta2d-react/index.html',
  770. '/view/meta2d-react/package.json',
  771. '/view/meta2d-react/README.md',
  772. '/view/meta2d-react/tsconfig.json',
  773. '/view/meta2d-react/tsconfig.node.json',
  774. '/view/meta2d-react/vite.config.ts',
  775. ];
  776. // if(flag_3d){
  777. // files_3d.push(...[
  778. // '/meta2d-react/src/plugins/meta3d/index.ts',
  779. // '/meta2d-react/src/plugins/meta3d/meta3d.css',
  780. // '/meta2d-react/src/plugins/meta3d/meta3d.js',
  781. // // '/meta2d-react/src/views/3d/Meta3d.tsx',
  782. // // '/meta2d-react/public/meta3d/js/draco_decoder_gltf.js',
  783. // // '/meta2d-react/public/meta3d/js/draco_decoder_gltf.wasm',
  784. // // '/meta2d-react/public/meta3d/js/draco_wasm_wrapper_gltf.js',
  785. // ]);
  786. // files.push('/view/meta2d-react/src/views/3d/Meta3d.tsx',)
  787. // }
  788. // break;
  789. default:
  790. break;
  791. }
  792. files.forEach((file) => {
  793. lists.add({
  794. url: (cdn ? cdn + '/v' : import.meta.env.BASE_URL.slice(0, -1)) + file,
  795. path: file.replace('/view', ''),
  796. });
  797. });
  798. if(flag_3d){
  799. files_3d.forEach((file) => {
  800. lists.add({
  801. // url: (cdn ? cdn + '/v' : import.meta.env.BASE_URL.slice(0, -1)) + '/view/meta3d/'+file.split('/meta3d/')[1],
  802. // path: file,
  803. url: (cdn ? cdn : '') + file,
  804. path: `/${folderName}/public${file}`,
  805. });
  806. })
  807. }
  808. let jsFiles = [
  809. '/view/js/marked.min.js',
  810. // '/view/js/echarts.min.js',
  811. '/view/js/lcjs.iife.js',
  812. // '/view/js/highcharts.js',
  813. // '/view/js/highcharts-more.js',
  814. '/view/js/r.js',
  815. '/view/icon/font_2395018_nng9x1qhat.css',
  816. '/view/icon/font_2073009_teagntehxt.css',
  817. // '/view/assets/cloudy.env',
  818. // '/view/assets/default.env',
  819. // '/view/assets/dusk.env',
  820. // '/view/assets/night.env',
  821. // '/view/assets/sunny.env',
  822. // '/view/assets/cloudy.jpg',
  823. // '/view/assets/dusk.jpg',
  824. // '/view/assets/night.jpg',
  825. // '/view/assets/sunny.jpg',
  826. // '/view/assets/luopan.png',
  827. // '/view/assets/Rain.png',
  828. // '/view/assets/zhizhen.png',
  829. // '/view/assets/默认环境光.png',
  830. // '/view/assets/draco_decoder_gltf.js',
  831. // '/view/assets/draco_wasm_wrapper_gltf.js',
  832. // '/view/assets/draco_decoder_gltf.wasm',
  833. ]
  834. jsFiles.forEach((file) => {
  835. lists.add({
  836. url: (cdn ? cdn + '/v' : import.meta.env.BASE_URL.slice(0, -1))+ file,
  837. path:`/${folderName}/public${file.replace('/view', '')}`,
  838. });
  839. });
  840. }
  841. //图纸数据
  842. if (meta2dData._id) delete meta2dData._id;
  843. if (meta2dData.id) delete meta2dData.id;
  844. if ((meta2dData as any).image) delete (meta2dData as any).image;
  845. lists.add({
  846. data: JSON.stringify(meta2dData)
  847. .replaceAll(img_cdn, '')
  848. .replaceAll(img_upCdn, ''),
  849. path: `/${folderName}/public/json/${path}.json`,
  850. });
  851. return lists;
  852. };
  853. export const getDownloadZipList = (meta2dData: any, zips:any) => {
  854. const lists = new Set();
  855. // const pngs = new Set<string>();
  856. if (meta2dData._id) delete meta2dData._id;
  857. if (meta2dData.id) delete meta2dData.id;
  858. let _fileName =
  859. (meta2dData.name && meta2dData.name.replace(/\//g, '_').replace(/:/g, '_')) ||
  860. 'le5le.meta2d';
  861. lists.add({
  862. data:JSON.stringify(meta2dData).replaceAll(img_cdn, '').replaceAll(img_upCdn, ''),
  863. path: `${_fileName}.json`
  864. });
  865. for (let key in zips) {
  866. lists.add({
  867. data:JSON.stringify(zips[key].data)?.replaceAll(img_cdn, '').replaceAll(img_upCdn, ''),
  868. path: `${key}/${zips[key].data.name?.replace(/\//g, '_')?.replace(/:/g, '_')}.json`
  869. });
  870. // zips[key].pngs.forEach(item => pngs.add(item));
  871. getDataPngs(zips[key].data).forEach(item => lists.add(item));
  872. }
  873. getDataPngs(meta2dData).forEach(item => lists.add(item));
  874. return lists;
  875. }
  876. export const getDataPngs = (meta2dData: any)=>{
  877. const lists = new Set();
  878. let img = meta2dData.bkImage;
  879. if (img) {
  880. if (
  881. img.startsWith('/') ||
  882. img.startsWith(img_cdn) ||
  883. img.startsWith(img_upCdn)
  884. ) {
  885. let _img = img.replace(img_cdn, '').replace(img_upCdn, '');
  886. // if (_img.startsWith('/v/')) {
  887. // _img = _img.slice(2);
  888. // }
  889. lists.add({
  890. url: img,
  891. path: _img.split('?')[0],
  892. });
  893. }
  894. }
  895. //图片图元(image strokeImage backgroundImage)
  896. const imageKeys = ['image', 'strokeImage', 'backgroundImage'];
  897. const images: string[] = [];
  898. for (const pen of meta2dData.pens) {
  899. for (const i of imageKeys) {
  900. const image = pen[i];
  901. if (image) {
  902. if (
  903. image.startsWith('/') ||
  904. image.startsWith(img_cdn) ||
  905. image.startsWith(img_upCdn)
  906. ) {
  907. // 只考虑相对路径下的 image ,绝对路径图片无需下载
  908. let _img = image.replace(img_cdn, '').replace(img_upCdn, '');
  909. if (!images.includes(image)) {
  910. // let _img = image.replace(cdn, '').replace(upCdn, '');
  911. lists.add({
  912. url: image,
  913. path:_img.split('?')[0],
  914. });
  915. }
  916. }
  917. }
  918. }
  919. }
  920. return lists;
  921. }