From 73b7388312166227d23ebfab5c0f51f3ff7d266a Mon Sep 17 00:00:00 2001 From: foxhui Date: Fri, 27 Mar 2026 15:17:20 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=B0=9D=E8=AF=95=E7=BC=93=E8=A7=A3=20C?= =?UTF-8?q?LICK=5FTIMEOUT=20=E7=9A=84=E9=97=AE=E9=A2=98=20(ref=20#30,=20re?= =?UTF-8?q?f=20#31,=20ref=20#33)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/adapter/gemini.js | 1 + src/backend/engine/utils.js | 15 +++++++++++++-- src/utils/constants.js | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/backend/adapter/gemini.js b/src/backend/adapter/gemini.js index 1064799..5a0584c 100644 --- a/src/backend/adapter/gemini.js +++ b/src/backend/adapter/gemini.js @@ -43,6 +43,7 @@ async function generate(context, prompt, imgPaths, modelId, meta = {}) { // 1. 等待输入框加载 await waitForInput(page, inputLocator, { click: false }); + await sleep(300, 500); // 2. 上传图片 if (imgPaths && imgPaths.length > 0) { diff --git a/src/backend/engine/utils.js b/src/backend/engine/utils.js index 19e4114..7b2364c 100644 --- a/src/backend/engine/utils.js +++ b/src/backend/engine/utils.js @@ -201,7 +201,7 @@ export function getHumanClickPoint(box, type = 'random') { * @param {number} stableFrames - 需要连续稳定的帧数,建议提高到 10 (约160ms) * @param {number} timeout - 总超时时间 (ms) */ -async function waitForElementStable(element, stableFrames = 10, timeout = 2000) { +async function waitForElementStable(element, stableFrames = 20, timeout = 2000) { if (!element) return; try { @@ -302,6 +302,8 @@ export async function safeClick(page, target, options = {}) { } }; + let aborted = false; + const doClick = async () => { // 1. 首次获取元素(用于滚动和等待稳定) const logKey = `${selector} ${target} ${options.bias || 'random'}`; @@ -311,12 +313,15 @@ export async function safeClick(page, target, options = {}) { // 2. 确保元素在可视区域内 logger.debug('浏览器', `[safeClick] 滚动到可视区域...`); + if (aborted) return; await el.scrollIntoViewIfNeeded().catch(() => { }); + if (aborted) return; // 3. 如果开启了布局稳定等待,等待元素位置稳定 if (waitStable) { logger.debug('浏览器', `[safeClick] 等待元素稳定...`); await waitForElementStable(el); + if (aborted) return; logger.debug('浏览器', `[safeClick] 元素已稳定`); // 4. 重新获取元素引用(防止等待期间 DOM 变化导致 detached 错误) @@ -327,14 +332,17 @@ export async function safeClick(page, target, options = {}) { } } + if (aborted) return; // 5. 使用自维护 ghost-cursor 拟人鼠标轨迹 (仅当 humanizeCursor=true) if (useGhostCursor) { const box = await el.boundingBox(); + if (aborted) return; logger.debug('浏览器', `[safeClick] boundingBox: ${JSON.stringify(box)}`); if (box) { const { x, y } = getHumanClickPoint(box, options.bias || 'random'); logger.debug('浏览器', `[safeClick] 移动鼠标到 (${x.toFixed(0)}, ${y.toFixed(0)})...`); await page.cursor.moveTo({ x, y }, { moveSpeed: cursorSpeed }); + if (aborted) return; logger.debug('浏览器', `[safeClick] 执行点击...`); await page.mouse.click(x, y, { clickCount }); return; @@ -356,7 +364,10 @@ export async function safeClick(page, target, options = {}) { let timeoutId; try { const timeoutPromise = new Promise((_, reject) => { - timeoutId = setTimeout(() => reject(new Error('CLICK_TIMEOUT')), timeout); + timeoutId = setTimeout(() => { + aborted = true; + reject(new Error('CLICK_TIMEOUT')); + }, timeout); }); await Promise.race([ diff --git a/src/utils/constants.js b/src/utils/constants.js index 30bf598..9b6225e 100644 --- a/src/utils/constants.js +++ b/src/utils/constants.js @@ -13,7 +13,7 @@ */ export const TIMEOUTS = { /** 元素点击超时 (safeClick) */ - ELEMENT_CLICK: 15000, + ELEMENT_CLICK: 25000, /** 输入框等待超时 (waitForInput) */ INPUT_WAIT: 20000,