From 1c0271f55e701ab3d9c958f09310a82dd6eb74c8 Mon Sep 17 00:00:00 2001 From: kuaifan Date: Fri, 4 Jul 2025 23:17:59 +0800 Subject: [PATCH] no message --- docker-compose.yml | 4 +- .../assets/js/components/MicroApps/iframe.vue | 65 +++++++++++++++++-- .../assets/js/components/MicroApps/index.vue | 47 +++++++------- 3 files changed, 88 insertions(+), 28 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index ce1a5081c..6dd391765 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ services: php: container_name: "dootask-php-${APP_ID}" - image: "kuaifan/php:swoole-8.0.rc20" + image: "kuaifan/php:swoole-8.0.rc21" shm_size: 2G ulimits: core: @@ -96,7 +96,7 @@ services: appstore: container_name: "dootask-appstore-${APP_ID}" privileged: true - image: "dootask/appstore:0.1.3" + image: "dootask/appstore:0.1.4" volumes: - shared_data:/usr/share/dootask - /var/run/docker.sock:/var/run/docker.sock diff --git a/resources/assets/js/components/MicroApps/iframe.vue b/resources/assets/js/components/MicroApps/iframe.vue index 29533844f..52b83feb0 100644 --- a/resources/assets/js/components/MicroApps/iframe.vue +++ b/resources/assets/js/components/MicroApps/iframe.vue @@ -42,12 +42,14 @@ export default { mounted() { this.injectMicroApp() + window.addEventListener('message', this.handleMessage.bind(this)) this.$refs.iframe.addEventListener('load', this.handleLoad.bind(this)) this.$refs.iframe.addEventListener('error', this.handleError.bind(this)) }, beforeDestroy() { this.cleanupMicroApp() + window.removeEventListener('message', this.handleMessage.bind(this)) this.$refs.iframe.removeEventListener('load', this.handleLoad.bind(this)) this.$refs.iframe.removeEventListener('error', this.handleError.bind(this)) }, @@ -76,17 +78,72 @@ export default { }) }, + // 处理 iframe 消息 + handleMessage(e) { + if (!this.isFromCurrentIframe(e)) { + return + } + const {type, message} = e.data; + switch (type) { + case 'MICRO_APP_METHOD': + if (!this.data || !this.data.methods) { + return + } + const {id, method, args} = message; + if (this.data.methods[method]) { + const postMessage = (result) => { + this.$refs.iframe.contentWindow.postMessage({ + type: 'MICRO_APP_METHOD_RESULT', + message: {id, result: $A.cloneJSON(result)} + }, '*') + } + const before = this.data.methods[method](...args) + if (before && before.then) { + before.then(postMessage).catch(postMessage) + } else { + postMessage(before) + } + } + break + default: + break + } + }, + + // 验证消息是否来自当前 iframe + isFromCurrentIframe(event) { + try { + const { source } = event + return this.$refs.iframe && source === this.$refs.iframe.contentWindow + } catch (error) { + // console.error('Failed to validate message from current iframe:', error) + return false + } + }, + // 注入 microApp 对象到 iframe injectMicroApp() { try { const iframeWindow = this.$refs.iframe.contentWindow if (iframeWindow && this.data) { - iframeWindow.microApp = { - getData: () => this.data + try { + // 直接注入 microApp 对象 + iframeWindow.microApp = { + getData: () => this.data + } + } catch (crossOriginError) { + // 跨域情况,使用 postMessage 发送 microApp 对象 + iframeWindow.postMessage({ + type: 'MICRO_APP_INJECT', + message: { + type: this.data.type, + props: this.data.props + } + }, '*') } } } catch (error) { - console.error('Failed to inject microApp object:', error) + // console.error('Failed to inject microApp object:', error) } }, @@ -98,7 +155,7 @@ export default { delete iframeWindow.microApp } } catch (error) { - console.error('Failed to cleanup microApp object:', error) + // console.error('Failed to cleanup microApp object:', error) } }, } diff --git a/resources/assets/js/components/MicroApps/index.vue b/resources/assets/js/components/MicroApps/index.vue index f061b3ea5..7d0a5c947 100644 --- a/resources/assets/js/components/MicroApps/index.vue +++ b/resources/assets/js/components/MicroApps/index.vue @@ -237,28 +237,6 @@ export default { back: () => { this.closeByName(name) }, - nextZIndex: () => { - if (typeof window.modalTransferIndex === 'number') { - return window.modalTransferIndex++; - } - return 1000; - }, - selectUsers: async (params) => { - if (!$A.isJson(params)) { - params = {value: params} - } - if ($A.isArray(params.value)) { - params.value = params.value ? [params.value] : [] - } - this.userSelectOptions.value = params.value - delete params.value - this.userSelectOptions.config = params - return await new Promise(resolve => { - this.$refs.userSelect.onSelection((res) => { - return resolve(res) - }) - }) - }, popoutWindow: async (windowConfig = null) => { const app = this.apps.find(item => item.name == name); if (!app) { @@ -294,6 +272,31 @@ export default { }, }); }, + requestAPI: async(params) => { + return await store.dispatch('call', params); + }, + selectUsers: async (params) => { + if (!$A.isJson(params)) { + params = {value: params} + } + if ($A.isArray(params.value)) { + params.value = params.value ? [params.value] : [] + } + this.userSelectOptions.value = params.value + delete params.value + this.userSelectOptions.config = params + return await new Promise(resolve => { + this.$refs.userSelect.onSelection((res) => { + return resolve(res) + }) + }) + }, + nextZIndex: () => { + if (typeof window.modalTransferIndex === 'number') { + return window.modalTransferIndex++; + } + return 1000; + }, extraCallA: (...args) => { if (args.length > 0 && typeof args[0] === 'string') { const methodName = args[0];