download.ts 35 KB

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