feat: 自动化执行逻辑开发

This commit is contained in:
DEV_DSW
2026-03-11 17:01:48 +08:00
parent d07c65c581
commit b32fb2e9e8
10 changed files with 525 additions and 95 deletions

View File

@@ -14,25 +14,26 @@ export function runTaskOperationService() {
try { try {
await launchLocalChrome(options) await launchLocalChrome(options)
const channels = ['fz', 'mt', 'dy', 'xc'] // 从options.roomList列表中找到对应的名称
const roomType = options.roomList.find((item: any) => item.id === options.roomType);
const scriptMap: Record<string, string> = { // 从roomType找fzName、mtName、dyHotelName、dyHotSpringName、xcName属性判断是否有值
fz: 'fg_trace.mjs', // 如果有值,就找出对应的脚本
mt: 'mt_trace.mjs', // 如果没有值,就跳过
dy: 'dy_trace.mjs', const pairs: Array<[string, string]> = [
xc: 'xc_trace.mjs', ['fzName', 'fg_trace.mjs'],
} ['mtName', 'mt_trace.mjs'],
['dyHotelName', 'dy_hotel_trace.mjs'],
['dyHotSpringName', 'dy_hot_spring_trace.mjs'],
['xcName', 'xc_trace.mjs'],
]
const scriptEntries = pairs.filter(([prop]) => roomType?.[prop])
const scriptsDir = app.isPackaged const scriptsDir = app.isPackaged
? path.join(process.resourcesPath, 'scripts') ? path.join(process.resourcesPath, 'scripts')
: path.join(process.cwd(), 'src/main/scripts') : path.join(process.cwd(), 'src/main/scripts')
const scriptPaths = channels.map((channel: string) => { const scriptPaths = scriptEntries.map(([channel, fileName]) => {
const fileName = scriptMap[channel]
if (!fileName) {
throw new Error(`Unknown channel: ${channel}`)
}
const p = path.join(scriptsDir, fileName) const p = path.join(scriptsDir, fileName)
if (!fs.existsSync(p)) { if (!fs.existsSync(p)) {
throw new Error(`Script not found for channel ${channel}: ${p}`) throw new Error(`Script not found for channel ${channel}: ${p}`)
@@ -43,7 +44,12 @@ export function runTaskOperationService() {
const results: any[] = [] const results: any[] = []
for (const item of scriptPaths) { for (const item of scriptPaths) {
log.info(`Launching script for channel ${item.channel}: ${item.scriptPath}`) log.info(`Launching script for channel ${item.channel}: ${item.scriptPath}`)
const result = await executeScriptServiceInstance.executeScript(item.scriptPath, options) const result = await executeScriptServiceInstance.executeScript(item.scriptPath, {
roomType: roomType[item.channel],
startTime: options.startTime,
endTime: options.endTime,
operation: options.operation,
})
results.push({ results.push({
channel: item.channel, channel: item.channel,
scriptPath: item.scriptPath, scriptPath: item.scriptPath,

View File

@@ -1,2 +1,33 @@
import log from 'electron-log'; const log = require('electron-log');
const checkLoginStatus = async (page) => {
try {
const currentUrl = await page.url();
log.info('current url==========>:', currentUrl);
const loginPagePatterns = ['/login', '/signin', '/auth'];
const isLoginPage = loginPagePatterns.some((pattern) => currentUrl.includes(pattern));
if (!isLoginPage) {
return true;
}
const pageContent = await page.content();
const loginKeywords = ['退出', '房价房量管理'];
const hasLoginKeyword = loginKeywords.some((keyword) => pageContent.includes(keyword));
if (hasLoginKeyword) {
return true;
}
return false;
} catch (error) {
return false;
}
};
module.exports = {
checkLoginStatus,
};

View File

@@ -0,0 +1,4 @@
import log from 'electron-log';
log.info('dy_trace.mjs placeholder: not implemented');
process.exit(0);

3
src/main/scripts/fg.md Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,38 +1,97 @@
import { chromium } from 'playwright'; import { chromium } from 'playwright';
import log from 'electron-log'; import log from 'electron-log';
import checkLoginStatusPkg from './common/checkLoginStatus.js';
const checkLoginStatus = async (page) => { const { checkLoginStatus } = checkLoginStatusPkg;
try {
const currentUrl = await page.url();
log.info('current url==========>:', currentUrl); const parseDateInput = (dateStr) => {
if (!dateStr) return null;
const loginPagePatterns = ['/login', '/signin', '/auth']; if (typeof dateStr === 'number' && Number.isFinite(dateStr)) return new Date(dateStr);
const isLoginPage = loginPagePatterns.some(pattern => currentUrl.includes(pattern)); if (dateStr instanceof Date && !Number.isNaN(dateStr.getTime())) return dateStr;
const raw = String(dateStr).trim();
if(!isLoginPage) { const ymdMatch = raw.match(/(\d{4}-\d{2}-\d{2})/);
return true; if (ymdMatch) return new Date(`${ymdMatch[1]}T00:00:00`);
const mmddMatch = raw.match(/(\d{2}-\d{2})/);
if (mmddMatch) {
const year = new Date().getFullYear();
return new Date(`${year}-${mmddMatch[1]}T00:00:00`);
} }
return null;
};
// 检查页面内容中的关键字 const formatMMDD = (d) => {
const pageContent = await page.content(); const mm = String(d.getMonth() + 1).padStart(2, '0');
const loginKeywords = ['退出', '房价房量管理']; const dd = String(d.getDate()).padStart(2, '0');
const hasLoginKeyword = loginKeywords.some(keyword => return `${mm}-${dd}`;
pageContent.includes(keyword) };
const buildDateList = (startDate, endDate) => {
const start = parseDateInput(startDate);
const end = parseDateInput(endDate || startDate);
if (!start || !end) return [];
const from = start <= end ? start : end;
const to = start <= end ? end : start;
const dates = [];
const cur = new Date(from.getTime());
while (cur <= to) {
dates.push(formatMMDD(cur));
cur.setDate(cur.getDate() + 1);
}
return dates;
};
const findHeaderDateIndex = async (container, mmdd) => {
for (let attempt = 0; attempt < 10; attempt++) {
const headerCells = container.locator(
"xpath=.//div[contains(@class,'headerRow')]/div[contains(@class,'headerContent')]",
); );
const count = await headerCells.count();
if (hasLoginKeyword) { for (let i = 0; i < count; i++) {
return true; const text = (await headerCells.nth(i).innerText()).replace(/\s+/g, ' ').trim();
if (text.includes(mmdd)) return i;
} }
return false; await container.evaluate((el) => {
} catch (error) { el.scrollLeft += 600;
return false; });
await container.page().waitForTimeout(120);
} }
} return -1;
};
const toggleRoomByDateIndex = async (page, container, { roomType, dateIndex, operation }) => {
const roomAnchor = container.getByText(roomType, { exact: true }).first();
await roomAnchor.scrollIntoViewIfNeeded();
const row = roomAnchor.locator(
"xpath=ancestor::*[.//div[contains(@class,'boardRow')]][1]",
);
const boardRow = row.locator("xpath=.//div[contains(@class,'boardRow')]").first();
const boardColPosition = dateIndex + 2;
const dayColumn = boardRow.locator(`xpath=./div[${boardColPosition}]`);
const targetStateClass = operation === 'open' ? 'error' : 'success';
const expectedCurrentLabel = operation === 'open' ? '满' : '有';
const barByLabel = dayColumn
.locator(
`xpath=.//*[ (contains(@class,'success') or contains(@class,'error')) and .//*[contains(normalize-space(),'${expectedCurrentLabel}')] ]//*[contains(@class,'bar')]`,
)
.first();
const barByClass = dayColumn
.locator(`xpath=.//*[contains(@class,'${targetStateClass}')]//*[contains(@class,'bar')]`)
.first();
const bar = (await barByLabel.count()) > 0 ? barByLabel : barByClass;
await bar.waitFor({ state: 'visible' });
await bar.scrollIntoViewIfNeeded();
await bar.click();
};
(async () => { (async () => {
const browser = await chromium.connectOverCDP(`http://localhost:9222`); const browser = await chromium.connectOverCDP(`http://127.0.0.1:9222`);
const context = browser.contexts()[0]; const context = browser.contexts()[0];
await context.addInitScript(() => { await context.addInitScript(() => {
@@ -102,55 +161,26 @@ const checkLoginStatus = async (page) => {
await page.waitForTimeout(4000 + Math.random() * 1000); await page.waitForTimeout(4000 + Math.random() * 1000);
await page.getByText('房价房量日历').click(); await page.getByText('房价房量日历').click();
// 获取网页接口(监听所有请求) const roomType = process.env.ROOM_TYPE;
await page.on('request', response => { const startDate = process.env.START_DATE;
const url = response.url() const endDate = process.env.END_DATE;
const operation = process.env.OPERATION === 'close' ? 'close' : 'open';
// log.info('request response:', url) if (!roomType || !startDate) {
log.info('ROOM_TYPE/START_DATE not provided, skip room toggle.');
if (url.includes('/heinventory/queryRoomTypeAndRatePlanLite')) { return;
// const data = await response.json()
log.info('interface response:', JSON.parse(response.postData()))
} }
// log.info('URL:', request.url())
// log.info('Method:', request.method())
// log.info('PostData:', request.postData())
})
// 获取接口返回数据 const container = page.locator('#price-reserve-table-container');
await page.on('response', async (response) => { await container.waitFor({ state: 'visible' });
const url = response.url()
if (url.includes('/heinventory/queryRoomTypeAndRatePlanLite')) { const dateList = buildDateList(startDate, endDate);
const data = await response.json() for (const mmdd of dateList) {
const dateIndex = await findHeaderDateIndex(container, mmdd);
log.info('interface response:', data) if (dateIndex < 0) {
throw new Error(`Date not found in header: ${mmdd}`);
}
await toggleRoomByDateIndex(page, container, { roomType, dateIndex, operation });
await page.waitForTimeout(600 + Math.random() * 600);
} }
})
// await page.pause();
/*
* 1、我要知道日期
* 2、我要知道房型
* 3、我要知道是关闭或开启操作
*
* 存在以下影响自动化情况:
* 1、房型重新拖拽排序会影响后续操作
* 2、筛选日期下存在没有安排的房型
*/
// await page.getByRole('textbox', { name: '-02-27' }).click();
// await page.getByText('27').nth(3).click();
// 开启房型div:nth-child(动态变化的) > .boardRow___p2ZiO > div:nth-child(2) > div > .ant-spin-nested-loading > .ant-spin-container > div > div > .success___VQjXR > .bar___i4k4r
// await page.locator('div:nth-child(7) > div > div:nth-child(2) > div > .ant-spin-nested-loading > .ant-spin-container > div > div > .success___VQjXR > .bar___i4k4r').first().click();
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div:nth-child(2) > .ant-spin-nested-loading > .ant-spin-container > div > div > .success___VQjXR > .bar___i4k4r').click();
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div:nth-child(3) > .ant-spin-nested-loading > .ant-spin-container > div > div > .success___VQjXR > .bar___i4k4r').click();
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div:nth-child(4) > .ant-spin-nested-loading > .ant-spin-container > div > div > .success___VQjXR > .bar___i4k4r').click();
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div:nth-child(5) > .ant-spin-nested-loading > .ant-spin-container > div > div > .success___VQjXR > .bar___i4k4r').click();
// 关闭房型div:nth-child(动态变化的) > .boardRow___p2ZiO > div:nth-child(2) > div > .ant-spin-nested-loading > .ant-spin-container > div > div > .error___IM8Yw > .bar___i4k4r
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div > .ant-spin-nested-loading > .ant-spin-container > div > div > .error___IM8Yw > .bar___i4k4r').first().click();
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div:nth-child(2) > .ant-spin-nested-loading > .ant-spin-container > div > div > .error___IM8Yw > .bar___i4k4r').click();
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div:nth-child(3) > .ant-spin-nested-loading > .ant-spin-container > div > div > .error___IM8Yw > .bar___i4k4r').click();
// await page.locator('div:nth-child(7) > .boardRow___p2ZiO > div:nth-child(2) > div:nth-child(4) > .ant-spin-nested-loading > .ant-spin-container > div > div > .error___IM8Yw > .bar___i4k4r').click();
})(); })();

View File

@@ -0,0 +1,348 @@
```json
{
"code": 0,
"msg": null,
"data": [
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:19",
"id": "0d6898fb7105419f895e2153e48df115",
"pmsName": "亲子太空舱",
"xcName": "亲子太空舱",
"fzName": "亲子太空舱",
"mtName": "亲子太空舱",
"dyHotelName": "亲子太空舱-含私汤",
"dyHotSrpingName": "亲子太空舱-含私汤",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:20",
"id": "1c3616b31de946ee868f74b550e9a88f",
"pmsName": "豪华特色",
"xcName": "豪华特色房",
"fzName": "豪华特色房(麻将)",
"mtName": "豪华特色房",
"dyHotelName": "豪华特色房",
"dyHotSrpingName": "豪华特色房(含双人温泉,入住期间不限次)",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:21",
"id": "2cfdf51d2cff4384ba53a0fa5b8a6c77",
"pmsName": "行政套房A",
"xcName": "行政套房A",
"fzName": "行政套房A",
"mtName": "行政套房A",
"dyHotelName": "行政套房A",
"dyHotSrpingName": "行政套房A含双人温泉入住期间不限次",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:22",
"id": "30ca794cc12743a19e6a2a8483838234",
"pmsName": "亲子房",
"xcName": "亲子房",
"fzName": "亲子房",
"mtName": "亲子房",
"dyHotelName": "亲子房",
"dyHotSrpingName": "亲子房(含三人温泉,入住期间不限次)",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:24",
"id": "4b307fd07e34483083f47d5ed32d9a26",
"pmsName": "太空舱",
"xcName": "太空舱(含私汤)",
"fzName": "太空舱",
"mtName": "太空舱(私汤)",
"dyHotelName": "太空舱",
"dyHotSrpingName": "太空舱(含双人温泉、入住期间不限次)",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:23",
"id": "4b77c93f42d34f7fa588a223dd1e1762",
"pmsName": "豪华行政套房",
"xcName": "",
"fzName": "",
"mtName": "",
"dyHotelName": "",
"dyHotSrpingName": "",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:26",
"id": "53b3c2a68dd844cb8f8d4f339ce521ef",
"pmsName": "至大",
"xcName": "至尊大床房(含私汤)",
"fzName": "和雅小筑-至尊大床房(户外泡池)",
"mtName": "至尊大床房",
"dyHotelName": "",
"dyHotSrpingName": "至尊大床房-私汤",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:26",
"id": "5cd720a6ed124c11a2ef61f1eef5a98d",
"pmsName": "行政套房B",
"xcName": "行政套房B含私汤",
"fzName": "行政套房B",
"mtName": "",
"dyHotelName": "",
"dyHotSrpingName": "",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:27",
"id": "76d9ff061da54e1f9ff1afd663dd22a5",
"pmsName": "汤墅会馆",
"xcName": "汤墅会馆(含私汤)",
"fzName": "汤墅会馆",
"mtName": "汤墅会馆(私汤)",
"dyHotelName": "",
"dyHotSrpingName": "",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:28",
"id": "7a21366f0ed3421592a3ee6835e03433",
"pmsName": "高级家庭套房",
"xcName": "高级家庭套房",
"fzName": "",
"mtName": "",
"dyHotelName": "高级家庭套房",
"dyHotSrpingName": "高级家庭套房",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:30",
"id": "822bede1a81641e6853a6f6313185b85",
"pmsName": "高级标准间",
"xcName": "高级标准间",
"fzName": "高级标准间",
"mtName": "高级标准间",
"dyHotelName": "高级标准间",
"dyHotSrpingName": "高级标准间(含双人温泉,入住期间不限次)",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:29",
"id": "88bfd80b66454f14bb0fe2ea61cee7b3",
"pmsName": "至尊汤屋",
"xcName": "至尊养生汤屋(含私汤)",
"fzName": "至尊养生汤屋(含私汤)",
"mtName": "至尊养生汤屋(私汤)",
"dyHotelName": "至尊养生汤屋",
"dyHotSrpingName": "至尊养生汤屋-含双人温泉、入住期间不限次",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:32",
"id": "9011e8d8d33945409344751132d21912",
"pmsName": "尊享豪大",
"xcName": "尊享豪华大床房(含私汤)",
"fzName": "豪华尊享大床房(双人温泉)",
"mtName": "尊享豪华大床房(私汤)",
"dyHotelName": "",
"dyHotSrpingName": "尊享豪华大床房-私汤",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:34",
"id": "94281bdcf8664a5bbcb3add6f62736fe",
"pmsName": "高级双人套房",
"xcName": "",
"fzName": "",
"mtName": "",
"dyHotelName": "高级双人套房",
"dyHotSrpingName": "高级双人套房-含双人温泉、入住期间不限次",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:33",
"id": "a211b49ff3f94f5a8d8c30bf80f7289e",
"pmsName": "豪华至尊养生汤屋",
"xcName": "豪华至尊养生汤屋(含私汤)",
"fzName": "豪华至尊养生汤屋(私汤)",
"mtName": "豪华至尊养生汤屋(私汤)",
"dyHotelName": "豪华至尊养生汤屋",
"dyHotSrpingName": "豪华至尊养生汤屋",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:35",
"id": "b9042d303bbe4ee09a4ffb567692714a",
"pmsName": "豪华家庭套房",
"xcName": "",
"fzName": "",
"mtName": "",
"dyHotelName": "",
"dyHotSrpingName": "",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:36",
"id": "bafb56cd74f44b44b836d727f5b604a7",
"pmsName": "豪华套房",
"xcName": "豪华套房(含私汤)",
"fzName": "天伦小筑-豪华套房(含私汤)",
"mtName": "豪华套房(私汤)",
"dyHotelName": "",
"dyHotSrpingName": "",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:37",
"id": "c03a339b407348438b056aca908b5580",
"pmsName": "雅致大床房",
"xcName": "雅致大床房",
"fzName": "",
"mtName": "",
"dyHotelName": "雅致大床",
"dyHotSrpingName": "雅致大床-房含双人温泉、入住期间不限次",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:38",
"id": "c68fa888684641ff9be8e25b83e4e347",
"pmsName": "榻榻米双床房",
"xcName": "榻榻米双床房",
"fzName": "榻榻米双床房",
"mtName": "榻榻米双床房",
"dyHotelName": "榻榻米双床房",
"dyHotSrpingName": "榻榻米双床房-含双人温泉,入住期间不限次",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:39",
"id": "e6f8f7fb6f014a3a84f0a037df8544e6",
"pmsName": "雅致标准间",
"xcName": "雅致双床房",
"fzName": "雅致双床房",
"mtName": "",
"dyHotelName": "雅致标准间",
"dyHotSrpingName": "雅致标准间-含双人温泉、入住期间不限次",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
}
]
}
```

View File

@@ -18,11 +18,19 @@ export class executeScriptService extends EventEmitter {
return await new Promise((resolve) => { return await new Promise((resolve) => {
try { try {
const roomType = options?.roomType ?? '';
const startTime = options?.startTime ?? '';
const endTime = options?.endTime ?? '';
const operation = options?.operation ?? '';
const child = spawn('node', [scriptPath], { const child = spawn('node', [scriptPath], {
env: { env: {
...process.env, ...process.env,
...options, ROOM_TYPE: String(roomType),
} START_DATE: String(startTime),
END_DATE: String(endTime),
OPERATION: String(operation)
},
}); });
let stdoutTail = ''; let stdoutTail = '';

View File

@@ -1,10 +1,10 @@
import http from 'http'; import http from 'http';
// Chrome是否已运行 // Chrome是否已运行
export async function isChromeRunning (): Promise<boolean> { export async function isChromeRunning(): Promise<boolean> {
try { try {
return new Promise((resolve) => { return new Promise((resolve) => {
const req = http.get('http://localhost:9222/json/version', (res: any) => { const req = http.get('http://127.0.0.1:9222/json/version', (res: any) => {
resolve(res.statusCode === 200); resolve(res.statusCode === 200);
}); });

View File

@@ -6,7 +6,7 @@ import { spawn } from 'child_process';
import log from 'electron-log'; import log from 'electron-log';
// 启动本地浏览器 // 启动本地浏览器
export async function launchLocalChrome (options: any) { export async function launchLocalChrome(options: any) {
const chromePath = getChromePath(); const chromePath = getChromePath();
// 多账号隔离 // 多账号隔离