import { ipcMain, app } from 'electron'; import { IPC_EVENTS } from '@lib/constants'; import { launchLocalChrome } from '@electron/utils/chrome/launchLocalChrome' import { executeScriptService } from '@electron/service/execute-script-service'; import { listScripts, getScript, saveScript, deleteScript, toggleScript, } from '@electron/service/script-store-service'; import { runScriptById } from '@electron/service/script-execution-service'; import { startRecording, stopRecording, } from '@electron/service/script-recorder-service'; import fs from 'fs' import path from 'path' import log from 'electron-log'; const openedTabIndexByChannelName = new Map() function getScriptsDir() { return app.isPackaged ? path.join(__dirname, 'scripts') : path.join(process.cwd(), 'electron/scripts') } export function runTaskOperationService() { const executeScriptServiceInstance = new executeScriptService(); // 脚本管理 IPC ipcMain.handle(IPC_EVENTS.SCRIPT_LIST, async () => { try { return listScripts(); } catch (error: any) { log.error('[SCRIPT_LIST] error:', error); throw error; } }); ipcMain.handle(IPC_EVENTS.SCRIPT_GET, async (_event, id: string) => { try { return getScript(id); } catch (error: any) { log.error('[SCRIPT_GET] error:', error); throw error; } }); ipcMain.handle(IPC_EVENTS.SCRIPT_SAVE, async (_event, input: any) => { try { return saveScript(input); } catch (error: any) { log.error('[SCRIPT_SAVE] error:', error); throw error; } }); ipcMain.handle(IPC_EVENTS.SCRIPT_DELETE, async (_event, id: string) => { try { return deleteScript(id); } catch (error: any) { log.error('[SCRIPT_DELETE] error:', error); throw error; } }); ipcMain.handle(IPC_EVENTS.SCRIPT_TOGGLE, async (_event, id: string, enabled: boolean) => { try { return toggleScript(id, enabled); } catch (error: any) { log.error('[SCRIPT_TOGGLE] error:', error); throw error; } }); ipcMain.handle(IPC_EVENTS.SCRIPT_RUN, async (_event, id: string) => { try { const script = getScript(id); return await runScriptById(id, script?.channel); } catch (error: any) { log.error('[SCRIPT_RUN] error:', error); return { success: false, exitCode: null, stdoutTail: '', stderrTail: '', error: error?.message || 'Run failed' }; } }); ipcMain.handle(IPC_EVENTS.SCRIPT_RECORD_START, async (_event, url?: string) => { try { return await startRecording(url); } catch (error: any) { log.error('[SCRIPT_RECORD_START] error:', error); return { success: false, error: error?.message || 'Recording start failed' }; } }); ipcMain.handle(IPC_EVENTS.SCRIPT_RECORD_STOP, async () => { try { return await stopRecording(); } catch (error: any) { log.error('[SCRIPT_RECORD_STOP] error:', error); return { success: false, error: error?.message || 'Recording stop failed' }; } }); // 打开渠道 ipcMain.handle(IPC_EVENTS.OPEN_CHANNEL, async (_event, channels: any) => { try { await launchLocalChrome() const scriptsDir = getScriptsDir() const scriptPath = path.join(scriptsDir, 'open_all_channel.js') openedTabIndexByChannelName.clear() if (Array.isArray(channels)) { for (let i = 0; i < channels.length; i++) { const name = channels[i]?.channelName if (name) openedTabIndexByChannelName.set(String(name), i) } } const result = await executeScriptServiceInstance.executeScript(scriptPath, { channels }) return { success: true, result } } catch (error) { return { success: false, error: (error as any)?.message || 'open channel failed' } } }) // 执行脚本 ipcMain.handle(IPC_EVENTS.EXECUTE_SCRIPT, async (_event, options: any) => { try { // 从options.roomList列表中找到对应的名称 const roomType = options.roomList.find((item: any) => item.id === options.roomType); const pairs: Array<[string, string]> = [ ['fzName', 'fg_trace.js'], ['mtName', 'mt_trace.js'], ['dyHotelName', 'dy_hotel_trace.js'], ['dyHotSpringName', 'dy_hot_spring_trace.js'] ] const scriptEntries = pairs.filter(([prop]) => roomType?.[prop]) const scriptsDir = getScriptsDir() const scriptPaths = scriptEntries.map(([channel, fileName]) => { const p = path.join(scriptsDir, fileName) if (!fs.existsSync(p)) { throw new Error(`Script not found for channel ${channel}: ${p}`) } return { channel, scriptPath: p } }) const results: any[] = [] for (let i = 0; i < scriptPaths.length; i++) { const item = scriptPaths[i] const channelNameMap: Record = { fzName: 'fliggy', mtName: 'meituan', dyHotelName: 'douyin', dyHotSpringName: 'douyin', } const defaultTabIndexMap: Record = { fliggy: 0, meituan: 1, douyin: 2 } const mappedName = channelNameMap[item.channel] const tabIndex = mappedName ? (openedTabIndexByChannelName.get(mappedName) ?? defaultTabIndexMap[mappedName] ?? i) : i log.info(`Launching script for channel ${item.channel}: ${item.scriptPath} (tabIndex: ${tabIndex})`) const result = await executeScriptServiceInstance.executeScript(item.scriptPath, { roomType: roomType[item.channel], startTime: options.startTime, endTime: options.endTime, operation: options.operation, tabIndex, }) results.push({ channel: item.channel, scriptPath: item.scriptPath, ...result, }) } return { success: true, result: results }; } catch (error: any) { return { success: false, error: error.message }; } }); }