guanghulab/modules/m-channel/adapters/module-adapter.js
Guanghu Domestic Migration d1e47f4565
Some checks are pending
自动更新代码和重启 / update-and-restart (push) Waiting to run
CI检查 + 自动部署 / check (push) Waiting to run
CI检查 + 自动部署 / deploy (push) Blocked by required conditions
重启聊天服务 / restart (push) Waiting to run
chore: import sanitized domestic snapshot for REPO-002
Source snapshot: ca48d3ddf926d79aa138306164169baf764bb829
2026-07-17 15:54:41 +08:00

141 lines
5.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 模块适配器核心 - 万能转接头
window.ModuleAdapter = {
// 已加载的真实模块缓存
loadedModules: {},
// 适配器配置
config: {
m06: {
name: '工单管理',
path: '/m06-ticket/index.html', // 真实路径,但文件可能不全
width: '100%',
height: '500px',
events: ['ticket:create', 'ticket:update', 'ticket:delete']
},
m08: {
name: '数据统计',
path: '/modules/m08/index.html', // 暂时未知,先保留错误路径触发边界
width: '100%',
height: '500px',
events: ['stats:refresh', 'stats:export']
},
m11: {
name: '组件库',
path: '/m11-module/index.html', // 正确路径!
width: '100%',
height: '600px',
events: ['theme:change', 'component:select']
}
},
// 加载真实模块(通过 iframe 沙箱)
loadModule: function(moduleId, containerId) {
console.log(`[adapter] 加载真实模块: ${moduleId}`);
const container = document.getElementById(containerId);
if (!container) {
console.error(`[adapter] 容器 ${containerId} 不存在`);
return null;
}
// 清理容器
container.innerHTML = '';
const config = this.config[moduleId];
if (!config) {
console.error(`[adapter] 未知模块: ${moduleId}`);
container.innerHTML = `<div class="error-boundary">模块配置不存在</div>`;
return null;
}
// 创建 iframe 沙箱(玻璃展柜)
const iframe = document.createElement('iframe');
iframe.src = config.path;
iframe.style.width = config.width;
iframe.style.height = config.height;
iframe.style.border = 'none';
iframe.style.borderRadius = '8px';
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms allow-popups');
iframe.setAttribute('allow', 'clipboard-read; clipboard-write');
// 添加加载指示器
const loadingDiv = document.createElement('div');
loadingDiv.className = 'module-loading';
loadingDiv.textContent = `加载 ${config.name}...`;
container.appendChild(loadingDiv);
// iframe 加载完成后移除加载指示器
iframe.onload = () => {
loadingDiv.remove();
console.log(`[adapter] ${moduleId} 加载完成`);
// 建立跨框架通信桥梁
this.setupMessageBridge(iframe, moduleId);
};
iframe.onerror = () => {
loadingDiv.remove();
container.innerHTML = `<div class="error-boundary">模块加载失败,请重试 <button onclick="ModuleAdapter.reloadModule('${moduleId}', '${containerId}')">重试</button></div>`;
};
container.appendChild(iframe);
this.loadedModules[moduleId] = { iframe, containerId };
return iframe;
},
// 重新加载模块(错误重试)
reloadModule: function(moduleId, containerId) {
console.log(`[adapter] 重新加载模块: ${moduleId}`);
this.loadModule(moduleId, containerId);
},
// 建立消息桥梁iframe 和主页通信)
setupMessageBridge: function(iframe, moduleId) {
// 监听来自 iframe 的消息
window.addEventListener('message', function(event) {
// 安全检查:确保消息来自正确的 iframe
if (event.source !== iframe.contentWindow) return;
const data = event.data;
if (!data || !data.type) return;
console.log(`[adapter] 收到来自 ${moduleId} 的消息:`, data);
// 转发为事件总线消息
if (window.EventBus) {
EventBus.emit(`module:${moduleId}:message`, {
from: moduleId,
type: data.type,
payload: data.payload
});
}
});
},
// 向模块发送消息
sendMessage: function(moduleId, message) {
const module = this.loadedModules[moduleId];
if (!module || !module.iframe) {
console.error(`[adapter] 模块 ${moduleId} 未加载`);
return false;
}
module.iframe.contentWindow.postMessage(message, '*');
return true;
},
// 卸载模块
unloadModule: function(moduleId) {
const module = this.loadedModules[moduleId];
if (module) {
const container = document.getElementById(module.containerId);
if (container) container.innerHTML = '';
delete this.loadedModules[moduleId];
console.log(`[adapter] 卸载模块: ${moduleId}`);
}
}
};
console.log('[adapter] 模块适配器已加载');