| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- import { Tray, Menu, dialog, BrowserWindow } from 'electron';
- import { join } from 'path';
- import { getBaseDir } from 'ee-core/ps';
- import { logger } from 'ee-core/log';
- import { app as electronApp } from 'electron';
- import { getMainWindow, getCloseAndQuit, setCloseAndQuit } from 'ee-core/electron';
- import { isSmartWindowOpen } from '../window/smartWindow';
- /**
- * 托盘
- * @class
- */
- class TrayService {
- constructor() {
- this.tray = null;
- this.quitConfirming = false;
- this.config = {
- title: 'electron-egg',
- icon: '/public/images/tray.png'
- }
- }
- /**
- * 创建托盘
- */
- create () {
- logger.info('[tray] load');
- const cfg = this.config;
- const mainWindow = getMainWindow();
- // tray icon
- const iconPath = join(getBaseDir(), cfg.icon);
- /**
- * 托盘退出前确认:退出会中止智能工作台正在进行的对话/任务。
- *
- * <p>托盘点击发生在主进程,此时主窗口可能已经收进托盘(不可见),
- * 没法可靠地在渲染层弹 Ant Design 确认框,所以用系统原生对话框。
- */
- const quitWithConfirm = async () => {
- if (this.quitConfirming) return;
- this.quitConfirming = true;
- try {
- const options = {
- type: 'warning',
- title: '退出程序',
- message: '确认退出清鉴?',
- detail: isSmartWindowOpen()
- ? '退出程序会中止智能工作台中正在进行的对话或任务,已生成的内容会保留。'
- : '退出程序会关闭所有窗口。',
- buttons: ['取消', '退出'],
- defaultId: 0,
- cancelId: 0,
- noLink: true,
- };
- // 有聚焦窗口就挂成它的模态;托盘菜单打开时通常没有聚焦窗口,用独立对话框,
- // 避免始终挂到可能被智能窗口挡住的 mainWindow 后面
- const focused = BrowserWindow.getFocusedWindow();
- const parent = focused && !focused.isDestroyed() ? focused : undefined;
- const result = parent
- ? await dialog.showMessageBox(parent, options)
- : await dialog.showMessageBox(options);
- if (result.response === 1) {
- electronApp.quit();
- }
- } catch (e) {
- logger.error('[tray] 退出确认失败:', e instanceof Error ? e.message : String(e));
- } finally {
- this.quitConfirming = false;
- }
- };
- // 托盘菜单功能列表
- // 智能工作台不放入口:顶栏「智能」开关是唯一入口(案件/账号生命周期也只在主窗口)
- const trayMenuTemplate = [
- {
- label: '显示主窗口',
- click: function () {
- if (mainWindow.isMinimized()) {
- mainWindow.restore();
- }
- mainWindow.show();
- mainWindow.focus();
- }
- },
- {
- label: '退出程序',
- click: () => {
- void quitWithConfirm();
- }
- }
- ]
-
- // 设置一个标识,点击关闭,最小化到托盘
- setCloseAndQuit(false);
- mainWindow.on('close', (event) => {
- if (getCloseAndQuit()) {
- return;
- }
- mainWindow.hide();
- event.preventDefault();
- });
-
- // 实例化托盘
- this.tray = new Tray(iconPath);
- this.tray.setToolTip(cfg.title);
- const contextMenu = Menu.buildFromTemplate(trayMenuTemplate);
- this.tray.setContextMenu(contextMenu);
- // 左键单击的时候能够显示主窗口
- this.tray.on('click', () => {
- mainWindow.show()
- })
- }
- }
- TrayService.toString = () => '[class TrayService]';
- export const trayService = new TrayService();
|