192 lines
5.9 KiB
TypeScript
192 lines
5.9 KiB
TypeScript
|
|
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<string, number>()
|
|
|
|
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<string, string> = {
|
|
fzName: 'fliggy',
|
|
mtName: 'meituan',
|
|
dyHotelName: 'douyin',
|
|
dyHotSpringName: 'douyin',
|
|
}
|
|
const defaultTabIndexMap: Record<string, number> = {
|
|
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 };
|
|
}
|
|
});
|
|
}
|