| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- import { BrowserWindow } from 'electron';
- import type { WebContents } from 'electron';
- import { logger } from 'ee-core/log';
- import {
- closeSmartWindow,
- focusMainWindow,
- isSmartWindow,
- isSmartWindowOpen,
- openSmartWindow,
- } from '../service/window/smartWindow';
- /** 主进程 → 渲染进程的跨窗口状态事件通道 */
- export const SYNC_EVENT_CHANNEL = 'app:state';
- interface IpcEventLike {
- sender?: WebContents;
- }
- interface OpenSmartWindowParams {
- fullPath?: string;
- reloadIfOpen?: boolean;
- navigateIfOpen?: boolean;
- }
- interface SyncStateParams {
- event?: {
- type?: string;
- payload?: Record<string, unknown>;
- };
- }
- function toMessage(error: unknown): string {
- return error instanceof Error ? error.message : String(error);
- }
- /**
- * 窗口管理 IPC:通道名 controller/windowCtl/<方法>(ee-core 按文件名自动注册)。
- *
- * 统一返回 { success, data|message },失败不抛到 Electron 层。
- */
- class WindowCtl {
- /** 打开/聚焦智能工作台窗口;params { fullPath?, reloadIfOpen? } */
- async openSmartWindow(params: OpenSmartWindowParams = {}) {
- try {
- openSmartWindow({
- fullPath: params?.fullPath,
- reloadIfOpen: params?.reloadIfOpen === true,
- navigateIfOpen: params?.navigateIfOpen === true,
- });
- return { success: true, data: { open: true } };
- } catch (e) {
- const message = toMessage(e);
- logger.error('[windowCtl] openSmartWindow failed:', message);
- return { success: false, message };
- }
- }
- /** 关闭智能工作台窗口(已关闭时是 no-op) */
- async closeSmartWindow() {
- try {
- closeSmartWindow();
- return { success: true };
- } catch (e) {
- const message = toMessage(e);
- logger.error('[windowCtl] closeSmartWindow failed:', message);
- return { success: false, message };
- }
- }
- async isSmartWindowOpen() {
- return { success: true, data: { open: isSmartWindowOpen() } };
- }
- /** 智能窗口遇到登录失效时,把主窗口拉到前台负责提示 */
- async focusMainWindow() {
- try {
- focusMainWindow();
- return { success: true };
- } catch (e) {
- const message = toMessage(e);
- logger.error('[windowCtl] focusMainWindow failed:', message);
- return { success: false, message };
- }
- }
- /**
- * 渲染进程启动时问一次自己的角色。
- *
- * <p>ee-core 的 IPC 注册是 fn.call(controller, params, event),
- * event.sender 就是发起调用的 webContents。
- */
- async getWindowRole(_params: unknown, event?: IpcEventLike) {
- const win = event?.sender ? BrowserWindow.fromWebContents(event.sender) : null;
- return { success: true, data: { role: isSmartWindow(win) ? 'smart' : 'main' } };
- }
- /**
- * 跨窗口状态同步:把语义事件发给除发送者外的所有窗口。
- *
- * <p>只做转发,不解释业务;接收方负责按事件类型重读事实源或关闭自己。
- */
- async syncState(params: SyncStateParams, event?: IpcEventLike) {
- const payload = params?.event;
- if (!payload?.type) {
- return { success: false, message: '同步事件缺少 type' };
- }
- const senderId = event?.sender?.id;
- for (const win of BrowserWindow.getAllWindows()) {
- if (win.isDestroyed() || win.webContents.isDestroyed()) continue;
- if (senderId && win.webContents.id === senderId) continue;
- try {
- win.webContents.send(SYNC_EVENT_CHANNEL, payload);
- } catch (e) {
- logger.warn('[windowCtl] syncState send failed:', toMessage(e));
- }
- }
- return { success: true };
- }
- }
- WindowCtl.toString = () => 'WindowCtl';
- export default WindowCtl;
|