feat: refine business chat workflow

This commit is contained in:
inman
2026-05-13 23:52:11 +08:00
parent 043d0f0bfe
commit 6b503dcbe9
30 changed files with 4609 additions and 126 deletions

View File

@@ -2,7 +2,7 @@
* Electron Main Process Entry
* Manages window creation, system tray, and IPC handlers
*/
import { app, BrowserWindow, nativeImage, session, shell } from 'electron';
import { app, BrowserWindow, nativeImage, Notification, session, shell } from 'electron';
import type { Server } from 'node:http';
import { join } from 'path';
import { GatewayManager } from '../gateway/manager';
@@ -48,6 +48,7 @@ import { deviceOAuthManager } from '../utils/device-oauth';
import { browserOAuthManager } from '../utils/browser-oauth';
import { whatsAppLoginManager } from '../utils/whatsapp-login';
import { syncAllProviderAuthToRuntime } from '../services/providers/provider-runtime-sync';
import { createCronDesktopReminderHandler, type CronDesktopReminderJob } from '../utils/cron-desktop-reminder';
const WINDOWS_APP_USER_MODEL_ID = 'app.zhinian.assistant';
const PRODUCT_NAME = '智念助手';
@@ -257,13 +258,16 @@ function focusWindow(win: BrowserWindow): void {
win.focus();
}
function focusMainWindow(): void {
function focusMainWindow(route?: string): void {
if (!mainWindow || mainWindow.isDestroyed()) {
return;
}
clearPendingSecondInstanceFocus(mainWindowFocusState);
focusWindow(mainWindow);
if (route) {
mainWindow.webContents.send('navigate', route);
}
}
function createMainWindow(): BrowserWindow {
@@ -426,6 +430,28 @@ async function initialize(): Promise<void> {
// Bridge gateway and host-side events before any auto-start logic runs, so
// renderer subscribers observe the full startup lifecycle.
const handleCronDesktopReminder = createCronDesktopReminderHandler({
resolveJob: async (jobId): Promise<CronDesktopReminderJob | undefined> => {
const result = await gatewayManager.rpc('cron.list', { includeDisabled: true }, 3000);
const jobs = (result as { jobs?: CronDesktopReminderJob[] })?.jobs
?? (Array.isArray(result) ? result as CronDesktopReminderJob[] : []);
return jobs.find((job) => job.id === jobId);
},
notify: (display) => {
if (!Notification.isSupported()) return;
const desktopNotification = new Notification({
title: display.title,
body: display.body,
icon: getAppIconPath(),
silent: false,
});
desktopNotification.on('click', () => {
focusMainWindow(display.route);
});
desktopNotification.show();
},
});
gatewayManager.on('status', (status: { state: string }) => {
hostEventBus.emit('gateway:status', status);
if (status.state === 'running' && !isE2EMode) {
@@ -441,6 +467,11 @@ async function initialize(): Promise<void> {
gatewayManager.on('notification', (notification) => {
hostEventBus.emit('gateway:notification', notification);
if (!isE2EMode) {
void handleCronDesktopReminder(notification).catch((error) => {
logger.warn('Failed to show cron desktop reminder:', error);
});
}
});
gatewayManager.on('chat:message', (data) => {