|
@@ -0,0 +1,1721 @@
|
|
|
+import { reactive, ref } from 'vue';
|
|
|
+import { addCollection, updateCollection, getCollection, cdn } from './api';
|
|
|
+import {
|
|
|
+ getPayList,
|
|
|
+ getDownloadList,
|
|
|
+ Frame,
|
|
|
+ get2dComponentJs,
|
|
|
+ getTemPngs,
|
|
|
+ // getDeployPngs,
|
|
|
+ img_cdn,
|
|
|
+ img_upCdn,
|
|
|
+ getFrameDownloadList,
|
|
|
+ getComponentPurchased,
|
|
|
+ getGoods,
|
|
|
+ // getDeployAccess,
|
|
|
+} from './download';
|
|
|
+import { rootDomain } from './defaults';
|
|
|
+import { newFile, queryURLParams } from './common';
|
|
|
+import axios from 'axios';
|
|
|
+import { MessagePlugin } from 'tdesign-vue-next';
|
|
|
+import { useUser } from '@/services/user';
|
|
|
+import { getResource } from './handle3d';
|
|
|
+import { s8 } from './random';
|
|
|
+import { load3d } from './load3d';
|
|
|
+import router from '@/router';
|
|
|
+import { noLoginTip } from './utils';
|
|
|
+import localforage from 'localforage';
|
|
|
+
|
|
|
+export const activedGroup = ref('');
|
|
|
+export const activeAssets = ref('system');
|
|
|
+
|
|
|
+const { user } = useUser();
|
|
|
+
|
|
|
+const isVip = () => {
|
|
|
+ if (!(user && user.id)) {
|
|
|
+ MessagePlugin.warning(noLoginTip);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!user.vip) {
|
|
|
+ MessagePlugin.info('需要开通会员~');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+};
|
|
|
+
|
|
|
+const taskDialog = reactive({
|
|
|
+ visible: false,
|
|
|
+ tasks: [],
|
|
|
+ cancel: false,
|
|
|
+ reload: false,
|
|
|
+ downloadList: [],
|
|
|
+});
|
|
|
+
|
|
|
+export const useTask = () => {
|
|
|
+ const setTask = (key, value) => {
|
|
|
+ taskDialog[key] = value;
|
|
|
+ };
|
|
|
+
|
|
|
+ return {
|
|
|
+ taskDialog,
|
|
|
+ setTask,
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+export const reDownload = async () => {
|
|
|
+ taskDialog.tasks[1].status = 'process';
|
|
|
+ taskDialog.reload = false;
|
|
|
+ let result = await saveZip(taskDialog.downloadList);
|
|
|
+ if (result === 'error') {
|
|
|
+ taskDialog.tasks[1].status = 'error';
|
|
|
+ taskDialog.reload = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ taskDialog.tasks[1].status = 'success';
|
|
|
+
|
|
|
+ MessagePlugin.closeAll();
|
|
|
+ taskDialog.tasks[2].status = 'success';
|
|
|
+ MessagePlugin.success('下载成功,请在浏览器下载列表中查看');
|
|
|
+ taskDialog.visible = false;
|
|
|
+};
|
|
|
+
|
|
|
+const payDialog = reactive({
|
|
|
+ visible: false,
|
|
|
+ data: {
|
|
|
+ price: 0,
|
|
|
+ list: [],
|
|
|
+ hasJs: false,
|
|
|
+ checked: true,
|
|
|
+ },
|
|
|
+ token: false,
|
|
|
+});
|
|
|
+
|
|
|
+export const usePay = () => {
|
|
|
+ const setPay = (key, value) => {
|
|
|
+ payDialog[key] = value;
|
|
|
+ };
|
|
|
+
|
|
|
+ return {
|
|
|
+ payDialog,
|
|
|
+ setPay,
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+const prePay = async () => {
|
|
|
+ if (user.vipData?.deployment) {
|
|
|
+ //可视化会员
|
|
|
+ if ((user.vipData.deployment & 128) === 128) {
|
|
|
+ //直接下载
|
|
|
+ payDialog.token = true;
|
|
|
+ doDownloadProjectSource();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //TODO 付费
|
|
|
+ let purchased = await getComponentPurchased({
|
|
|
+ pngs: [...prePayList.pngs],
|
|
|
+ jsPens: [],
|
|
|
+ iotPens: [],
|
|
|
+ svgPens: [],
|
|
|
+ });
|
|
|
+ if (
|
|
|
+ [...prePayList.jsPens].length ||
|
|
|
+ [...prePayList.iotPens].length ||
|
|
|
+ [...prePayList.svgPens].length
|
|
|
+ ) {
|
|
|
+ payDialog.data.hasJs = true;
|
|
|
+ } else {
|
|
|
+ payDialog.data.hasJs = false;
|
|
|
+ }
|
|
|
+ let names = purchased.map((item) => item.name);
|
|
|
+ let goods = await getGoods();
|
|
|
+ let list = [...prePayList.pngs].filter((item) => !names.includes(item));
|
|
|
+ if (!list.length) {
|
|
|
+ //直接下载
|
|
|
+ doDownloadProjectSource();
|
|
|
+ } else {
|
|
|
+ let unitPrice = goods.find((item) => item.type === '图片图元').unitPrice;
|
|
|
+ payDialog.data.price = unitPrice * list.length;
|
|
|
+ payDialog.data.checked = true;
|
|
|
+ payDialog.visible = true;
|
|
|
+ payDialog.data.list = list;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+export const payProjectDialog = reactive({
|
|
|
+ visible: false,
|
|
|
+ data: {
|
|
|
+ price: 0,
|
|
|
+ payAll: false,
|
|
|
+ list: [],
|
|
|
+ title: '',
|
|
|
+ checked: true,
|
|
|
+ payList: [],
|
|
|
+ },
|
|
|
+ token: '',
|
|
|
+});
|
|
|
+
|
|
|
+/*
|
|
|
+const prePayProject = async () => {
|
|
|
+ if (user.vipData?.deployment) {
|
|
|
+ //可视化会员
|
|
|
+ if ((user.vipData.deployment & 128) === 128) {
|
|
|
+ //直接下载
|
|
|
+ payDialog.token = true;
|
|
|
+ doDownloadProject();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const result: {
|
|
|
+ token?: string;
|
|
|
+ vip?: boolean;
|
|
|
+ error?: string;
|
|
|
+ deployment?: any;
|
|
|
+ } = await getDeployAccess(
|
|
|
+ Object.keys(page3dDatas).length ? '3d,v' : 'v',
|
|
|
+ prePayList
|
|
|
+ );
|
|
|
+ if (result.vip) {
|
|
|
+ if (result.token) {
|
|
|
+ payProjectDialog.token = result.token;
|
|
|
+ doDownloadProject();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //图形库
|
|
|
+ let _goods = await getGoods();
|
|
|
+ let purchasedList = await getComponentPurchased(prePayList);
|
|
|
+ payProjectDialog.data.list = [];
|
|
|
+ // return;
|
|
|
+ payProjectDialog.data.payAll = false;
|
|
|
+ // _goods.forEach((goods)=>{
|
|
|
+
|
|
|
+ for (let i = 0; i < _goods.length; i++) {
|
|
|
+ let goods = _goods[i];
|
|
|
+ let purchased = purchasedList?.filter((_item) => _item.type === goods.type);
|
|
|
+ let names = purchased.map((item) => item.name);
|
|
|
+ let list = [];
|
|
|
+ if (goods.type === '图片图元') {
|
|
|
+ list = [...prePayList.pngs];
|
|
|
+ } else if (goods.type === 'JS线性图元') {
|
|
|
+ list = [...prePayList.jsPens];
|
|
|
+ } else if (goods.type === 'SVG线性图元') {
|
|
|
+ list = [...prePayList.svgPens];
|
|
|
+ } else if (goods.type === '控件') {
|
|
|
+ list = [...prePayList.iotPens];
|
|
|
+ }
|
|
|
+ let num = 0;
|
|
|
+ if (goods.type === 'SVG线性图元' && [...prePayList.svgPens].includes('*')) {
|
|
|
+ //需要购买全部
|
|
|
+ num = goods.count - names.length;
|
|
|
+ payProjectDialog.data.payAll = true;
|
|
|
+ } else {
|
|
|
+ // list.forEach((item)=>{
|
|
|
+ for (let j = 0; j < list.length; j++) {
|
|
|
+ let item = list[j];
|
|
|
+ if (!names.includes(item)) {
|
|
|
+ if (goods.type === '控件') {
|
|
|
+ payProjectDialog.data.list.push({
|
|
|
+ name: item,
|
|
|
+ });
|
|
|
+ } else if (goods.type === 'JS线性图元') {
|
|
|
+ payProjectDialog.data.list.push({
|
|
|
+ svg: globalThis.jsPensMap ? globalThis.jsPensMap[item] : item,
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ payProjectDialog.data.list.push({
|
|
|
+ img: item,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ num += 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ goods.num = num;
|
|
|
+ }
|
|
|
+ let price = 0;
|
|
|
+ for (let i = 0; i < _goods.length; i++) {
|
|
|
+ price += _goods[i].num * _goods[i].unitPrice;
|
|
|
+ }
|
|
|
+ payProjectDialog.data.price = price;
|
|
|
+
|
|
|
+ let payList = [];
|
|
|
+ let names = purchasedList.map((item) => item.name);
|
|
|
+ prePayList.pngs.forEach((item) => {
|
|
|
+ if (!names.includes(item)) {
|
|
|
+ payList.push({
|
|
|
+ type: '图片图元',
|
|
|
+ name: item,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ prePayList.jsPens.forEach((item) => {
|
|
|
+ if (!names.includes(item)) {
|
|
|
+ payList.push({
|
|
|
+ type: 'JS线性图元',
|
|
|
+ name: item,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ prePayList.iotPens.forEach((item) => {
|
|
|
+ if (!names.includes(item)) {
|
|
|
+ payList.push({
|
|
|
+ type: '控件',
|
|
|
+ name: item,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if ([...prePayList.svgPens].includes('*')) {
|
|
|
+ payList.push({
|
|
|
+ type: 'SVG线性图元',
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ prePayList.svgPens.forEach((item) => {
|
|
|
+ if (!names.includes(item)) {
|
|
|
+ payList.push({
|
|
|
+ type: 'SVG线性图元',
|
|
|
+ name: item,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ payProjectDialog.data.checked = true;
|
|
|
+ payProjectDialog.data.payList = payList;
|
|
|
+
|
|
|
+ switch (downloadType) {
|
|
|
+ case Frame.html:
|
|
|
+ payProjectDialog.data.title = '下载离线部署包';
|
|
|
+ break;
|
|
|
+ case Frame.vue2:
|
|
|
+ payProjectDialog.data.title = '下载vue2组件包';
|
|
|
+ break;
|
|
|
+ case Frame.vue3:
|
|
|
+ payProjectDialog.data.title = '下载vue3组件包';
|
|
|
+ break;
|
|
|
+ case Frame.react:
|
|
|
+ payProjectDialog.data.title = '下载react组件包';
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (payProjectDialog.data.price === 0) {
|
|
|
+ doDownloadProject();
|
|
|
+ } else {
|
|
|
+ payProjectDialog.visible = true;
|
|
|
+ }
|
|
|
+};*/
|
|
|
+
|
|
|
+const data = reactive({
|
|
|
+ id: undefined,
|
|
|
+ tree: [
|
|
|
+ // {
|
|
|
+ // value: '1',
|
|
|
+ // label: '文件夹1',
|
|
|
+ // children: [
|
|
|
+ // {
|
|
|
+ // value: '11',
|
|
|
+ // label: '页面1',
|
|
|
+ // type: 'page',
|
|
|
+ // pageId: '1',
|
|
|
+ // pageType: '', //v/2d/3d
|
|
|
+ // tag: '首页',
|
|
|
+ // },
|
|
|
+ // ],
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // value: '2',
|
|
|
+ // label: '文件夹2',
|
|
|
+ // children: [
|
|
|
+ // {
|
|
|
+ // value: '21',
|
|
|
+ // label: '页面1',
|
|
|
+ // type: 'page',
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // value: '22',
|
|
|
+ // label: '页面1',
|
|
|
+ // type: 'page',
|
|
|
+ // },
|
|
|
+ // ],
|
|
|
+ // },
|
|
|
+ ],
|
|
|
+ actived: [],
|
|
|
+});
|
|
|
+
|
|
|
+export const graphicsRef = ref(null);
|
|
|
+const tree = ref();
|
|
|
+const activeNode = ref(null);
|
|
|
+let activePage = null;
|
|
|
+
|
|
|
+//新建工程
|
|
|
+export const newProject = () => {
|
|
|
+ //新建页面
|
|
|
+ newFile();
|
|
|
+ //新建工程
|
|
|
+ data.tree = [
|
|
|
+ {
|
|
|
+ value: s8(),
|
|
|
+ label: '文件夹',
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ value: s8(),
|
|
|
+ label: '页面',
|
|
|
+ type: 'page',
|
|
|
+ pageType: '', //v/2d/3d
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ data.id = undefined;
|
|
|
+
|
|
|
+ //展示工程
|
|
|
+ activeAssets.value = 'structure';
|
|
|
+ graphicsRef.value.assetsChange(activeAssets.value);
|
|
|
+ activedGroup.value = '工程';
|
|
|
+};
|
|
|
+
|
|
|
+const getHomePage = (treeData) => {
|
|
|
+ for (let i = 0; i < treeData.length; i++) {
|
|
|
+ if (treeData[i].type === 'page' && treeData[i].tag === '首页') {
|
|
|
+ return treeData[i];
|
|
|
+ }
|
|
|
+ if (treeData[i].children) {
|
|
|
+ const page = getHomePage(treeData[i].children);
|
|
|
+ if (page) {
|
|
|
+ return page;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+export const loadProject = () => {
|
|
|
+ if (!isVip()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const input = document.createElement('input');
|
|
|
+ input.type = 'file';
|
|
|
+ input.onchange = async (event) => {
|
|
|
+ const elem = event.target as HTMLInputElement;
|
|
|
+ if (elem.files && elem.files[0]) {
|
|
|
+ // 路由跳转 可能在 openFile 后执行
|
|
|
+ if (elem.files[0].name.endsWith('.zip')) {
|
|
|
+ let projectData = await uploadProjectSource(elem.files[0]);
|
|
|
+ if (projectData) {
|
|
|
+ let home = getHomePage(projectData.data);
|
|
|
+ if (!home) {
|
|
|
+ home = projectData.data[0].children?.length
|
|
|
+ ? projectData.data[0].children[0]
|
|
|
+ : projectData.data[0];
|
|
|
+ }
|
|
|
+ router.push({
|
|
|
+ path: '/',
|
|
|
+ query: {
|
|
|
+ r: Date.now() + '',
|
|
|
+ id: home.pageId,
|
|
|
+ },
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取首页
|
|
|
+ if (activedGroup.value !== '工程') {
|
|
|
+ activeAssets.value = 'structure';
|
|
|
+ graphicsRef.value.assetsChange(activeAssets.value);
|
|
|
+ activedGroup.value = '工程';
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ MessagePlugin.info('打开工程文件只支持 zip 格式');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ input.click();
|
|
|
+};
|
|
|
+
|
|
|
+export const useProject = () => {
|
|
|
+ const getProject = async (id: string) => {
|
|
|
+ if (id === data.id) {
|
|
|
+ setActive(meta2d.store.data.id);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const ret: any = await getCollection('web', id);
|
|
|
+ data.tree = ret.data;
|
|
|
+ data.id = ret.id;
|
|
|
+ setActive(meta2d.store.data.id);
|
|
|
+ };
|
|
|
+
|
|
|
+ const setActive = (pageId) => {
|
|
|
+ const find = (treeData) => {
|
|
|
+ for (let i = 0; i < treeData.length; i++) {
|
|
|
+ if (treeData[i].pageId === pageId) {
|
|
|
+ data.actived = [treeData[i].value];
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (treeData[i].children) {
|
|
|
+ find(treeData[i].children);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ find(data.tree);
|
|
|
+ };
|
|
|
+
|
|
|
+ const setProject = async (data) => {};
|
|
|
+
|
|
|
+ const saveProject = async (id?: string, over?: boolean) => {
|
|
|
+ if (!data.tree.length) {
|
|
|
+ //无数据
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!activeNode.value && !over) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (id) {
|
|
|
+ if (!tree.value) {
|
|
|
+ // let activePage = getLeaf(activeNode.value.data.value,data.tree);
|
|
|
+ setData(data.tree, activeNode.value.data.value, 'pageId', id);
|
|
|
+ // activePage.pageId = id;
|
|
|
+ } else {
|
|
|
+ await activeNode.value.setData({ pageId: id });
|
|
|
+ }
|
|
|
+ setData(data.tree, activeNode.value.data.value, 'pageId', id);
|
|
|
+ }
|
|
|
+ // return
|
|
|
+
|
|
|
+ const treeData = (await tree?.value?.getTreeData?.()) || data.tree;
|
|
|
+ if (!(treeData && treeData.length > 0)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const _data = {
|
|
|
+ id: data.id,
|
|
|
+ data: treeData,
|
|
|
+ name: 'test',
|
|
|
+ image: '',
|
|
|
+ };
|
|
|
+ // if(data.id&&!id){
|
|
|
+ // // 已经有工程 没有 不需要更新数据
|
|
|
+ // return data.id;
|
|
|
+ // }
|
|
|
+ if (data.id) {
|
|
|
+ await updateCollection('web', _data);
|
|
|
+ return data.id;
|
|
|
+ } else {
|
|
|
+ const ret: any = await addCollection('web', _data);
|
|
|
+ data.id = ret.id;
|
|
|
+ return ret.id;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const clearProject = () => {
|
|
|
+ data.id = undefined;
|
|
|
+ data.tree = [];
|
|
|
+ };
|
|
|
+
|
|
|
+ const setActivedNode = (node) => {
|
|
|
+ activeNode.value = node;
|
|
|
+ // if(!data.tree){
|
|
|
+
|
|
|
+ // }
|
|
|
+ // activePage = getLeaf(node.data.value,data.tree);
|
|
|
+ };
|
|
|
+ return {
|
|
|
+ data,
|
|
|
+ tree,
|
|
|
+ activePage,
|
|
|
+ activeNode,
|
|
|
+ saveProject,
|
|
|
+ getProject,
|
|
|
+ setProject,
|
|
|
+ clearProject,
|
|
|
+ setActivedNode,
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+const getLeaf = (id, arr: any) => {
|
|
|
+ arr.forEach((item) => {
|
|
|
+ if (item.children) {
|
|
|
+ getLeaf(id, item.children);
|
|
|
+ } else {
|
|
|
+ if (item.value === id) {
|
|
|
+ return item;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const setData = (arr: any, id, key, value) => {
|
|
|
+ arr.forEach((item) => {
|
|
|
+ if (item.children) {
|
|
|
+ setData(item.children, id, key, value);
|
|
|
+ } else {
|
|
|
+ if (item.value === id) {
|
|
|
+ item[key] = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+let downloadType: Frame = Frame.html;
|
|
|
+let pageDatas = {};
|
|
|
+let page3dDatas = {};
|
|
|
+let page2dDatas = {};
|
|
|
+
|
|
|
+const setDownloadType = (type: Frame) => {
|
|
|
+ downloadType = type;
|
|
|
+};
|
|
|
+
|
|
|
+const prePayList = reactive({
|
|
|
+ pngs: new Set<string>(),
|
|
|
+ jsPens: new Set<string>(),
|
|
|
+ iotPens: new Set<string>(),
|
|
|
+ svgPens: new Set<string>(),
|
|
|
+});
|
|
|
+
|
|
|
+let downloadList = [];
|
|
|
+
|
|
|
+const isV = (url) => {
|
|
|
+ return (
|
|
|
+ url.indexOf(`v.le5le.com`) !== -1 ||
|
|
|
+ url.indexOf(`view.le5le.com/v`) !== -1 ||
|
|
|
+ url.indexOf(`/view/v`) !== -1 ||
|
|
|
+ url.indexOf(`/preview`) !== -1
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+const is3D = (url) => {
|
|
|
+ return (
|
|
|
+ url.indexOf(`3d.le5le.com`) !== -1 ||
|
|
|
+ url.indexOf(`view.le5le.com/3d`) !== -1 ||
|
|
|
+ url.indexOf(`/view/3d`) !== -1
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+const is2D = (url) => {
|
|
|
+ return (
|
|
|
+ url.indexOf(`2d.le5le.com`) !== -1 ||
|
|
|
+ url.indexOf(`view.le5le.com/2d`) !== -1 ||
|
|
|
+ url.indexOf(`/view/2d`) !== -1
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+const getPageDataByUrl = async (url) => {
|
|
|
+ // let id = queryURLParams(url.split('?')[1])?.id;
|
|
|
+ let params = queryURLParams(url.split('?')[1]);
|
|
|
+ let id = params?.id;
|
|
|
+ delete params.id;
|
|
|
+ let search = '';
|
|
|
+ for(let key in params){
|
|
|
+ search += `&${key}=${params[key]}`
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isV(url)) {
|
|
|
+ if (!pageDatas[id]) {
|
|
|
+ let data = await getCollection('v', id);
|
|
|
+ pageDatas[id] = data.data;
|
|
|
+ }
|
|
|
+ //TODO 更改图纸中的iframe地址
|
|
|
+ if (downloadType === Frame.html) {
|
|
|
+ return `/view?data=${id}${search}`; //`/view/v?data=${id}`
|
|
|
+ } else {
|
|
|
+ return `/2d?id=${id}${search}`;
|
|
|
+ }
|
|
|
+ } else if (is3D(url)) {
|
|
|
+ if (!page3dDatas[id]) {
|
|
|
+ let data = await getCollection('3d', id);
|
|
|
+ page3dDatas[id] = data.data;
|
|
|
+ }
|
|
|
+ if (downloadType === Frame.html) {
|
|
|
+ return `/view?data=${id}${search}`; //`/view/v?data=${id}`
|
|
|
+ } else {
|
|
|
+ return `/view/index.html?data=${id}${search}`;
|
|
|
+ }
|
|
|
+ } else if (is2D(url)) {
|
|
|
+ if (!page2dDatas[id]) {
|
|
|
+ let data = await getCollection('2d', id);
|
|
|
+ page2dDatas[id] = data.data;
|
|
|
+ }
|
|
|
+ if (downloadType === Frame.html) {
|
|
|
+ return `/view?data=${id}${search}`; //`/view/v?data=${id}`
|
|
|
+ } else {
|
|
|
+ return `/2d?id=${id}${search}`;
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+//获取工程包含的所有数据内容
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @param replace 是否替换地址
|
|
|
+ */
|
|
|
+const getDatas = async (replace = true) => {
|
|
|
+ const list = treeToList(data.tree).filter((item) => item.type && item.pageId);
|
|
|
+ pageDatas = {};
|
|
|
+ page3dDatas = {};
|
|
|
+ page2dDatas = {};
|
|
|
+
|
|
|
+ await Promise.all(
|
|
|
+ list.map(async (item: any) => {
|
|
|
+ let v = await getCollection('v', item.pageId);
|
|
|
+ pageDatas[item.pageId] = v.data;
|
|
|
+ if (v.data?.pens?.length) {
|
|
|
+ // 内嵌iframe网页
|
|
|
+ const pens = v.data.pens.filter(
|
|
|
+ (pen) =>
|
|
|
+ pen.name === 'iframe' &&
|
|
|
+ (isV(pen.iframe) || is3D(pen.iframe) || is2D(pen.iframe))
|
|
|
+ );
|
|
|
+ for (let i = 0; i < pens.length; i++) {
|
|
|
+ let pen = pens[i];
|
|
|
+ let iframe = await getPageDataByUrl(pen.iframe);
|
|
|
+ if (replace) {
|
|
|
+ pen.iframe = iframe;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (let i = 0; i < v.data.pens.length; i++) {
|
|
|
+ let pen = v.data.pens[i];
|
|
|
+ if (pen.events?.length) {
|
|
|
+ for (let j = 0; j < pen.events.length; j++) {
|
|
|
+ //打开弹框
|
|
|
+ const actions = pen.events[j].actions; //.filter((action)=>action.action === 14);
|
|
|
+ for (let k = 0; k < actions.length; k++) {
|
|
|
+ let action = actions[k];
|
|
|
+ if (action.action === 14) {
|
|
|
+ //打开弹框
|
|
|
+ let iframe = await getPageDataByUrl(action.params);
|
|
|
+ if (replace) {
|
|
|
+ action.params = iframe;
|
|
|
+ }
|
|
|
+ } else if (action.action === 1) {
|
|
|
+ //更改iframe属性
|
|
|
+ if (action.value?.iframe) {
|
|
|
+ let iframe = await getPageDataByUrl(action.value.iframe);
|
|
|
+ if (replace) {
|
|
|
+ action.value.iframe = iframe;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (pen.triggers?.length) {
|
|
|
+ for (let j = 0; j < pen.triggers.length; j++) {
|
|
|
+ const trigger = pen.triggers[j];
|
|
|
+ for (let k = 0; k < trigger.status.length; k++) {
|
|
|
+ let status = trigger.status[k];
|
|
|
+ for (let l = 0; l < status.actions.length; l++) {
|
|
|
+ let action = status.actions[l];
|
|
|
+ if (action.action === 14) {
|
|
|
+ //打开弹框
|
|
|
+ // action.params = await getPageDataByUrl(action.params);
|
|
|
+ let iframe = await getPageDataByUrl(action.params);
|
|
|
+ if (replace) {
|
|
|
+ action.params = iframe;
|
|
|
+ }
|
|
|
+ } else if (action.action === 1) {
|
|
|
+ //更改iframe属性
|
|
|
+ if (action.value?.iframe) {
|
|
|
+ // action.value.iframe = await getPageDataByUrl(action.value.iframe);
|
|
|
+ let iframe = await getPageDataByUrl(action.value.iframe);
|
|
|
+ if (replace) {
|
|
|
+ action.value.iframe = iframe;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+const getEnterprisePens = async () => {
|
|
|
+ let pngs = [],
|
|
|
+ jsPens = [],
|
|
|
+ iotPens = [],
|
|
|
+ svgPens = [];
|
|
|
+ for (let key in pageDatas) {
|
|
|
+ const pageData = pageDatas[key];
|
|
|
+ const payList = getPayList(pageData);
|
|
|
+ pngs.push(...payList.pngs);
|
|
|
+ jsPens.push(...payList.jsPens);
|
|
|
+ iotPens.push(...payList.iotPens);
|
|
|
+ svgPens.push(...payList.svgPens);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (let key in page2dDatas) {
|
|
|
+ const pageData = page2dDatas[key];
|
|
|
+ const payList = getPayList(pageData);
|
|
|
+ pngs.push(...payList.pngs);
|
|
|
+ jsPens.push(...payList.jsPens);
|
|
|
+ iotPens.push(...payList.iotPens);
|
|
|
+ svgPens.push(...payList.svgPens);
|
|
|
+ }
|
|
|
+
|
|
|
+ prePayList.pngs = new Set(pngs);
|
|
|
+ prePayList.jsPens = new Set(jsPens);
|
|
|
+ prePayList.iotPens = new Set(iotPens);
|
|
|
+ prePayList.svgPens = new Set(svgPens);
|
|
|
+};
|
|
|
+
|
|
|
+// 下载工程
|
|
|
+export const downloadProject = async (type: Frame) => {
|
|
|
+ // if (!isVip()) {
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+ downloadType = type;
|
|
|
+ //通过工程获取所有的页面数据 ,包括2d 3d v
|
|
|
+ await getDatas();
|
|
|
+ // if (isDownload) {
|
|
|
+ //安装包
|
|
|
+ await doDownloadProject();
|
|
|
+ return;
|
|
|
+ // }
|
|
|
+ //获取 2d 大屏企业图形库
|
|
|
+ // await getEnterprisePens();
|
|
|
+ // await prePayProject();
|
|
|
+};
|
|
|
+
|
|
|
+export const doDownloadProject = async () => {
|
|
|
+ //TODO 验证付费图形库
|
|
|
+ taskDialog.visible = true;
|
|
|
+ taskDialog.tasks = [
|
|
|
+ {
|
|
|
+ status: 'prepare',
|
|
|
+ title: '获取工程数据资源',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ status: 'prepare',
|
|
|
+ title: '下载工程资源',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ status: 'prepare',
|
|
|
+ title: '完成',
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ taskDialog.tasks[0].status = 'process';
|
|
|
+
|
|
|
+ let dList = [];
|
|
|
+ let flag_3d = false;
|
|
|
+ if (downloadType === Frame.html) {
|
|
|
+ for (let key in pageDatas) {
|
|
|
+ // pageDatas[key].userId = user.id;
|
|
|
+ dList.push(...(await getDownloadList(pageDatas[key], key, false)));
|
|
|
+ }
|
|
|
+ for (let key in page2dDatas) {
|
|
|
+ // page2dDatas[key].userId = user.id;
|
|
|
+ dList.push(...(await getDownloadList(page2dDatas[key], key, false)));
|
|
|
+ }
|
|
|
+
|
|
|
+ for (let key in page3dDatas) {
|
|
|
+ flag_3d = true;
|
|
|
+ let source3dList = await getResource(
|
|
|
+ page3dDatas[key].data,
|
|
|
+ key,
|
|
|
+ 'deploy'
|
|
|
+ );
|
|
|
+ dList.push(...source3dList);
|
|
|
+ }
|
|
|
+
|
|
|
+ //下载运行环境文件
|
|
|
+ dList.push(...getDownloadList(undefined, 'v', flag_3d));
|
|
|
+ } else {
|
|
|
+ for (let key in pageDatas) {
|
|
|
+ // pageDatas[key].userId = user.id;
|
|
|
+ dList.push(
|
|
|
+ ...(await getFrameDownloadList(
|
|
|
+ pageDatas[key],
|
|
|
+ key,
|
|
|
+ downloadType,
|
|
|
+ false
|
|
|
+ ))
|
|
|
+ );
|
|
|
+ }
|
|
|
+ for (let key in page2dDatas) {
|
|
|
+ // page2dDatas[key].userId = user.id;
|
|
|
+ dList.push(
|
|
|
+ ...(await getFrameDownloadList(
|
|
|
+ page2dDatas[key],
|
|
|
+ key,
|
|
|
+ downloadType,
|
|
|
+ false
|
|
|
+ ))
|
|
|
+ );
|
|
|
+ }
|
|
|
+ const map = {
|
|
|
+ [Frame.vue2]: 'toVue2',
|
|
|
+ [Frame.vue3]: 'toVue3',
|
|
|
+ [Frame.react]: 'toReact',
|
|
|
+ };
|
|
|
+ for (let key in page3dDatas) {
|
|
|
+ flag_3d = true;
|
|
|
+ let source3dList = await getResource(
|
|
|
+ page3dDatas[key].data,
|
|
|
+ key,
|
|
|
+ map[downloadType]
|
|
|
+ );
|
|
|
+ let folderName =downloadType===Frame.vue3?'meta2d-vue3':downloadType===Frame.vue2?'meta2d-vue2': 'meta2d-react';
|
|
|
+ source3dList.forEach((item) => {
|
|
|
+ if(item.path.startsWith('/vue3/')||item.path.startsWith('/vue2/')||item.path.startsWith('/react/')){
|
|
|
+ item.path = item.path.replace('vue3',folderName).replace('vue2',folderName).replace('react',folderName);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ dList.push(...source3dList);
|
|
|
+ }
|
|
|
+
|
|
|
+ //下载运行环境文件
|
|
|
+ dList.push(...getFrameDownloadList(undefined, 'v', downloadType, flag_3d));
|
|
|
+ }
|
|
|
+ taskDialog.tasks[0].status = 'success';
|
|
|
+ taskDialog.tasks[1].status = 'process';
|
|
|
+ downloadList = uniqueObjArrayFast(dList, 'path');
|
|
|
+
|
|
|
+ //下载列表
|
|
|
+ let result = await saveDownload(downloadList);
|
|
|
+ if (!result) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ taskDialog.tasks[1].status = 'success';
|
|
|
+ taskDialog.tasks[2].status = 'process';
|
|
|
+ taskDialog.visible = false;
|
|
|
+};
|
|
|
+
|
|
|
+const saveDownload = async (downloadList) => {
|
|
|
+ const list = [...downloadList];
|
|
|
+ //控件
|
|
|
+ let jsPath = '';
|
|
|
+ let jsPensPath = '';
|
|
|
+ switch (downloadType) {
|
|
|
+ case Frame.html:
|
|
|
+ jsPath = '/view/js/2d-components.js';
|
|
|
+ jsPensPath = `/view/js/1.js`;
|
|
|
+ break;
|
|
|
+ case Frame.vue2:
|
|
|
+ jsPath = '/meta2d-vue2/public/js/2d-components.js';
|
|
|
+ jsPensPath = `/meta2d-vue2/public/js/1.js`;
|
|
|
+ break;
|
|
|
+ case Frame.vue3:
|
|
|
+ jsPath = '/meta2d-vue3/public/js/2d-components.js';
|
|
|
+ jsPensPath = `/meta2d-vue3/public/js/1.js`;
|
|
|
+ break;
|
|
|
+ case Frame.react:
|
|
|
+ jsPath = '/meta2d-react/public/js/2d-components.js';
|
|
|
+ jsPensPath = `/meta2d-react/public/js/1.js`;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // if (isDownload) {
|
|
|
+ // 安装包
|
|
|
+ list.push({
|
|
|
+ url: '/view/js/2d-components.js', //需要购买
|
|
|
+ path: jsPath,
|
|
|
+ });
|
|
|
+ /*
|
|
|
+ } else {
|
|
|
+ const js = await get2dComponentJs([...prePayList.iotPens]);
|
|
|
+ list.push({
|
|
|
+ data: js,
|
|
|
+ path: jsPath,
|
|
|
+ });
|
|
|
+
|
|
|
+ ///png图形库
|
|
|
+ let pngs: any = {};
|
|
|
+ //TODO token
|
|
|
+ let token = '';
|
|
|
+ if (token) {
|
|
|
+ pngs = await getDeployPngs([...prePayList.pngs], token);
|
|
|
+ } else {
|
|
|
+ pngs = await getTemPngs([...prePayList.pngs]);
|
|
|
+ }
|
|
|
+ list.forEach((item) => {
|
|
|
+ if (item.url) {
|
|
|
+ let url = item.url.replace(img_cdn, '').replace(img_upCdn, '');
|
|
|
+ if (pngs[url]) {
|
|
|
+ item.url = pngs[url];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ //js线性图元
|
|
|
+ let arr = [];
|
|
|
+ if (token) {
|
|
|
+ arr = [...prePayList.jsPens];
|
|
|
+ } else {
|
|
|
+ const res: any = await axios.post(
|
|
|
+ '/api/paid/2d/component?pageSize=1000',
|
|
|
+ {
|
|
|
+ type: 'JS线性图元',
|
|
|
+ collection: 'v',
|
|
|
+ id: meta2d.store.data.id,
|
|
|
+ }
|
|
|
+ );
|
|
|
+ let purchased = [];
|
|
|
+ if (res?.list && res.list.length) {
|
|
|
+ purchased = res.list.map((item) => item.name);
|
|
|
+ }
|
|
|
+ [...prePayList.jsPens].forEach((item) => {
|
|
|
+ if (purchased.includes(item)) {
|
|
|
+ arr.push(item);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ const res_list: any = await axios.post('/api/2d/tools', {
|
|
|
+ list: arr.map((item) => {
|
|
|
+ return {
|
|
|
+ type: 'JS线性图元',
|
|
|
+ name: item,
|
|
|
+ };
|
|
|
+ }),
|
|
|
+ });
|
|
|
+ const json =
|
|
|
+ `!window.meta2dToolId&&(window.meta2dToolId="${res_list?.id}");var tmpTools=` +
|
|
|
+ JSON.stringify(res_list?.list) +
|
|
|
+ `;!window.meta2dTools&&(window.meta2dTools=[]);window.meta2dTools.push.apply(window.meta2dTools,tmpTools);`;
|
|
|
+
|
|
|
+ list.push({
|
|
|
+ data: json,
|
|
|
+ path: jsPensPath,
|
|
|
+ });
|
|
|
+
|
|
|
+ //SVG线性图元
|
|
|
+ if ([...prePayList.svgPens].length) {
|
|
|
+ // let purchased = data.purchasedList?.filter(
|
|
|
+ // (_item) => _item.type === 'SVG线性图元'
|
|
|
+ // );
|
|
|
+ let purchased = [];
|
|
|
+ if (!token) {
|
|
|
+ const res: any = await axios.post(
|
|
|
+ '/api/paid/2d/component?pageSize=1000',
|
|
|
+ {
|
|
|
+ type: 'SVG线性图元',
|
|
|
+ collection: 'v',
|
|
|
+ id: meta2d.store.data.id,
|
|
|
+ }
|
|
|
+ );
|
|
|
+ purchased = res?.list || [];
|
|
|
+ }
|
|
|
+ //TODO
|
|
|
+ let count = 0; // data.goods.find((item) => item.type === 'SVG线性图元')?.count;
|
|
|
+ if (purchased.length === count || token) {
|
|
|
+ // if (purchased.length === 1 && !purchased[0].name) {
|
|
|
+ //已经购买全部
|
|
|
+ list.forEach((item) => {
|
|
|
+ if (
|
|
|
+ item.data &&
|
|
|
+ (item.path.indexOf('/projects/2d') !== -1 ||
|
|
|
+ item.path.indexOf('/projects/v') !== -1 ||
|
|
|
+ item.path.indexOf('/public/json') !== -1) &&
|
|
|
+ item.path.indexOf('/projects/v/png/') === -1 &&
|
|
|
+ item.path.indexOf('/projects/2d/png/') === -1
|
|
|
+ ) {
|
|
|
+ //清空所有svgpath
|
|
|
+ let meta2dData = JSON.parse(item.data);
|
|
|
+ for (let key of Object.keys(meta2dData.paths)) {
|
|
|
+ let path = meta2dData.paths[key];
|
|
|
+ if (
|
|
|
+ path.indexOf('-1.18Zm4-1') !== -1 ||
|
|
|
+ path.indexOf('-1.19Zm4-1') !== -1 ||
|
|
|
+ path.indexOf('2.85ZM') !== -1 ||
|
|
|
+ path.indexOf('-1-2.39.3') !== -1
|
|
|
+ ) {
|
|
|
+ meta2dData.paths[key] = '';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ item.data = JSON.stringify(meta2dData);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ let svgnames = purchased.map((i) => i.name);
|
|
|
+ list.forEach((item) => {
|
|
|
+ if (
|
|
|
+ item.data &&
|
|
|
+ (item.path.indexOf('/projects/2d') !== -1 ||
|
|
|
+ item.path.indexOf('/projects/v') !== -1 ||
|
|
|
+ item.path.indexOf('/public/json') !== -1) &&
|
|
|
+ item.path.indexOf('/projects/v/png/') === -1 &&
|
|
|
+ item.path.indexOf('/projects/2d/png/') === -1
|
|
|
+ ) {
|
|
|
+ //2d 图纸数据
|
|
|
+ let meta2dData = JSON.parse(item.data);
|
|
|
+ meta2dData.pens.forEach((pen) => {
|
|
|
+ if (pen.name === 'svgPath' && pen.svgUrl) {
|
|
|
+ if (svgnames.includes(pen.svgUrl.replace(img_cdn, ''))) {
|
|
|
+ pen.pathId = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ item.data = JSON.stringify(meta2dData);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }*/
|
|
|
+ //开始下载list
|
|
|
+ let result = await saveZip(list);
|
|
|
+ if (result === 'error') {
|
|
|
+ taskDialog.tasks[1].status = 'error';
|
|
|
+ taskDialog.reload = true;
|
|
|
+ taskDialog.downloadList = list;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ MessagePlugin.closeAll();
|
|
|
+ MessagePlugin.success('下载成功,请在浏览器下载列表中查看');
|
|
|
+ return true;
|
|
|
+};
|
|
|
+
|
|
|
+const saveZip = async (list: any[], fileName: string = '工程下载') => {
|
|
|
+ //开始下载list
|
|
|
+ const [{ default: JSZip }, { saveAs }] = await Promise.all([
|
|
|
+ import('jszip'),
|
|
|
+ import('file-saver'),
|
|
|
+ ]);
|
|
|
+ const zip = new JSZip();
|
|
|
+ const _zip = zip.folder(`${fileName}`);
|
|
|
+
|
|
|
+ const results = await Promise.all(
|
|
|
+ list.map(async (item: any) => {
|
|
|
+ if (item.url) {
|
|
|
+ //接口请求
|
|
|
+ try {
|
|
|
+ let url = item.url.startsWith('/') ? cdn + item.url : item.url;
|
|
|
+ if (url.indexOf('/view/index.html') !== -1) {
|
|
|
+ url = url.replace('/view/index.html', '/v/view/index.html'); //线上不包含cdn的inde.html
|
|
|
+ }
|
|
|
+ if (url.includes('?')) {
|
|
|
+ url = url + `&r=${Date.now()}`;
|
|
|
+ } else {
|
|
|
+ url = url + `?r=${Date.now()}`;
|
|
|
+ }
|
|
|
+ let res: Blob = null;
|
|
|
+ let localBlob: any = await localforage.getItem(item.path);
|
|
|
+ if (localBlob) {
|
|
|
+ res = localBlob;
|
|
|
+ } else {
|
|
|
+ res = await axios.get(url, {
|
|
|
+ responseType: 'blob',
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (!res) {
|
|
|
+ throw new Error('请求失败');
|
|
|
+ }
|
|
|
+ localforage.setItem(item.path, res); //缓存
|
|
|
+ let path = item.path.split('?')[0];
|
|
|
+ if (path.startsWith('/')) {
|
|
|
+ path = path.slice(1);
|
|
|
+ }
|
|
|
+ _zip.file(path, res, { createFolders: true });
|
|
|
+ } catch (error) {
|
|
|
+ return { error: error.message,url: item.url}; // 返回错误信息
|
|
|
+ }
|
|
|
+ } else if (item.data) {
|
|
|
+ //直接写数据
|
|
|
+ let path = item.path;
|
|
|
+ if (path.startsWith('/')) {
|
|
|
+ path = path.slice(1);
|
|
|
+ }
|
|
|
+ _zip.file(path, item.data, { createFolders: true });
|
|
|
+ }
|
|
|
+ })
|
|
|
+ );
|
|
|
+ console.log("results",results);
|
|
|
+ let errorLen = results.filter((item) => item && item.error);
|
|
|
+ if (errorLen.length) {
|
|
|
+ MessagePlugin.error('部分文件下载失败,请确保网络畅通');
|
|
|
+ return 'error';
|
|
|
+ }
|
|
|
+ //清除本地存储
|
|
|
+ list.forEach((item) => {
|
|
|
+ localforage.removeItem(item.path);
|
|
|
+ });
|
|
|
+ const blob = await zip.generateAsync({ type: 'blob' });
|
|
|
+ saveAs(blob, `${fileName}.zip`);
|
|
|
+};
|
|
|
+
|
|
|
+//遍历树
|
|
|
+const treeToList = (tree) => {
|
|
|
+ const list = [];
|
|
|
+ for (let i = 0; i < tree.length; i++) {
|
|
|
+ const item = tree[i];
|
|
|
+ list.push(item);
|
|
|
+ if (item.children) {
|
|
|
+ list.push(...treeToList(item.children));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+};
|
|
|
+
|
|
|
+//下载zip资源
|
|
|
+export const downloadProjectSource = async () => {
|
|
|
+ // if (!isVip()) {
|
|
|
+ // return; //非vip用户不能下载
|
|
|
+ // }
|
|
|
+ await getDatas(false);
|
|
|
+ // if (isDownload) {
|
|
|
+ //安装包
|
|
|
+ await doDownloadProjectSource();
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+ // await getEnterprisePens(); //获取企业图库
|
|
|
+ // await prePay();
|
|
|
+};
|
|
|
+
|
|
|
+export const doDownloadProjectSource = async () => {
|
|
|
+ // prePayList.pngs.forEach
|
|
|
+ taskDialog.reload = false;
|
|
|
+ taskDialog.visible = true;
|
|
|
+ taskDialog.tasks = [
|
|
|
+ {
|
|
|
+ status: 'prepare',
|
|
|
+ title: '获取工程数据资源',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ status: 'prepare',
|
|
|
+ title: '下载资源',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ status: 'prepare',
|
|
|
+ title: '完成',
|
|
|
+ },
|
|
|
+ ];
|
|
|
+
|
|
|
+ taskDialog.tasks[0].status = 'process';
|
|
|
+ let dList = [];
|
|
|
+ let imgList = [];
|
|
|
+ for (let key in pageDatas) {
|
|
|
+ imgList.push(...(await getImgList(pageDatas[key])));
|
|
|
+ }
|
|
|
+ for (let key in page2dDatas) {
|
|
|
+ imgList.push(...(await getImgList(page2dDatas[key])));
|
|
|
+ }
|
|
|
+ imgList = uniqueObjArrayFast(imgList, 'path');
|
|
|
+
|
|
|
+ //获取去水印企业图库
|
|
|
+ /*if ([...prePayList.pngs].length && !isDownload) {
|
|
|
+ let pngs: any = {};
|
|
|
+ if (payDialog.token) {
|
|
|
+ pngs = await getDeployPngs(
|
|
|
+ [...prePayList.pngs],
|
|
|
+ undefined
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ pngs = await getTemPngs([...prePayList.pngs]);
|
|
|
+ }
|
|
|
+ if (!pngs) {
|
|
|
+ pngs = {};
|
|
|
+ }
|
|
|
+ imgList.forEach((item) => {
|
|
|
+ if (item.url) {
|
|
|
+ let url = item.url.replace(img_cdn, '').replace(img_upCdn, '');
|
|
|
+ if (pngs[url]) {
|
|
|
+ item.url = pngs[url];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }*/
|
|
|
+
|
|
|
+ dList.push(...imgList);
|
|
|
+ for (let key in pageDatas) {
|
|
|
+ dList.push({
|
|
|
+ data: JSON.stringify(pageDatas[key]),
|
|
|
+ path: `${key}.json`,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ for (let key in page2dDatas) {
|
|
|
+ dList.push({
|
|
|
+ data: JSON.stringify(page2dDatas[key]),
|
|
|
+ path: `${key}.json`,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ //TODO 获取zip包的内容
|
|
|
+ for (let key in page3dDatas) {
|
|
|
+ let source3dList = await getResource(
|
|
|
+ page3dDatas[key].data,
|
|
|
+ '3d-' + key,
|
|
|
+ 'deployAsZip'
|
|
|
+ );
|
|
|
+ dList.push(...source3dList);
|
|
|
+ }
|
|
|
+ dList.push({
|
|
|
+ data: JSON.stringify(data.tree),
|
|
|
+ path: 'project.json',
|
|
|
+ });
|
|
|
+ dList = uniqueObjArrayFast(dList, 'path'); //去重
|
|
|
+ taskDialog.tasks[0].status = 'success';
|
|
|
+ taskDialog.tasks[1].status = 'process';
|
|
|
+
|
|
|
+ //下载
|
|
|
+ //开始下载list
|
|
|
+ let result = await saveZip(dList);
|
|
|
+ if (result === 'error') {
|
|
|
+ taskDialog.tasks[1].status = 'error';
|
|
|
+ taskDialog.reload = true;
|
|
|
+ taskDialog.downloadList = dList;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ taskDialog.tasks[1].status = 'success';
|
|
|
+
|
|
|
+ MessagePlugin.closeAll();
|
|
|
+ taskDialog.tasks[2].status = 'success';
|
|
|
+ MessagePlugin.success('下载成功,请在浏览器下载列表中查看');
|
|
|
+ taskDialog.visible = false;
|
|
|
+};
|
|
|
+
|
|
|
+//TODO 任务取消 是否需要删除已经上传的内容
|
|
|
+export const uploadProjectSource = async (file) => {
|
|
|
+ taskDialog.visible = true;
|
|
|
+ taskDialog.tasks = [
|
|
|
+ {
|
|
|
+ status: 'prepare',
|
|
|
+ title: '解析ZIP文件',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ status: 'prepare',
|
|
|
+ title: '上传资源文件',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ status: 'prepare',
|
|
|
+ title: '生成项目',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ status: 'prepare',
|
|
|
+ title: '完成',
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ // return;
|
|
|
+ //TODO 上传zip包
|
|
|
+ const { default: JSZip } = await import('jszip');
|
|
|
+ const zip = new JSZip();
|
|
|
+ await zip.loadAsync(file, { base64: true });
|
|
|
+
|
|
|
+ taskDialog.tasks[0].status = 'success';
|
|
|
+ taskDialog.tasks[1].status = 'process';
|
|
|
+
|
|
|
+ let fileName = file.name.slice(0, -4);
|
|
|
+ let treeData = '';
|
|
|
+ for (const key in zip.files) {
|
|
|
+ if (zip.files[key].dir) {
|
|
|
+ fileName = key.split('/')[0]; // 取第一个文件夹名称
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (key.endsWith('project.json')) {
|
|
|
+ // 工程json 文件
|
|
|
+ treeData = await zip.file(key).async('string');
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!treeData) {
|
|
|
+ MessagePlugin.error('这不是一个工程包,请重新选择');
|
|
|
+ taskDialog.visible = false;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ const imgMap = {}; //新老图纸映射
|
|
|
+ const _2dDataMap = {}; //2d数据映射
|
|
|
+ const _3dIDMap = {}; //3d id映射
|
|
|
+ const _2dIDMap = {}; //2d id映射
|
|
|
+ //上传所有图片资源
|
|
|
+ for (const key in zip.files) {
|
|
|
+ if (taskDialog.cancel) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (zip.files[key].dir) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ let _keyLower = key.toLowerCase();
|
|
|
+ if (
|
|
|
+ _keyLower.endsWith('.png') ||
|
|
|
+ _keyLower.endsWith('.svg') ||
|
|
|
+ _keyLower.endsWith('.gif') ||
|
|
|
+ _keyLower.endsWith('.jpg') ||
|
|
|
+ _keyLower.endsWith('.jpeg')
|
|
|
+ ) {
|
|
|
+ let _filename = key.substr(key.lastIndexOf('/') + 1);
|
|
|
+ const form = new FormData();
|
|
|
+ form.append('name', _filename);
|
|
|
+ form.append('directory', '/大屏/图片/默认');
|
|
|
+ form.append('shared', true + '');
|
|
|
+ form.append('file', await zip.file(key).async('blob'));
|
|
|
+ form.append('conflict', 'new');
|
|
|
+ const result: any = await axios.post('/api/image/upload', form);
|
|
|
+ let arr = key.split('/');
|
|
|
+ // arr.shift();
|
|
|
+
|
|
|
+ if (arr[0] === fileName) {
|
|
|
+ arr.shift();
|
|
|
+ }
|
|
|
+ if (arr[0] === fileName) {
|
|
|
+ arr.shift();
|
|
|
+ }
|
|
|
+ let _key = '/' + arr.join('/');
|
|
|
+
|
|
|
+ if (result) {
|
|
|
+ imgMap[_key] = result.url;
|
|
|
+ }
|
|
|
+ } else if (_keyLower.endsWith('.json')) {
|
|
|
+ let arr = key.split('/');
|
|
|
+ if (arr[0] === fileName) {
|
|
|
+ arr.shift();
|
|
|
+ }
|
|
|
+ if (arr[0] === fileName) {
|
|
|
+ arr.shift();
|
|
|
+ }
|
|
|
+ let data = await zip.file(key).async('string');
|
|
|
+ let id = arr[0].split('.')[0];
|
|
|
+ // if(!arr[0].endsWith('.json')){
|
|
|
+ if (!key.endsWith('project.json')) {
|
|
|
+ _2dDataMap[id] = data;
|
|
|
+ }
|
|
|
+ // }
|
|
|
+ } else {
|
|
|
+ //TODO 多个3d场景问题
|
|
|
+ if (key.indexOf('3d') !== -1 && key.indexOf('files/') === -1) {
|
|
|
+ let id_3d = await load3d(zip, key);
|
|
|
+ if (id_3d) {
|
|
|
+ let originId = key.split('3d-')[1];
|
|
|
+ _3dIDMap[originId] = id_3d;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ taskDialog.tasks[1].status = 'success';
|
|
|
+ taskDialog.tasks[2].status = 'process';
|
|
|
+ if (taskDialog.cancel) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //将 图纸里面的地址替换成最新的地址
|
|
|
+ for (let old in imgMap) {
|
|
|
+ let newImg = imgMap[old];
|
|
|
+ for (let key in _2dDataMap) {
|
|
|
+ _2dDataMap[key] = _2dDataMap[key].replaceAll(old, newImg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //上传所有图纸
|
|
|
+ //生成 老图纸和新图纸对应的map
|
|
|
+ let arr = Object.keys(_2dDataMap);
|
|
|
+ // for(let key in _2dDataMap){
|
|
|
+ for (let i = 0; i < arr.length; i++) {
|
|
|
+ if (taskDialog.cancel) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let idata = JSON.parse(_2dDataMap[arr[i]]);
|
|
|
+ const ret: any = await addCollection('v', {
|
|
|
+ data: idata,
|
|
|
+ image: idata.image || 'xxx',
|
|
|
+ name: idata.name || '新建项目',
|
|
|
+ folder: idata.folder,
|
|
|
+ system: false,
|
|
|
+ case: idata.case,
|
|
|
+ });
|
|
|
+ _2dIDMap[arr[i]] = ret.id;
|
|
|
+ }
|
|
|
+ treeData = JSON.parse(treeData);
|
|
|
+ arr = treeToList(treeData)
|
|
|
+ .filter((item) => item.pageId)
|
|
|
+ .map((item) => item.pageId);
|
|
|
+ deepUpdateID(treeData, _2dIDMap);
|
|
|
+ //上传 生成的新的工程树
|
|
|
+ const projectData = {
|
|
|
+ id: data.id,
|
|
|
+ data: treeData,
|
|
|
+ name: 'test',
|
|
|
+ image: '',
|
|
|
+ };
|
|
|
+ const ret: any = await addCollection('web', projectData);
|
|
|
+ const projectId = ret.id;
|
|
|
+
|
|
|
+ //更新图纸里面工程树id内容
|
|
|
+ // for(let key in _2dDataMap){
|
|
|
+ for (let i = 0; i < arr.length; i++) {
|
|
|
+ if (taskDialog.cancel) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let idata = await update2dData(_2dDataMap[arr[i]], _2dIDMap, _3dIDMap);
|
|
|
+ const ret: any = await updateCollection('v', {
|
|
|
+ data: idata,
|
|
|
+ id: _2dIDMap[arr[i]],
|
|
|
+ otherData: { projectId },
|
|
|
+ });
|
|
|
+ _2dIDMap[arr[i]] = ret.id;
|
|
|
+ }
|
|
|
+ taskDialog.tasks[2].status = 'success';
|
|
|
+ taskDialog.tasks[3].status = 'process';
|
|
|
+
|
|
|
+ taskDialog.tasks[3].status = 'success';
|
|
|
+ taskDialog.visible = false;
|
|
|
+ return ret;
|
|
|
+};
|
|
|
+
|
|
|
+//将工程树里面的图纸id替换成新的id
|
|
|
+const deepUpdateID = (treeData, _2dIDMap) => {
|
|
|
+ treeData.forEach((item) => {
|
|
|
+ if (item.children) {
|
|
|
+ deepUpdateID(item.children, _2dIDMap);
|
|
|
+ } else {
|
|
|
+ if (item.type === 'page') {
|
|
|
+ item.pageId = _2dIDMap[item.pageId];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+function getSearch(url){
|
|
|
+ let params = queryURLParams(url.split('?')[1]);
|
|
|
+ let id = params?.id;
|
|
|
+ delete params.id;
|
|
|
+ let search = '';
|
|
|
+ for(let key in params){
|
|
|
+ search += `&${key}=${params[key]}`
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ id,
|
|
|
+ search
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const update2dData = async (_data, _2dIDMap, _3dIDMap) => {
|
|
|
+ let domain = 'https://view.le5le.com';
|
|
|
+ // if (isDownload || location.origin.indexOf('le5le.com') === -1) {
|
|
|
+ domain = location.origin + '/view';
|
|
|
+ // }
|
|
|
+ let data = JSON.parse(_data);
|
|
|
+ if (data.pens?.length) {
|
|
|
+ // 内嵌iframe网页
|
|
|
+ const pens = data.pens.filter(
|
|
|
+ (pen) =>
|
|
|
+ pen.name === 'iframe' &&
|
|
|
+ (isV(pen.iframe) || is3D(pen.iframe) || is2D(pen.iframe))
|
|
|
+ );
|
|
|
+ for (let i = 0; i < pens.length; i++) {
|
|
|
+ let pen = pens[i];
|
|
|
+ let { id, search } = getSearch(pen.iframe);
|
|
|
+ if (is3D(pen.iframe)) {
|
|
|
+ pen.iframe = `${domain}/3d/?id=${_3dIDMap[id]}${search}`;
|
|
|
+ } else {
|
|
|
+ pen.iframe = `${domain}/v/?id=${_2dIDMap[id]}${search}`;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (let i = 0; i < data.pens.length; i++) {
|
|
|
+ let pen = data.pens[i];
|
|
|
+ if (pen.events?.length) {
|
|
|
+ for (let j = 0; j < pen.events.length; j++) {
|
|
|
+ //打开弹框
|
|
|
+ const actions = pen.events[j].actions;
|
|
|
+ for (let k = 0; k < actions.length; k++) {
|
|
|
+ let action = actions[k];
|
|
|
+ if (action.action === 14) {
|
|
|
+ //打开弹框
|
|
|
+ if (
|
|
|
+ is2D(action.params) ||
|
|
|
+ is3D(action.params) ||
|
|
|
+ isV(action.params)
|
|
|
+ ) {
|
|
|
+ // let id = queryURLParams(action.params.split('?')[1])?.id;
|
|
|
+ let { id, search } = getSearch(action.params);
|
|
|
+ action.params = `${domain}/v/?id=${_2dIDMap[id]}${search}`;
|
|
|
+ }
|
|
|
+ } else if (action.action === 1) {
|
|
|
+ //更改iframe属性
|
|
|
+ if (action.value?.iframe) {
|
|
|
+ if (is2D(action.value.iframe) || isV(action.value.iframe)) {
|
|
|
+ // let id = queryURLParams(
|
|
|
+ // action.value.iframe.split('?')[1]
|
|
|
+ // )?.id;
|
|
|
+ let { id, search } = getSearch(action.value.iframe);
|
|
|
+ action.value.iframe = `${domain}/v/?id=${_2dIDMap[id]}${search}`;
|
|
|
+ } else if (is3D(action.value.iframe)) {
|
|
|
+ // let id = queryURLParams(
|
|
|
+ // action.value.iframe.split('?')[1]
|
|
|
+ // )?.id;
|
|
|
+ let { id, search } = getSearch(action.value.iframe);
|
|
|
+ action.value.iframe = `${domain}/3d/?id=${_3dIDMap[id]}${search}`;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (action.action === 13) {
|
|
|
+ //打开视图
|
|
|
+ action.value = _2dIDMap[action.value];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (pen.triggers?.length) {
|
|
|
+ for (let j = 0; j < pen.triggers.length; j++) {
|
|
|
+ const trigger = pen.triggers[j];
|
|
|
+ for (let k = 0; k < trigger.status.length; k++) {
|
|
|
+ let status = trigger.status[k];
|
|
|
+ for (let l = 0; l < status.actions.length; l++) {
|
|
|
+ let action = status.actions[l];
|
|
|
+ if (action.action === 14) {
|
|
|
+ //打开弹框
|
|
|
+ if (
|
|
|
+ is2D(action.params) ||
|
|
|
+ is3D(action.params) ||
|
|
|
+ isV(action.params)
|
|
|
+ ) {
|
|
|
+ // let id = queryURLParams(action.params.split('?')[1])?.id;
|
|
|
+ let { id, search } = getSearch(action.params);
|
|
|
+ action.params = `${domain}/v/?id=${_2dIDMap[id]}${search}`;
|
|
|
+ }
|
|
|
+ } else if (action.action === 1) {
|
|
|
+ //更改iframe属性
|
|
|
+ if (action.value?.iframe) {
|
|
|
+ if (is2D(action.value.iframe) || isV(action.value.iframe)) {
|
|
|
+ // let id = queryURLParams(
|
|
|
+ // action.value.iframe.split('?')[1]
|
|
|
+ // )?.id;
|
|
|
+ let { id, search } = getSearch(action.value.iframe);
|
|
|
+ action.value.iframe = `${domain}/v/?id=${_2dIDMap[id]}${search}`;
|
|
|
+ } else if (is3D(action.value.iframe)) {
|
|
|
+ // let id = queryURLParams(
|
|
|
+ // action.value.iframe.split('?')[1]
|
|
|
+ // )?.id;
|
|
|
+ let { id, search } = getSearch(action.value.iframe);
|
|
|
+ action.value.iframe = `${domain}/3d/?id=${_3dIDMap[id]}${search}`;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (action.action === 13) {
|
|
|
+ //打开视图
|
|
|
+ action.value = _2dIDMap[action.value];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return data;
|
|
|
+};
|
|
|
+
|
|
|
+//去重
|
|
|
+function uniqueObjArrayFast(arr, key) {
|
|
|
+ const seen = {};
|
|
|
+ return arr.filter((item) => {
|
|
|
+ const val = item[key];
|
|
|
+ return seen.hasOwnProperty(val) ? false : (seen[val] = true);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+const uploadProject = async (file) => {};
|
|
|
+
|
|
|
+const getImgList = async (meta2dData) => {
|
|
|
+ let lists = [];
|
|
|
+ let img = meta2dData.bkImage;
|
|
|
+ if (img) {
|
|
|
+ if (
|
|
|
+ img.startsWith('/') ||
|
|
|
+ img.startsWith(img_cdn) ||
|
|
|
+ img.startsWith(img_upCdn)
|
|
|
+ ) {
|
|
|
+ let _img = img.replace(img_cdn, '').replace(img_upCdn, '');
|
|
|
+ if (_img.startsWith('/v/')) {
|
|
|
+ _img = _img.slice(2);
|
|
|
+ }
|
|
|
+ _img = decodeURIComponent(_img);
|
|
|
+ lists.push({
|
|
|
+ url: img,
|
|
|
+ path: _img,
|
|
|
+ });
|
|
|
+ meta2dData.bkImage = _img;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //图片图元(image strokeImage backgroundImage)
|
|
|
+ const imageKeys = ['image', 'strokeImage', 'backgroundImage','activeBgImage','bgImage'];
|
|
|
+ const images: string[] = [];
|
|
|
+ for (const pen of meta2dData.pens) {
|
|
|
+ for (const i of imageKeys) {
|
|
|
+ const image = pen[i];
|
|
|
+ if (image) {
|
|
|
+ if (
|
|
|
+ image.startsWith('/') ||
|
|
|
+ image.startsWith(img_cdn) ||
|
|
|
+ image.startsWith(img_upCdn)
|
|
|
+ ) {
|
|
|
+ // 只考虑相对路径下的 image ,绝对路径图片无需下载
|
|
|
+ let _img = image.replace(img_cdn, '').replace(img_upCdn, '').split('?')[0];
|
|
|
+ if (_img.startsWith('/v/')) {
|
|
|
+ _img = _img.slice(2);
|
|
|
+ }
|
|
|
+ _img = decodeURIComponent(_img);
|
|
|
+ if (!images.includes(image)) {
|
|
|
+ // let _img = image.replace(cdn, '').replace(upCdn, '');
|
|
|
+ lists.push({
|
|
|
+ url: image,
|
|
|
+ path: _img,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ pen[i] = _img;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ pen.events?.forEach((event) => {
|
|
|
+ if (event.actions?.length) {
|
|
|
+ event.actions.forEach((action) => {
|
|
|
+ if (action.action === 1) {
|
|
|
+ //更改属性
|
|
|
+ if (action.value?.image) {
|
|
|
+ let image = action.value.image;
|
|
|
+ if (
|
|
|
+ image.startsWith('/') ||
|
|
|
+ image.startsWith(img_cdn) ||
|
|
|
+ image.startsWith(img_upCdn)
|
|
|
+ ) {
|
|
|
+ // 只考虑相对路径下的 image ,绝对路径图片无需下载
|
|
|
+ let _img = image.replace(img_cdn, '').replace(img_upCdn, '').split('?')[0];
|
|
|
+ if (_img.startsWith('/v/')) {
|
|
|
+ _img = _img.slice(2);
|
|
|
+ }
|
|
|
+ _img = decodeURIComponent(_img);
|
|
|
+ if (!images.includes(image)) {
|
|
|
+ lists.push({
|
|
|
+ url: image,
|
|
|
+ path: _img,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ action.value.image = _img;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ pen.triggers?.forEach((trigger) => {
|
|
|
+ trigger?.status?.forEach((state) => {
|
|
|
+ if (state.actions?.length) {
|
|
|
+ state.actions.forEach((action) => {
|
|
|
+ if (action.action === 1) {
|
|
|
+ //更改属性
|
|
|
+ if (action.value?.image) {
|
|
|
+ let image = action.value.image;
|
|
|
+ if (
|
|
|
+ image.startsWith('/') ||
|
|
|
+ image.startsWith(img_cdn) ||
|
|
|
+ image.startsWith(img_upCdn)
|
|
|
+ ) {
|
|
|
+ // 只考虑相对路径下的 image ,绝对路径图片无需下载
|
|
|
+ let _img = image.replace(img_cdn, '').replace(img_upCdn, '').split('?')[0];
|
|
|
+ if (_img.startsWith('/v/')) {
|
|
|
+ _img = _img.slice(2);
|
|
|
+ }
|
|
|
+ _img = decodeURIComponent(_img);
|
|
|
+ if (!images.includes(image)) {
|
|
|
+ lists.push({
|
|
|
+ url: image,
|
|
|
+ path: _img,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ action.value.image = _img;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ return lists;
|
|
|
+};
|