diff --git a/packages/backend/src/i18n.ts b/packages/backend/src/i18n.ts index 25d5cf4..16cb792 100644 --- a/packages/backend/src/i18n.ts +++ b/packages/backend/src/i18n.ts @@ -12,16 +12,16 @@ try { dynamicSupportedLngs = entries .filter(dirent => dirent.isFile() && dirent.name.endsWith('.json')) .map(dirent => dirent.name.replace('.json', '')); // Extract lang code from filename - console.log('[i18next] Dynamically detected languages:', dynamicSupportedLngs); + console.log('[i18next] 动态检测到的语言:', dynamicSupportedLngs); } catch (err) { - console.error('[i18next] Error reading locales directory:', err); + console.error('[i18next] 读取 locales 目录时出错:', err); dynamicSupportedLngs = ['en-US']; // Fallback } export const defaultLng = 'en-US'; if (!dynamicSupportedLngs.includes(defaultLng)) { dynamicSupportedLngs.push(defaultLng); - console.warn(`[i18next] Default language '${defaultLng}' not found in detected files, adding it to supported list.`); + console.warn(`[i18next] 在检测到的文件中未找到默认语言 '${defaultLng}',将其添加到支持列表中。`); } export const supportedLngs = dynamicSupportedLngs; // --- 结束动态确定 --- @@ -33,7 +33,7 @@ const i18nInitializationPromise = new Promise((resolve, reject) => { i18next .use(Backend) .init({ - debug: process.env.NODE_ENV === 'development', + debug: false, // 强制禁用 i18next 调试日志 supportedLngs: supportedLngs, fallbackLng: defaultLng, preload: supportedLngs, @@ -46,11 +46,11 @@ const i18nInitializationPromise = new Promise((resolve, reject) => { }, }, (err, t) => { // Init callback if (err) { - console.error('[i18next] Error during initialization:', err); + console.error('[i18next] 初始化过程中出错:', err); i18nInitialized = false; // Mark as not initialized on error return reject(err); // Reject the promise on error } - console.log('[i18next] Initialization complete. Loaded languages:', Object.keys(i18next.store.data || {})); // Safe access to store.data + console.log('[i18next] 初始化完成。已加载语言:', Object.keys(i18next.store.data || {})); // Safe access to store.data i18nInitialized = true; // Mark as initialized resolve(); // Resolve the promise on success }); diff --git a/packages/backend/src/repositories/appearance.repository.ts b/packages/backend/src/repositories/appearance.repository.ts index dd3ec53..b8fcb0c 100644 --- a/packages/backend/src/repositories/appearance.repository.ts +++ b/packages/backend/src/repositories/appearance.repository.ts @@ -155,7 +155,7 @@ const findAndSetDefaultThemeIdIfNull = async (db: sqlite3.Database): Promise(db, `SELECT id FROM terminal_themes WHERE name = ? AND theme_type = 'preset'`, [preset.name]); @@ -260,9 +260,9 @@ export const initializePresetThemes = async (db: Database, presets: Array { this.dispatchNotification(processedNotification).catch(error => { - console.error(`[NotificationDispatcher] Error dispatching notification for channel ${processedNotification.channelType}:`, error); + console.error(`[NotificationDispatcher] 分发通道 ${processedNotification.channelType} 的通知时出错:`, error); }); }); }); - console.log('[NotificationDispatcher] Listening for processed notifications.'); + console.log('[NotificationDispatcher] 正在监听处理后的通知。'); } private async dispatchNotification(notification: ProcessedNotification) { const sender = this.senders.get(notification.channelType); if (!sender) { - console.warn(`[NotificationDispatcher] No sender registered for channel type: ${notification.channelType}. Skipping notification.`); + console.warn(`[NotificationDispatcher] 没有为通道类型注册发送器: ${notification.channelType}。跳过通知。`); return; } - console.log(`[NotificationDispatcher] Dispatching notification via ${notification.channelType}`); + console.log(`[NotificationDispatcher] 正在通过 ${notification.channelType} 分发通知`); try { await sender.send(notification); - console.log(`[NotificationDispatcher] Successfully sent notification via ${notification.channelType}`); + console.log(`[NotificationDispatcher] 已成功通过 ${notification.channelType} 发送通知`); } catch (error) { - console.error(`[NotificationDispatcher] Failed to send notification via ${notification.channelType}:`, error); + console.error(`[NotificationDispatcher] 通过 ${notification.channelType} 发送通知失败:`, error); // 这里可以添加失败重试或记录失败状态的逻辑 } } diff --git a/packages/backend/src/services/notification.processor.service.ts b/packages/backend/src/services/notification.processor.service.ts index 463392f..a5913f7 100644 --- a/packages/backend/src/services/notification.processor.service.ts +++ b/packages/backend/src/services/notification.processor.service.ts @@ -27,21 +27,21 @@ class NotificationProcessorService extends EventEmitter { private async initialize(): Promise { try { - console.log('[NotificationProcessor] Waiting for i18n initialization...'); + console.log('[NotificationProcessor] 等待 i18n 初始化...'); await i18nInitializationPromise; - console.log('[NotificationProcessor] i18n initialized. Registering event listeners...'); + console.log('[NotificationProcessor] i18n 初始化完成。正在注册事件监听器...'); this.registerEventListeners(); this.isInitialized = true; - console.log('[NotificationProcessor] Initialization complete.'); + console.log('[NotificationProcessor] 初始化完成。'); } catch (error) { - console.error('[NotificationProcessor] Failed to initialize due to i18n error:', error); + console.error('[NotificationProcessor] 因 i18n 错误导致初始化失败:', error); } } private registerEventListeners() { if (this.isInitialized) { - console.warn('[NotificationProcessor] Attempted to register listeners multiple times.'); + console.warn('[NotificationProcessor] 尝试多次注册监听器。'); return; } // 监听所有 AppEventType 事件 @@ -51,7 +51,7 @@ class NotificationProcessorService extends EventEmitter { // 使用 setImmediate 或 process.nextTick 避免阻塞事件循环 setImmediate(() => { this.processStandardEvent(eventType, payload).catch(error => { - console.error(`[NotificationProcessor] Error processing event ${eventType}:`, error); + console.error(`[NotificationProcessor] 处理事件 ${eventType} 时出错:`, error); }); }); }); @@ -60,24 +60,24 @@ class NotificationProcessorService extends EventEmitter { eventService.onEvent(AppEventType.TestNotification, (payload) => { setImmediate(() => { this.processTestEvent(payload).catch(error => { - console.error(`[NotificationProcessor] Error processing test event:`, error); + console.error(`[NotificationProcessor] 处理测试事件时出错:`, error); }); }); }); - console.log('[NotificationProcessor] Registered listeners.'); + console.log('[NotificationProcessor] 已注册监听器。'); } private async processStandardEvent(eventType: AppEventType, payload: AppEventPayload) { if (!this.isInitialized) { - console.warn(`[NotificationProcessor] Received event ${eventType} before initialization. Skipping.`); + console.warn(`[NotificationProcessor] 在初始化完成前收到事件 ${eventType}。跳过处理。`); return; } - console.log(`[NotificationProcessor] Received standard event: ${eventType}`, payload); + console.log(`[NotificationProcessor] 收到标准事件: ${eventType}`, payload); const eventKey = eventType as NotificationEvent; // 类型转换,假设 AppEventType 和 NotificationEvent 对应 try { const applicableSettings = await this.repository.getEnabledByEvent(eventKey); - console.log(`[NotificationProcessor] Found ${applicableSettings.length} applicable settings for event ${eventKey}`); + console.log(`[NotificationProcessor] 找到 ${applicableSettings.length} 个适用于事件 ${eventKey} 的设置`); if (applicableSettings.length === 0) { return; // 没有配置需要处理 @@ -94,20 +94,20 @@ class NotificationProcessorService extends EventEmitter { this.processSingleSetting(setting, eventType, payload, translatedEvent, userLang); } } catch (error) { - console.error(`[NotificationProcessor] Failed to fetch settings for event ${eventKey}:`, error); + console.error(`[NotificationProcessor] 获取事件 ${eventKey} 的设置失败:`, error); } } private async processTestEvent(payload: AppEventPayload) { if (!this.isInitialized) { - console.warn(`[NotificationProcessor] Received test event before initialization. Skipping.`); + console.warn(`[NotificationProcessor] 在初始化完成前收到测试事件。跳过处理。`); return; } - console.log(`[NotificationProcessor] Received test event`, payload); + console.log(`[NotificationProcessor] 收到测试事件`, payload); const { testTargetConfig, testTargetChannelType } = payload.details || {}; if (!testTargetConfig || !testTargetChannelType) { - console.error('[NotificationProcessor] Test event payload missing testTargetConfig or testTargetChannelType.'); + console.error('[NotificationProcessor] 测试事件负载缺少 testTargetConfig 或 testTargetChannelType。'); return; } @@ -146,10 +146,10 @@ class NotificationProcessorService extends EventEmitter { if (processedNotification) { this.emit('sendNotification', processedNotification); - console.log(`[NotificationProcessor] Emitting sendNotification for ${setting.channel_type} (Setting ID: ${setting.id}, Event: ${eventType})`); + console.log(`[NotificationProcessor] 正在为 ${setting.channel_type} 发送 sendNotification (设置 ID: ${setting.id}, 事件: ${eventType})`); } } catch (error) { - console.error(`[NotificationProcessor] Error preparing notification for setting ID ${setting.id} and event ${eventType}:`, error); + console.error(`[NotificationProcessor] 为设置 ID ${setting.id} 和事件 ${eventType} 准备通知时出错:`, error); } } @@ -206,7 +206,7 @@ class NotificationProcessorService extends EventEmitter { break; default: - console.warn(`[NotificationProcessor] Unsupported channel type: ${setting.channel_type}`); + console.warn(`[NotificationProcessor] 不支持的通道类型: ${setting.channel_type}`); return null; } diff --git a/packages/backend/src/websocket.ts b/packages/backend/src/websocket.ts index 716cc5e..c92571f 100644 --- a/packages/backend/src/websocket.ts +++ b/packages/backend/src/websocket.ts @@ -196,7 +196,7 @@ const fetchRemoteDockerStatus = async (state: ClientState): Promise<{ available: try { const versionCommand = "docker version --format '{{.Server.Version}}'"; - console.log(`[fetchRemoteDockerStatus] Executing: ${versionCommand} on session ${state.ws.sessionId}`); + // console.log(`[fetchRemoteDockerStatus] Executing: ${versionCommand} on session ${state.ws.sessionId}`); const { stdout: versionStdout, stderr: versionStderr } = await new Promise<{ stdout: string; stderr: string }>((resolve, reject) => { let stdout = ''; let stderr = ''; @@ -225,7 +225,7 @@ const fetchRemoteDockerStatus = async (state: ClientState): Promise<{ available: if (versionStdout.trim()) { - console.log(`[fetchRemoteDockerStatus] Docker version check successful on session ${state.ws.sessionId}. Version: ${versionStdout.trim()}`); + // console.log(`[fetchRemoteDockerStatus] Docker version check successful on session ${state.ws.sessionId}. Version: ${versionStdout.trim()}`); isDockerCmdAvailable = true; } else { @@ -244,7 +244,7 @@ const fetchRemoteDockerStatus = async (state: ClientState): Promise<{ available: try { const psCommand = "docker ps -a --no-trunc --format '{{json .}}'"; - console.log(`[fetchRemoteDockerStatus] Executing: ${psCommand} on session ${state.ws.sessionId}`); + // console.log(`[fetchRemoteDockerStatus] Executing: ${psCommand} on session ${state.ws.sessionId}`); const { stdout: psStdout, stderr: psStderr } = await new Promise<{ stdout: string; stderr: string }>((resolve, reject) => { let stdout = ''; let stderr = ''; @@ -316,7 +316,7 @@ const fetchRemoteDockerStatus = async (state: ClientState): Promise<{ available: try { const statsCommand = `docker stats ${runningContainerIds.join(' ')} --no-stream --format '{{json .}}'`; - console.log(`[fetchRemoteDockerStatus] Executing: ${statsCommand} on session ${state.ws.sessionId}`); + // console.log(`[fetchRemoteDockerStatus] Executing: ${statsCommand} on session ${state.ws.sessionId}`); const { stdout: statsStdout, stderr: statsStderr } = await new Promise<{ stdout: string; stderr: string }>((resolve, reject) => { let stdout = ''; let stderr = ''; @@ -354,7 +354,7 @@ const fetchRemoteDockerStatus = async (state: ClientState): Promise<{ available: console.warn(`[fetchRemoteDockerStatus] Error executing docker stats for session ${state.ws.sessionId}:`, error); } } else { - console.log(`[fetchRemoteDockerStatus] No running containers found on session ${state.ws.sessionId}, skipping docker stats.`); + // console.log(`[fetchRemoteDockerStatus] No running containers found on session ${state.ws.sessionId}, skipping docker stats.`); } @@ -838,8 +838,6 @@ export const initializeWebSocket = async (server: http.Server, sessionParser: Re ws.send(JSON.stringify({ type: 'sftp_error', payload: { message: `SFTP 操作 ${type} 缺少 requestId` } })); return; } - // TODO: 在这里或 SftpService 内部添加 SFTP 操作的审计日志记录 (可选) - // 例如: auditLogService.logAction('SFTP_ACTION', { type, path: payload?.path, userId: ws.userId, ip: state.ipAddress }); try { switch (type) { case 'sftp:readdir':