download.ts 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177
  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. 'tablePlus',
  52. 'tank',
  53. 'treeFilterDom',
  54. 'datePickerDom',
  55. 'dateRangePickerDom',
  56. 'cascadeFilterDom',
  57. ];
  58. export const getDownloadList = (meta2dData: any, path: string = 'v') => {
  59. const lists = new Set();
  60. //TODO 加一个type区分是数据/还是接口
  61. //背景图片
  62. // const meta2dData = meta2d.data();
  63. let img = meta2dData.bkImage;
  64. if (img) {
  65. if (
  66. img.startsWith('/') ||
  67. img.startsWith(img_cdn) ||
  68. img.startsWith(img_upCdn)
  69. ) {
  70. let _img = img.replace(img_cdn, '').replace(img_upCdn, '');
  71. if (_img.startsWith('/v/')) {
  72. _img = _img.slice(2);
  73. }
  74. _img = decodeURIComponent(_img);
  75. lists.add({
  76. url: img,
  77. path: `/view/projects/assets` + _img,
  78. });
  79. meta2dData.bkImage = `projects/assets` + _img;
  80. }
  81. }
  82. //图片图元(image strokeImage backgroundImage)
  83. const imageKeys = ['image', 'strokeImage', 'backgroundImage'];
  84. const images: string[] = [];
  85. for (const pen of meta2dData.pens) {
  86. for (const i of imageKeys) {
  87. const image = pen[i];
  88. if (image) {
  89. if (
  90. image.startsWith('/') ||
  91. image.startsWith(img_cdn) ||
  92. image.startsWith(img_upCdn)
  93. ) {
  94. // 只考虑相对路径下的 image ,绝对路径图片无需下载
  95. let _img = image.replace(img_cdn, '').replace(img_upCdn, '');
  96. if (_img.startsWith('/v/')) {
  97. _img = _img.slice(2);
  98. }
  99. _img = decodeURIComponent(_img);
  100. if (!images.includes(image)) {
  101. // let _img = image.replace(cdn, '').replace(upCdn, '');
  102. lists.add({
  103. url: image,
  104. path: `/view/projects/assets` + _img,
  105. });
  106. }
  107. pen[i] = `projects/assets` + _img;
  108. }
  109. }
  110. }
  111. pen.events?.forEach((event) => {
  112. if (event.actions?.length) {
  113. event.actions.forEach((action) => {
  114. if (action.action === 1) {
  115. //更改属性
  116. if (action.value?.image) {
  117. let image = action.value.image;
  118. if (
  119. image.startsWith('/') ||
  120. image.startsWith(img_cdn) ||
  121. image.startsWith(img_upCdn)
  122. ) {
  123. // 只考虑相对路径下的 image ,绝对路径图片无需下载
  124. let _img = image.replace(img_cdn, '').replace(img_upCdn, '');
  125. if (_img.startsWith('/v/')) {
  126. _img = _img.slice(2);
  127. }
  128. _img = decodeURIComponent(_img);
  129. if (!images.includes(image)) {
  130. lists.add({
  131. url: image,
  132. path: `/view/projects/assets` + _img,
  133. });
  134. }
  135. action.value.image = `projects/assets` + _img;
  136. }
  137. }
  138. }
  139. });
  140. }
  141. });
  142. pen.triggers?.forEach((trigger) => {
  143. trigger?.status?.forEach((state) => {
  144. if (state.actions?.length) {
  145. state.actions.forEach((action) => {
  146. if (action.action === 1) {
  147. //更改属性
  148. if (action.value?.image) {
  149. let image = action.value.image;
  150. if (
  151. image.startsWith('/') ||
  152. image.startsWith(img_cdn) ||
  153. image.startsWith(img_upCdn)
  154. ) {
  155. // 只考虑相对路径下的 image ,绝对路径图片无需下载
  156. let _img = image.replace(img_cdn, '').replace(img_upCdn, '');
  157. if (_img.startsWith('/v/')) {
  158. _img = _img.slice(2);
  159. }
  160. _img = decodeURIComponent(_img);
  161. if (!images.includes(image)) {
  162. lists.add({
  163. url: image,
  164. path: `/view/projects/assets` + _img,
  165. });
  166. }
  167. action.value.image = `projects/assets` + _img;
  168. }
  169. }
  170. }
  171. });
  172. }
  173. });
  174. });
  175. }
  176. if(path === 'v'){ //iframe嵌入的页面无需再次下载
  177. //其他文件
  178. const files = [
  179. '/view/assets/index.js',
  180. '/view/assets/index.css',
  181. '/view/css/index.css',
  182. '/view/css/t/font_2395018_nng9x1qhat.css',
  183. '/view/css/t/font_2073009_teagntehxt.css',
  184. '/view/css/v/iconfont.css',
  185. '/view/css/v/iconfont.ttf',
  186. '/view/css/v/iconfont.woff',
  187. '/view/css/v/iconfont.woff2',
  188. '/view/css/v/iconfont.svg',
  189. //字体
  190. '/view/css/fonts/DS-DIGI-1.ttf',
  191. '/view/css/fonts/DS-DIGIB-2.ttf',
  192. '/view/css/fonts/DS-DIGII-3.ttf',
  193. '/view/css/fonts/DS-DIGIT-4.ttf',
  194. '/view/css/fonts/fonts.css',
  195. '/view/css/fonts/TG-TYPE-Bold.otf',
  196. '/view/css/fonts/TG-TYPE-Regular.otf',
  197. '/view/css/fonts/庞门正道标题体.ttf',
  198. '/view/css/fonts/斗鱼追光体.ttf',
  199. '/view/js/marked.min.js',
  200. '/view/js/echarts.min.js',
  201. '/view/js/lcjs.iife.js',
  202. '/view/js/highcharts.js',
  203. '/view/js/highcharts-more.js',
  204. '/view/js/r.js',
  205. '/view/index.html',
  206. '/view/favicon.ico',
  207. '/view/view.conf',
  208. '/view/离线部署包使用说明.pdf',
  209. '/view/assets/cloudy.env',
  210. '/view/assets/default.env',
  211. '/view/assets/dusk.env',
  212. '/view/assets/night.env',
  213. '/view/assets/sunny.env',
  214. '/view/assets/cloudy.jpg',
  215. '/view/assets/dusk.jpg',
  216. '/view/assets/night.jpg',
  217. '/view/assets/sunny.jpg',
  218. '/view/assets/luopan.png',
  219. '/view/assets/Rain.png',
  220. '/view/assets/zhizhen.png',
  221. '/view/assets/默认环境光.png',
  222. '/view/assets/draco_decoder_gltf.js',
  223. '/view/assets/draco_wasm_wrapper_gltf.js',
  224. '/view/assets/draco_decoder_gltf.wasm',
  225. //echarts 主题
  226. '/view/theme/dark.json',
  227. '/view/theme/light.json',
  228. ];
  229. files.forEach((file) => {
  230. lists.add({
  231. url: (cdn ? cdn : '') + file,
  232. path: file,
  233. });
  234. });
  235. }
  236. //数据
  237. // const data: any = meta2d.data();
  238. if (meta2dData._id) delete meta2dData._id;
  239. if (meta2dData.id) delete meta2dData.id;
  240. if ((meta2dData as any).image) delete (meta2dData as any).image;
  241. checkData(meta2dData);
  242. lists.add({
  243. data: JSON.stringify(meta2dData)
  244. .replaceAll(img_cdn, '')
  245. .replaceAll(img_upCdn, ''),
  246. path: `/view/projects/${path}`,
  247. });
  248. return lists;
  249. };
  250. export const getPayList = (meta2dData: any) => {
  251. const pngs = new Set<string>();
  252. const jsPens = new Set<string>();
  253. const iotPens = new Set<string>();
  254. const svgPens = new Set<string>();
  255. for (const pen of meta2dData.pens) {
  256. if (pen.image) {
  257. if (
  258. pen.image.startsWith(`${img_cdn}/png/`) ||
  259. pen.image.startsWith('/png/')
  260. ) {
  261. pngs.add(pen.image.replace(img_cdn, ''));
  262. }
  263. } else if (pen.subClassName && pen.fullname) {
  264. if(!['箭头','拓扑图未分类','工具'].includes(pen.subClassName)){
  265. jsPens.add(pen.name);
  266. }
  267. } else if (components.includes(pen.name)) {
  268. iotPens.add(pen.name);
  269. } else if (pen.svgUrl) {
  270. if (
  271. pen.svgUrl.startsWith(`${img_cdn}/svg/`) ||
  272. pen.svgUrl.startsWith('/svg/')
  273. ) {
  274. svgPens.add(pen.svgUrl.replace(img_cdn, ''));
  275. }
  276. }
  277. }
  278. if (![...svgPens].length) {
  279. //判断是否为老数据
  280. if (meta2dData.paths) {
  281. let keys = [];
  282. for (let key of Object.keys(meta2dData.paths)) {
  283. let path = meta2dData.paths[key];
  284. if (
  285. path.indexOf('-1.18Zm4-1') !== -1 ||
  286. path.indexOf('-1.19Zm4-1') !== -1 ||
  287. path.indexOf('2.85ZM') !== -1 ||
  288. path.indexOf('-1-2.39.3') !== -1
  289. ) {
  290. keys.push(key);
  291. }
  292. }
  293. let flag = meta2dData.pens.some(
  294. (pen) => pen.name === 'svgPath' && keys.includes(pen.pathId)
  295. );
  296. if (flag) {
  297. svgPens.add('*'); //需要购买所有
  298. }
  299. }
  300. }
  301. return {
  302. pngs: [...pngs],
  303. jsPens: [...jsPens],
  304. iotPens: [...iotPens],
  305. svgPens: [...svgPens],
  306. };
  307. };
  308. //获取已购买
  309. export const getComponentPurchased = async (list: any) => {
  310. let _list = [];
  311. list.pngs.forEach((item) => {
  312. _list.push({
  313. type: '图片图元',
  314. name: item,
  315. });
  316. });
  317. list.jsPens.forEach((item) => {
  318. _list.push({
  319. type: 'JS线性图元',
  320. name: item,
  321. });
  322. });
  323. list.iotPens.forEach((item) => {
  324. _list.push({
  325. type: '控件',
  326. name: item,
  327. });
  328. });
  329. if ([...list.svgPens].includes('*')) {
  330. _list.push({
  331. type: 'SVG线性图元',
  332. });
  333. } else {
  334. list.svgPens.forEach((item) => {
  335. _list.push({
  336. type: 'SVG线性图元',
  337. name: item,
  338. });
  339. });
  340. }
  341. if(!_list.length){
  342. return [];
  343. }
  344. const res: any = await axios.post('/api/paid/2d/component?pageSize=1000', {
  345. list: _list,
  346. });
  347. if (res.error) {
  348. return [];
  349. }
  350. // let purchasedPngs = res.list.filter((item) => list.pngs.has(item));
  351. // let purchasedJs = res.list.filter((item) => list.jsPens.has(item));
  352. // let purchasedIot = res.list.filter((item) => list.iotPens.has(item));
  353. // let purchasedSvg = res.list.filter((item) => list.svgPens.has(item));
  354. // let price =
  355. // ([...list.pngs].length - purchasedPngs.length) * 50 +
  356. // ([...list.jsPens].length - purchasedJs.length) * 10 +
  357. // ([...list.iotPens].length - purchasedIot.length) * 70+
  358. // ([...list.svgPens].length - purchasedSvg.length) * 10;
  359. return res.list;
  360. };
  361. export const get2dComponentJs = async (names: string[] = components) => {
  362. let list = [];
  363. names.forEach((item) => {
  364. list.push({
  365. type: '控件',
  366. name: item,
  367. });
  368. });
  369. const res: any = await axios.post(
  370. '/api/2d-component.js',
  371. {
  372. // list,
  373. },
  374. {
  375. responseType: 'blob',
  376. }
  377. );
  378. return res;
  379. };
  380. export const getTemPngs = async (names: string[]) => {
  381. const res: any = await axios.post('/api/file/presign', {
  382. names,
  383. });
  384. return res;
  385. };
  386. export const getGoods = async () => {
  387. const res: any = await axios.get('/api/goods/2d/component/types');
  388. // console.log("res",res);
  389. return res;
  390. };
  391. export const getDeployGoods = async () => {
  392. const ret:any = await axios.post('/api/goods/list',{
  393. type:'私有部署'
  394. });
  395. return ret.list;
  396. }
  397. export enum Frame {
  398. vue2,
  399. vue3,
  400. react,
  401. html,
  402. zip
  403. }
  404. // export const _preFrameDownload = async (type: Frame) => {
  405. // frameFlag = type;
  406. // // MessagePlugin.info('正在下载打包中,可能需要几分钟,请耐心等待...');
  407. // zip3D(
  408. // type === Frame.vue3 ? 'toVue3' : type === Frame.vue2 ? 'toVue2' : 'toReact'
  409. // );
  410. // zip2D(
  411. // type === Frame.vue3
  412. // ? 'downloadVue3'
  413. // : type === Frame.vue2
  414. // ? 'downloadVue2'
  415. // : 'downloadReact'
  416. // );
  417. // const data: any = meta2d.data();
  418. // if (data._id) delete data._id;
  419. // if (data.id) delete data.id;
  420. // if (data.image) delete data.image;
  421. // data.userId = user.id;
  422. // checkData(data);
  423. // const [{ default: JSZip }, { saveAs }] = await Promise.all([
  424. // import('jszip'),
  425. // import('file-saver'),
  426. // ]);
  427. // const zip = new JSZip();
  428. // let _fileName =
  429. // (data.name && data.name.replace(/\//g, '_').replace(/:/g, '_')) ||
  430. // 'le5le.meta2d';
  431. // //处理付费svg
  432. // if (Object.keys(data.paths).length >= 3) {
  433. // //简单判断有无svg图元
  434. // const res: any = await axios.post('/api/paid/2d/component?pageSize=1000', {
  435. // type: 'SVG线性图元',
  436. // });
  437. // if (res.list.length === 1 && !res.list[0].name) {
  438. // //已经购买全部
  439. // for (let key of Object.keys(data.paths)) {
  440. // let path = data.paths[key];
  441. // if (
  442. // path.indexOf('-1.18Zm4-1') !== -1 ||
  443. // path.indexOf('-1.19Zm4-1') !== -1 ||
  444. // path.indexOf('2.85ZM') !== -1 ||
  445. // path.indexOf('-1-2.39.3') !== -1
  446. // ) {
  447. // data.paths[key] = '';
  448. // }
  449. // }
  450. // } else {
  451. // //购买部分
  452. // let purchasedList = res.list.map((i) => i.name);
  453. // data.pens.forEach((pen) => {
  454. // if (pen.name === 'svgPath' && pen.svgUrl) {
  455. // if (purchasedList.includes(pen.svgUrl.replace(img_cdn, ''))) {
  456. // pen.pathId = null;
  457. // }
  458. // }
  459. // });
  460. // }
  461. // }
  462. // const _zip: any = zip.folder(`${_fileName}`);
  463. // _zip.file(
  464. // `${
  465. // type === Frame.vue3
  466. // ? 'meta2d-vue3'
  467. // : type === Frame.vue2
  468. // ? 'meta2d-vue2'
  469. // : 'meta2d-react'
  470. // }/public/json/data.json`,
  471. // JSON.stringify(data).replaceAll(img_cdn, '').replaceAll(img_upCdn, '')
  472. // );
  473. // await Promise.all([
  474. // zipJs(_zip),
  475. // zipBkImg(_zip),
  476. // zipImages(_zip, meta2d.store.data.pens),
  477. // type === Frame.vue3
  478. // ? zipVue3Files(_zip)
  479. // : type === Frame.vue2
  480. // ? zipVue2Files(_zip)
  481. // : zipReactFiles(_zip),
  482. // zipIotPens(_zip),
  483. // ]);
  484. // const blob = await zip.generateAsync({ type: 'blob' });
  485. // saveAs(blob, `${_fileName}.zip`);
  486. // frameFlag = -1;
  487. // };
  488. // async function zipIotPens(zip: JSZip) {
  489. // //处理控件
  490. // const js = await get2dComponentJs();
  491. // zip.file(
  492. // `${
  493. // frameFlag === Frame.vue3
  494. // ? 'meta2d-vue3'
  495. // : frameFlag === Frame.vue2
  496. // ? 'meta2d-vue2'
  497. // : 'meta2d-react'
  498. // }/public/js/2d-components.js`,
  499. // js,
  500. // { createFolders: true }
  501. // );
  502. // const res: Blob = await axios.get( cdn+'/view/js/r.js', {
  503. // responseType: 'blob',
  504. // });
  505. // zip.file(
  506. // `${
  507. // frameFlag === Frame.vue3
  508. // ? 'meta2d-vue3'
  509. // : frameFlag === Frame.vue2
  510. // ? 'meta2d-vue2'
  511. // : 'meta2d-react'
  512. // }/public/js/r.js`,
  513. // res,
  514. // { createFolders: true }
  515. // );
  516. // }
  517. // async function zipJs(zip: JSZip) {
  518. // const files = ['/view/js/marked.min.js', '/view/js/lcjs.iife.js'];
  519. // await Promise.all(
  520. // files.map(async (filePath) => {
  521. // const res: Blob = await axios.get(cdn+filePath, {
  522. // responseType: 'blob',
  523. // });
  524. // zip.file(
  525. // `${
  526. // frameFlag === Frame.vue3
  527. // ? 'meta2d-vue3'
  528. // : frameFlag === Frame.vue2
  529. // ? 'meta2d-vue2'
  530. // : 'meta2d-react'
  531. // }/public` + filePath.replace('/view', ''),
  532. // res,
  533. // { createFolders: true }
  534. // );
  535. // })
  536. // );
  537. // }
  538. export async function zipBkImg(zip: JSZip) {
  539. let img = meta2d.store.data.bkImage;
  540. if (img) {
  541. if (img.startsWith('/') || img.startsWith(img_cdn) || img.startsWith(img_upCdn)) {
  542. const pngs = await getTemPngs([img.replace(img_cdn, '').replace(img_upCdn, '')]);
  543. await zipImage(zip, img, pngs[img.replace(img_cdn, '').replace(img_upCdn, '')]);
  544. }
  545. }
  546. }
  547. async function zipImage(zip: JSZip, image: string, temImage?: string) {
  548. const res: Blob = await axios.get(temImage || image, {
  549. responseType: 'blob',
  550. // params: {
  551. // isZip: true,
  552. // },
  553. });
  554. zip.file(
  555. (cdn ? image.replace(cdn, '').replace(upCdn, '') : image),
  556. res,
  557. {
  558. createFolders: true,
  559. }
  560. );
  561. }
  562. // const zip3D = (name: string) => {
  563. // const pen_3d = meta2d.store.data.pens.filter(
  564. // (pen) =>
  565. // pen.name === 'iframe' &&
  566. // (pen.tags.includes('meta3d') || pen.iframe.indexOf('/3d') !== -1)
  567. // );
  568. // if (pen_3d && pen_3d.length) {
  569. // //存在3d场景
  570. // pen_3d.forEach((pen) => {
  571. // //发送消息
  572. // // let params = queryURLParams(pen.iframe.split('?')[1]);
  573. // (
  574. // pen.calculative.singleton.div.children[0] as HTMLIFrameElement
  575. // ).contentWindow.postMessage(
  576. // JSON.stringify({
  577. // type: 1,
  578. // name,
  579. // // id: params.id,
  580. // }),
  581. // '*'
  582. // );
  583. // });
  584. // }
  585. // };
  586. // const zip2D = (name: string) => {
  587. // const pen_2d = meta2d.store.data.pens.filter(
  588. // (pen) =>
  589. // pen.name === 'iframe' &&
  590. // pen.iframe.indexOf('/2d') !== -1 || pen.iframe.indexOf('data=2d') !== -1 ||
  591. // pen.iframe.indexOf('/view/v') !== -1 ||pen.iframe.indexOf('data=v') !== -1||
  592. // pen.iframe.indexOf('/preview') !== -1)
  593. // );
  594. // if (pen_2d && pen_2d.length) {
  595. // //存在3d场景
  596. // pen_2d.forEach((pen) => {
  597. // //发送消息
  598. // // let params = queryURLParams(pen.iframe.split('?')[1]);
  599. // (
  600. // pen.calculative.singleton.div.children[0] as HTMLIFrameElement
  601. // ).contentWindow.postMessage(
  602. // JSON.stringify({
  603. // name,
  604. // type: 1,
  605. // }),
  606. // '*'
  607. // );
  608. // });
  609. // }
  610. // };
  611. /**
  612. * 图片放到 zip 里
  613. * @param pens 可以是非具有 calculative 的 pen
  614. */
  615. export async function zipImages(zip: JSZip, pens: Pen[]) {
  616. if (!pens) {
  617. return;
  618. }
  619. // 不止 image 上有图片, strokeImage ,backgroundImage 也有图片
  620. const imageKeys = [
  621. {
  622. string: 'image',
  623. },
  624. { string: 'strokeImage' },
  625. { string: 'backgroundImage' },
  626. ] as const;
  627. const images: string[] = [];
  628. for (const pen of pens) {
  629. for (const i of imageKeys) {
  630. const image = pen[i.string];
  631. if (image) {
  632. // HTMLImageElement 无法精确控制图片格式
  633. if (
  634. image.startsWith('/') ||
  635. image.startsWith(cdn) ||
  636. image.startsWith(upCdn)
  637. ) {
  638. // 只考虑相对路径下的 image ,绝对路径图片无需下载
  639. if (!images.includes(image)) {
  640. images.push(image);
  641. }
  642. }
  643. }
  644. }
  645. // 无需递归遍历子节点,现在所有的节点都在外层
  646. }
  647. //付费pngs
  648. const pngs = await getTemPngs(
  649. images.map((i) => i.replace(img_cdn, '').replace(img_upCdn, ''))
  650. );
  651. await Promise.all(
  652. images.map((image) =>
  653. zipImage(zip, image, pngs[image.replace(img_cdn, '').replace(img_upCdn, '')])
  654. )
  655. );
  656. }
  657. //新
  658. // async function zipVue3Files(zip: JSZip) {
  659. // const files = [
  660. // '/view/meta2d-vue3/src/components/Meta2d.vue',
  661. // '/view/meta2d-vue3/src/App.vue',
  662. // '/view/meta2d-vue3/src/main.js',
  663. // '/view/meta2d-vue3/src/style.css',
  664. // '/view/meta2d-vue3/index.html',
  665. // '/view/meta2d-vue3/package.json',
  666. // '/view/meta2d-vue3/README.md',
  667. // '/view/meta2d-vue3/vite.config.js',
  668. // ] as const;
  669. // // 文件同时加载
  670. // await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
  671. // }
  672. // async function zipVue2Files(zip: JSZip) {
  673. // const files = [
  674. // '/view/meta2d-vue2/src/components/Meta2d.vue',
  675. // '/view/meta2d-vue2/src/App.vue',
  676. // '/view/meta2d-vue2/src/main.js',
  677. // // '/view/meta2d-vue2/src/style.css',
  678. // '/view/meta2d-vue2/public/index.html',
  679. // '/view/meta2d-vue2/package.json',
  680. // '/view/meta2d-vue2/README.md',
  681. // // '/view/meta2d-vue3/vite.config.js',
  682. // ] as const;
  683. // // 文件同时加载
  684. // await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
  685. // }
  686. // async function zipReactFiles(zip: JSZip) {
  687. // const files = [
  688. // '/view/meta2d-react/src/index.css',
  689. // '/view/meta2d-react/src/index.js',
  690. // '/view/meta2d-react/src/Meta2d.css',
  691. // '/view/meta2d-react/src/Meta2d.jsx',
  692. // '/view/meta2d-react/package.json',
  693. // '/view/meta2d-react/README.md',
  694. // '/view/meta2d-react/public/index.html',
  695. // ] as const;
  696. // // 文件同时加载
  697. // await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
  698. // }
  699. // async function zipFile(zip: JSZip, filePath: string) {
  700. // const res: Blob = await axios.get(
  701. // (cdn ? cdn + '/v' : import.meta.env.BASE_URL.slice(0, -1)) + filePath,
  702. // {
  703. // responseType: 'blob',
  704. // }
  705. // );
  706. // zip.file(filePath.replace('/view', ''), res, { createFolders: true });
  707. // }
  708. export const getFrameDownloadList =(meta2dData: any, path: string = 'v',type:Frame, flag_3d=false) => {
  709. const lists = new Set();
  710. let img = meta2dData.bkImage;
  711. if (img) {
  712. if (
  713. img.startsWith('/') ||
  714. img.startsWith(img_cdn) ||
  715. img.startsWith(img_upCdn)
  716. ) {
  717. let _img = img.replace(img_cdn, '').replace(img_upCdn, '');
  718. if (_img.startsWith('/v/')) {
  719. _img = _img.slice(2);
  720. }
  721. _img = decodeURIComponent(_img);
  722. lists.add({
  723. url: img,
  724. path: (`${
  725. type === Frame.vue3
  726. ? 'meta2d-vue3'
  727. : type === Frame.vue2
  728. ? 'meta2d-vue2'
  729. : 'meta2d-react'
  730. }/public`) + _img,
  731. });
  732. meta2dData.bkImage = _img;
  733. }
  734. }
  735. //图片图元(image strokeImage backgroundImage)
  736. const imageKeys = ['image', 'strokeImage', 'backgroundImage'];
  737. const images: string[] = [];
  738. for (const pen of meta2dData.pens) {
  739. for (const i of imageKeys) {
  740. const image = pen[i];
  741. if (image) {
  742. if (
  743. image.startsWith('/') ||
  744. image.startsWith(img_cdn) ||
  745. image.startsWith(img_upCdn)
  746. ) {
  747. // 只考虑相对路径下的 image ,绝对路径图片无需下载
  748. let _img = image.replace(img_cdn, '').replace(img_upCdn, '');
  749. if (_img.startsWith('/v/')) {
  750. _img = _img.slice(2);
  751. }
  752. _img = decodeURIComponent(_img);
  753. let path = (`${
  754. type === Frame.vue3
  755. ? 'meta2d-vue3'
  756. : type === Frame.vue2
  757. ? 'meta2d-vue2'
  758. : 'meta2d-react'
  759. }/public`) + _img
  760. if (!images.includes(image)) {
  761. // let _img = image.replace(cdn, '').replace(upCdn, '');
  762. lists.add({
  763. url: image,
  764. path,
  765. });
  766. }
  767. pen[i] = _img;
  768. }
  769. }
  770. }
  771. pen.events?.forEach((event) => {
  772. if (event.actions?.length) {
  773. event.actions.forEach((action) => {
  774. if (action.action === 1) {
  775. //更改属性
  776. if (action.value?.image) {
  777. let image = action.value.image;
  778. if (
  779. image.startsWith('/') ||
  780. image.startsWith(img_cdn) ||
  781. image.startsWith(img_upCdn)
  782. ) {
  783. // 只考虑相对路径下的 image ,绝对路径图片无需下载
  784. let _img = image.replace(img_cdn, '').replace(img_upCdn, '');
  785. if (_img.startsWith('/v/')) {
  786. _img = _img.slice(2);
  787. }
  788. _img = decodeURIComponent(_img);
  789. let path = (`${
  790. type === Frame.vue3
  791. ? 'meta2d-vue3'
  792. : type === Frame.vue2
  793. ? 'meta2d-vue2'
  794. : 'meta2d-react'
  795. }/public`) + _img
  796. if (!images.includes(image)) {
  797. // let _img = image.replace(cdn, '').replace(upCdn, '');
  798. lists.add({
  799. url: image,
  800. path,
  801. });
  802. }
  803. action.value.image = _img;
  804. }
  805. }
  806. }
  807. });
  808. }
  809. });
  810. pen.triggers?.forEach((trigger) => {
  811. trigger?.status?.forEach((state) => {
  812. if (state.actions?.length) {
  813. state.actions.forEach((action) => {
  814. if (action.action === 1) {
  815. //更改属性
  816. if (action.value?.image) {
  817. let image = action.value.image;
  818. if (
  819. image.startsWith('/') ||
  820. image.startsWith(img_cdn) ||
  821. image.startsWith(img_upCdn)
  822. ) {
  823. // 只考虑相对路径下的 image ,绝对路径图片无需下载
  824. let _img = image.replace(img_cdn, '').replace(img_upCdn, '');
  825. if (_img.startsWith('/v/')) {
  826. _img = _img.slice(2);
  827. }
  828. _img = decodeURIComponent(_img);
  829. let path = (`${
  830. type === Frame.vue3
  831. ? 'meta2d-vue3'
  832. : type === Frame.vue2
  833. ? 'meta2d-vue2'
  834. : 'meta2d-react'
  835. }/public`) + _img
  836. if (!images.includes(image)) {
  837. // let _img = image.replace(cdn, '').replace(upCdn, '');
  838. lists.add({
  839. url: image,
  840. path,
  841. });
  842. }
  843. action.value.image = _img;
  844. }
  845. }
  846. }
  847. });
  848. }
  849. });
  850. });
  851. }
  852. let folderName =type===Frame.vue3?'meta2d-vue3':type===Frame.vue2?'meta2d-vue2': 'meta2d-react';
  853. if(path === 'v'){ //iframe嵌入的页面无需再次下载
  854. //其他文件
  855. let files = [];
  856. let files_3d = [
  857. '/view/index.html',
  858. '/view/favicon.ico',
  859. '/view/view.conf',
  860. '/view/离线部署包使用说明.pdf',
  861. '/view/css/index.css',
  862. //字体
  863. '/view/css/fonts/DS-DIGI-1.ttf',
  864. '/view/css/fonts/DS-DIGIB-2.ttf',
  865. '/view/css/fonts/DS-DIGII-3.ttf',
  866. '/view/css/fonts/DS-DIGIT-4.ttf',
  867. '/view/css/fonts/fonts.css',
  868. '/view/css/fonts/TG-TYPE-Bold.otf',
  869. '/view/css/fonts/TG-TYPE-Regular.otf',
  870. '/view/css/fonts/庞门正道标题体.ttf',
  871. '/view/css/fonts/斗鱼追光体.ttf',
  872. '/view/assets/index.js',
  873. '/view/assets/index.css',
  874. '/view/assets/cloudy.env',
  875. '/view/assets/default.env',
  876. '/view/assets/dusk.env',
  877. '/view/assets/night.env',
  878. '/view/assets/sunny.env',
  879. '/view/assets/cloudy.jpg',
  880. '/view/assets/dusk.jpg',
  881. '/view/assets/night.jpg',
  882. '/view/assets/sunny.jpg',
  883. '/view/assets/luopan.png',
  884. '/view/assets/Rain.png',
  885. '/view/assets/zhizhen.png',
  886. '/view/assets/默认环境光.png',
  887. '/view/assets/draco_decoder_gltf.js',
  888. '/view/assets/draco_wasm_wrapper_gltf.js',
  889. '/view/assets/draco_decoder_gltf.wasm',
  890. ];
  891. switch (type) {
  892. case Frame.vue3:
  893. files =[
  894. '/view/meta2d-vue3/src/router/index.ts',
  895. '/view/meta2d-vue3/src/views/2d/Meta2d.vue',
  896. '/view/meta2d-vue3/src/App.vue',
  897. '/view/meta2d-vue3/src/main.ts',
  898. '/view/meta2d-vue3/src/style.css',
  899. '/view/meta2d-vue3/index.html',
  900. '/view/meta2d-vue3/package.json',
  901. '/view/meta2d-vue3/README.md',
  902. '/view/meta2d-vue3/tsconfig.json',
  903. '/view/meta2d-vue3/tsconfig.node.json',
  904. '/view/meta2d-vue3/vite.config.ts',
  905. ];
  906. // if(flag_3d){
  907. // //存在3d场景
  908. // files_3d.push(...[
  909. // '/meta2d-vue3/src/plugins/meta3d/index.ts',
  910. // '/meta2d-vue3/src/plugins/meta3d/meta3d.css',
  911. // '/meta2d-vue3/src/plugins/meta3d/meta3d.js',
  912. // // '/view/meta2d-vue3/src/views/3d/Meta3d.vue',
  913. // // '/meta2d-vue3/public/meta3d/js/draco_decoder_gltf.js',
  914. // // '/meta2d-vue3/public/meta3d/js/draco_decoder_gltf.wasm',
  915. // // '/meta2d-vue3/public/meta3d/js/draco_wasm_wrapper_gltf.js',
  916. // ]);
  917. // files.push( '/view/meta2d-vue3/src/views/3d/Meta3d.vue',)
  918. // }
  919. break;
  920. case Frame.vue2:
  921. files =[
  922. '/view/meta2d-vue2/src/router/index.js',
  923. '/view/meta2d-vue2/src/views/2d/Meta2d.vue',
  924. '/view/meta2d-vue2/src/App.vue',
  925. '/view/meta2d-vue2/src/main.js',
  926. '/view/meta2d-vue2/index.html',
  927. '/view/meta2d-vue2/package.json',
  928. '/view/meta2d-vue2/README.md',
  929. '/view/meta2d-vue2/vite.config.js'
  930. ];
  931. // if(flag_3d){
  932. // files_3d.push(...[
  933. // '/meta2d-vue2/src/plugins/meta3d/index.js',
  934. // '/meta2d-vue2/src/plugins/meta3d/meta3d.css',
  935. // '/meta2d-vue2/src/plugins/meta3d/meta3d.js',
  936. // // '/meta2d-vue2/src/views/3d/Meta3d.vue',
  937. // // '/meta2d-vue2/public/meta3d/js/draco_decoder_gltf.js',
  938. // // '/meta2d-vue2/public/meta3d/js/draco_decoder_gltf.wasm',
  939. // // '/meta2d-vue2/public/meta3d/js/draco_wasm_wrapper_gltf.js',
  940. // ]);
  941. // files.push( '/view/meta2d-vue2/src/views/3d/Meta3d.vue',)
  942. // }
  943. // break;
  944. case Frame.react:
  945. files =[
  946. '/view/meta2d-react/src/router/index.tsx',
  947. '/view/meta2d-react/src/views/2d/Meta2d.tsx',
  948. '/view/meta2d-react/src/App.tsx',
  949. '/view/meta2d-react/src/index.css',
  950. '/view/meta2d-react/src/main.tsx',
  951. '/view/meta2d-react/index.html',
  952. '/view/meta2d-react/package.json',
  953. '/view/meta2d-react/README.md',
  954. '/view/meta2d-react/tsconfig.json',
  955. '/view/meta2d-react/tsconfig.node.json',
  956. '/view/meta2d-react/vite.config.ts',
  957. ];
  958. // if(flag_3d){
  959. // files_3d.push(...[
  960. // '/meta2d-react/src/plugins/meta3d/index.ts',
  961. // '/meta2d-react/src/plugins/meta3d/meta3d.css',
  962. // '/meta2d-react/src/plugins/meta3d/meta3d.js',
  963. // // '/meta2d-react/src/views/3d/Meta3d.tsx',
  964. // // '/meta2d-react/public/meta3d/js/draco_decoder_gltf.js',
  965. // // '/meta2d-react/public/meta3d/js/draco_decoder_gltf.wasm',
  966. // // '/meta2d-react/public/meta3d/js/draco_wasm_wrapper_gltf.js',
  967. // ]);
  968. // files.push('/view/meta2d-react/src/views/3d/Meta3d.tsx',)
  969. // }
  970. // break;
  971. default:
  972. break;
  973. }
  974. files.forEach((file) => {
  975. lists.add({
  976. url: (cdn ? cdn + '/v' : import.meta.env.BASE_URL.slice(0, -1)) + file,
  977. path: file.replace('/view', ''),
  978. });
  979. });
  980. if(flag_3d){
  981. files_3d.forEach((file) => {
  982. lists.add({
  983. // url: (cdn ? cdn + '/v' : import.meta.env.BASE_URL.slice(0, -1)) + '/view/meta3d/'+file.split('/meta3d/')[1],
  984. // path: file,
  985. url: (cdn ? cdn : '') + file,
  986. path: `/${folderName}/public${file}`,
  987. });
  988. })
  989. }
  990. let jsFiles = [
  991. '/view/js/marked.min.js',
  992. // '/view/js/echarts.min.js',
  993. '/view/js/lcjs.iife.js',
  994. // '/view/js/highcharts.js',
  995. // '/view/js/highcharts-more.js',
  996. '/view/js/r.js',
  997. '/view/icon/font_2395018_nng9x1qhat.css',
  998. '/view/icon/font_2073009_teagntehxt.css',
  999. //字体
  1000. '/view/css/fonts/DS-DIGI-1.ttf',
  1001. '/view/css/fonts/DS-DIGIB-2.ttf',
  1002. '/view/css/fonts/DS-DIGII-3.ttf',
  1003. '/view/css/fonts/DS-DIGIT-4.ttf',
  1004. '/view/css/fonts/fonts.css',
  1005. '/view/css/fonts/TG-TYPE-Bold.otf',
  1006. '/view/css/fonts/TG-TYPE-Regular.otf',
  1007. '/view/css/fonts/庞门正道标题体.ttf',
  1008. '/view/css/fonts/斗鱼追光体.ttf',
  1009. // '/view/assets/cloudy.env',
  1010. // '/view/assets/default.env',
  1011. // '/view/assets/dusk.env',
  1012. // '/view/assets/night.env',
  1013. // '/view/assets/sunny.env',
  1014. // '/view/assets/cloudy.jpg',
  1015. // '/view/assets/dusk.jpg',
  1016. // '/view/assets/night.jpg',
  1017. // '/view/assets/sunny.jpg',
  1018. // '/view/assets/luopan.png',
  1019. // '/view/assets/Rain.png',
  1020. // '/view/assets/zhizhen.png',
  1021. // '/view/assets/默认环境光.png',
  1022. // '/view/assets/draco_decoder_gltf.js',
  1023. // '/view/assets/draco_wasm_wrapper_gltf.js',
  1024. // '/view/assets/draco_decoder_gltf.wasm',
  1025. '/view/css/v/iconfont.css',
  1026. '/view/css/v/iconfont.ttf',
  1027. '/view/css/v/iconfont.woff',
  1028. '/view/css/v/iconfont.woff2',
  1029. '/view/css/v/iconfont.svg',
  1030. //echarts 主题
  1031. '/theme/dark.json',
  1032. '/theme/light.json',
  1033. ]
  1034. jsFiles.forEach((file) => {
  1035. lists.add({
  1036. url: (cdn ? cdn + '/v' : import.meta.env.BASE_URL.slice(0, -1))+ file,
  1037. path:`/${folderName}/public${file.replace('/view', '')}`,
  1038. });
  1039. });
  1040. }
  1041. //图纸数据
  1042. if (meta2dData._id) delete meta2dData._id;
  1043. if (meta2dData.id) delete meta2dData.id;
  1044. if ((meta2dData as any).image) delete (meta2dData as any).image;
  1045. lists.add({
  1046. data: JSON.stringify(meta2dData)
  1047. .replaceAll(img_cdn, '')
  1048. .replaceAll(img_upCdn, ''),
  1049. path: `/${folderName}/public/json/${path}.json`,
  1050. });
  1051. return lists;
  1052. };
  1053. export const getDownloadZipList = (meta2dData: any, zips:any) => {
  1054. const lists = new Set();
  1055. // const pngs = new Set<string>();
  1056. if (meta2dData._id) delete meta2dData._id;
  1057. if (meta2dData.id) delete meta2dData.id;
  1058. let _fileName =
  1059. (meta2dData.name && meta2dData.name.replace(/\//g, '_').replace(/:/g, '_')) ||
  1060. 'unimat.iot';
  1061. lists.add({
  1062. data:JSON.stringify(meta2dData).replaceAll(img_cdn, '').replaceAll(img_upCdn, ''),
  1063. path: `${_fileName}.json`
  1064. });
  1065. for (let key in zips) {
  1066. lists.add({
  1067. data:JSON.stringify(zips[key].data)?.replaceAll(img_cdn, '').replaceAll(img_upCdn, ''),
  1068. path: `${key}/${zips[key].data.name?.replace(/\//g, '_')?.replace(/:/g, '_')}.json`
  1069. });
  1070. // zips[key].pngs.forEach(item => pngs.add(item));
  1071. getDataPngs(zips[key].data).forEach(item => lists.add(item));
  1072. }
  1073. getDataPngs(meta2dData).forEach(item => lists.add(item));
  1074. return lists;
  1075. }
  1076. export const getDataPngs = (meta2dData: any)=>{
  1077. const lists = new Set();
  1078. let img = meta2dData.bkImage;
  1079. if (img) {
  1080. if (
  1081. img.startsWith('/') ||
  1082. img.startsWith(img_cdn) ||
  1083. img.startsWith(img_upCdn)
  1084. ) {
  1085. let _img = img.replace(img_cdn, '').replace(img_upCdn, '');
  1086. _img = decodeURIComponent(_img);
  1087. // if (_img.startsWith('/v/')) {
  1088. // _img = _img.slice(2);
  1089. // }
  1090. lists.add({
  1091. url: img,
  1092. path: _img.split('?')[0],
  1093. });
  1094. }
  1095. }
  1096. //图片图元(image strokeImage backgroundImage)
  1097. const imageKeys = ['image', 'strokeImage', 'backgroundImage'];
  1098. const images: string[] = [];
  1099. for (const pen of meta2dData.pens) {
  1100. for (const i of imageKeys) {
  1101. const image = pen[i];
  1102. if (image) {
  1103. if (
  1104. image.startsWith('/') ||
  1105. image.startsWith(img_cdn) ||
  1106. image.startsWith(img_upCdn)
  1107. ) {
  1108. // 只考虑相对路径下的 image ,绝对路径图片无需下载
  1109. let _img = image.replace(img_cdn, '').replace(img_upCdn, '');
  1110. if (!images.includes(image)) {
  1111. // let _img = image.replace(cdn, '').replace(upCdn, '');
  1112. lists.add({
  1113. url: image,
  1114. path:_img.split('?')[0],
  1115. });
  1116. }
  1117. }
  1118. }
  1119. }
  1120. }
  1121. return lists;
  1122. }