From 2649776a96611369e98070bcd83c89d9ed7cae49 Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Fri, 15 Mar 2024 17:53:34 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20iframe=E5=B5=8C=E5=85=A5=E5=BC=8F?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=B5=84=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/core-frontend/src/permission.ts | 8 +- .../src/store/modules/embedded.ts | 18 +++++ core/core-frontend/src/utils/communication.ts | 77 +++++++++++++++++++ .../src/views/chart/ChartView.vue | 24 ++---- .../src/views/common/DeResourceTree.vue | 19 +++-- .../src/views/dashboard/index.vue | 20 ++++- .../src/views/data-visualization/index.vue | 7 ++ 7 files changed, 143 insertions(+), 30 deletions(-) create mode 100644 core/core-frontend/src/utils/communication.ts diff --git a/core/core-frontend/src/permission.ts b/core/core-frontend/src/permission.ts index c514b93ac5..50ac6bf646 100644 --- a/core/core-frontend/src/permission.ts +++ b/core/core-frontend/src/permission.ts @@ -23,7 +23,7 @@ const { start, done } = useNProgress() const { loadStart, loadDone } = usePageLoading() const whiteList = ['/login', '/de-link', '/chart-view'] // 不重定向白名单 - +const embeddedWhiteList = ['/dvCanvas', '/dashboard'] router.beforeEach(async (to, from, next) => { start() loadStart() @@ -96,7 +96,11 @@ router.beforeEach(async (to, from, next) => { next(nextData) } } else { - if (whiteList.indexOf(to.path) !== -1 || to.path.startsWith('/de-link/')) { + if ( + embeddedWhiteList.includes(to.path) || + whiteList.indexOf(to.path) !== -1 || + to.path.startsWith('/de-link/') + ) { permissionStore.setCurrentPath(to.path) next() } else { diff --git a/core/core-frontend/src/store/modules/embedded.ts b/core/core-frontend/src/store/modules/embedded.ts index ab490b8745..65f1bc56a3 100644 --- a/core/core-frontend/src/store/modules/embedded.ts +++ b/core/core-frontend/src/store/modules/embedded.ts @@ -48,6 +48,16 @@ export const userStore = defineStore('embedded', { }, getResourceId(): string { return this.resourceId + }, + getIframeData(): any { + return { + embeddedToken: this.token, + busiFlag: this.busiFlag, + type: this.type, + dvId: this.dvId, + chartId: this.chartId, + pid: this.pid + } } }, actions: { @@ -74,6 +84,14 @@ export const userStore = defineStore('embedded', { }, setResourceId(resourceId: string) { this.resourceId = resourceId + }, + setIframeData(data: any) { + this.type = data['type'] + this.token = data['embeddedToken'] + this.busiFlag = data['busiFlag'] + this.dvId = data['dvId'] + this.chartId = data['chartId'] + this.pid = data['pid'] } } }) diff --git a/core/core-frontend/src/utils/communication.ts b/core/core-frontend/src/utils/communication.ts new file mode 100644 index 0000000000..1a0e32db1a --- /dev/null +++ b/core/core-frontend/src/utils/communication.ts @@ -0,0 +1,77 @@ +export interface EmbeddedData { + 'de-embedded': boolean + embeddedToken?: string + busiFlag?: string + type?: string + dvId?: string + chartId?: string + pid: string +} + +export const communicationInit = cb => { + window.addEventListener('message', event => { + if (!event.data['de-embedded']) { + return + } + const origin = event.origin + console.log(origin) + const embeddedData: EmbeddedData = event.data + // validate origin + if (cb) { + cb(embeddedData) + } + }) + const readyData = { + ready: true, + msgOrigin: 'de-fit2cloud' + } + window.parent.postMessage(readyData, '*') +} + +export const initOpenHandler = (newWindow, data) => { + if (!data.embeddedToken) { + return + } + window['uuid'] = new Date().getTime() + newWindow['uuid'] = window['uuid'] + 1 + newWindow['name'] = 'de-new-resource-window' + window.addEventListener('message', event => { + if ( + event.data?.msgOrigin !== 'de-inner-fit2cloud' || + event.origin !== window.origin || + event.source['uuid'] !== newWindow['uuid'] + ) { + return + } + data['de-inner-embedded'] = true + if (event.data.ready) { + newWindow.postMessage(data, '/') + } + }) +} + +export const newWindowReady = async cb => { + return new Promise((resolve, reject) => { + if (!window.opener || window['name'] !== 'de-new-resource-window') { + return resolve(null) + } + window.addEventListener('message', event => { + if ( + !event.data['de-inner-embedded'] || + event.origin !== window.origin || + window['uuid'] !== event.source['uuid'] - 1 + ) { + return + } + if (cb) { + cb(event.data) + resolve(true) + } + }) + const readyData = { + ready: true, + msgOrigin: 'de-inner-fit2cloud' + } + window.opener.postMessage(readyData, '/') + }) +} diff --git a/core/core-frontend/src/views/chart/ChartView.vue b/core/core-frontend/src/views/chart/ChartView.vue index 61a94f3c44..72bea1e486 100644 --- a/core/core-frontend/src/views/chart/ChartView.vue +++ b/core/core-frontend/src/views/chart/ChartView.vue @@ -3,9 +3,8 @@ import { shallowRef, defineAsyncComponent, ref, onBeforeUnmount } from 'vue' import { debounce } from 'lodash-es' import { useEmbedded } from '@/store/modules/embedded' import { useAppStoreWithOut } from '@/store/modules/app' -import { useRoute } from 'vue-router' import { onBeforeMount } from 'vue' -const route = useRoute() +import { communicationInit, EmbeddedData } from '@/utils/communication' const embeddedStore = useEmbedded() const appStore = useAppStoreWithOut() @@ -37,21 +36,6 @@ const componentMap = { ScreenPanel, DashboardPanel } -const init = () => { - appStore.setIsIframe(true) - const busiFlag = route.query.busiFlag as string - const dvId = route.query.dvId as string - const chartId = route.query.chartId as string - const type = route.query.type as string - const embeddedToken = route.query.embeddedToken as string - embeddedStore.setBusiFlag(busiFlag) - embeddedStore.setToken(embeddedToken) - embeddedStore.setChartId(chartId) - embeddedStore.setDvId(dvId) - embeddedStore.setType(type) - currentComponent.value = componentMap[type || 'ViewWrapper'] -} - const iframeStyle = ref(null) const setStyle = debounce(() => { iframeStyle.value = { @@ -60,9 +44,13 @@ const setStyle = debounce(() => { } }, 300) onBeforeMount(() => { + communicationInit((data: EmbeddedData) => { + embeddedStore.setIframeData(data) + appStore.setIsIframe(true) + currentComponent.value = componentMap[data.type || 'ViewWrapper'] + }) window.addEventListener('resize', setStyle) setStyle() - init() }) onBeforeUnmount(() => { diff --git a/core/core-frontend/src/views/common/DeResourceTree.vue b/core/core-frontend/src/views/common/DeResourceTree.vue index bf83e67eab..016665426d 100644 --- a/core/core-frontend/src/views/common/DeResourceTree.vue +++ b/core/core-frontend/src/views/common/DeResourceTree.vue @@ -20,6 +20,7 @@ import DeResourceCreateOpt from '@/views/common/DeResourceCreateOpt.vue' import DeResourceCreateOptV2 from '@/views/common/DeResourceCreateOptV2.vue' import { useCache } from '@/hooks/web/useCache' import { findParentIdByChildIdRecursive } from '@/utils/canvasUtils' +import { initOpenHandler } from '@/utils/communication' const { wsCache } = useCache() const dvMainStore = dvMainStoreWithOut() @@ -275,7 +276,8 @@ const operation = (cmd: string, data: BusiTreeNode, nodeType: string) => { curCanvasType.value === 'dataV' ? `#/dvCanvas?opt=copy&pid=${params.pid}&dvId=${data.data}` : `#/dashboard?opt=copy&pid=${params.pid}&resourceId=${data.data}` - window.open(baseUrl, '_blank') + const newWindow = window.open(baseUrl, '_blank') + initOpenHandler(newWindow, embeddedStore.getIframeData) }) } else { resourceGroupOpt.value.optInit(nodeType, data, cmd, ['copy'].includes(cmd)) @@ -292,11 +294,13 @@ const addOperation = ( if (cmd === 'newLeaf') { const baseUrl = curCanvasType.value === 'dataV' ? '#/dvCanvas?opt=create' : '#/dashboard?opt=create' + let newWindow = null if (data?.id) { - window.open(baseUrl + `&pid=${data.id}`, '_blank') + newWindow = window.open(baseUrl + `&pid=${data.id}`, '_blank') } else { - window.open(baseUrl, '_blank') + newWindow = window.open(baseUrl, '_blank') } + initOpenHandler(newWindow, embeddedStore.getIframeData) } else if (cmd === 'newFromTemplate') { // state.templateCreatePid = data?.id // // newFromTemplate @@ -318,7 +322,8 @@ function createNewObject() { const resourceEdit = resourceId => { const baseUrl = curCanvasType.value === 'dataV' ? '#/dvCanvas?dvId=' : '#/dashboard?resourceId=' - window.open(baseUrl + resourceId, '_blank') + const newWindow = window.open(baseUrl + resourceId, '_blank') + initOpenHandler(newWindow, embeddedStore.getIframeData) } const resourceOptFinish = () => { @@ -332,11 +337,13 @@ const resourceCreateFinish = templateData => { curCanvasType.value === 'dataV' ? '#/dvCanvas?opt=create&createType=template' : '#/dashboard?opt=create&createType=template' + let newWindow = null if (state.templateCreatePid) { - window.open(baseUrl + `&pid=${state.templateCreatePid}`, '_blank') + newWindow = window.open(baseUrl + `&pid=${state.templateCreatePid}`, '_blank') } else { - window.open(baseUrl, '_blank') + newWindow = window.open(baseUrl, '_blank') } + initOpenHandler(newWindow, embeddedStore.getIframeData) } const getParentKeys = (tree, targetKey, parentKeys = []) => { diff --git a/core/core-frontend/src/views/dashboard/index.vue b/core/core-frontend/src/views/dashboard/index.vue index 815be1b116..cb93a23e82 100644 --- a/core/core-frontend/src/views/dashboard/index.vue +++ b/core/core-frontend/src/views/dashboard/index.vue @@ -1,5 +1,5 @@