feat: 按任务管理比特浏览器临时窗口
This commit is contained in:
+4
-65
@@ -177,7 +177,6 @@ function geminiApp() {
|
||||
inlineEditRechargeStatusEmail: null,
|
||||
inlineEditAccountRefundEmail: null,
|
||||
inlineEditRefundProcessEmail: null,
|
||||
importAutoSetup: true,
|
||||
exportFields: {
|
||||
email: true, password: true, recovery_email: true, secret_key: true,
|
||||
country: false, sheerid_link: false, status: false, message: false, customer_name: false,
|
||||
@@ -1316,17 +1315,8 @@ function geminiApp() {
|
||||
this.accountPage = 1;
|
||||
await this.loadAccounts();
|
||||
|
||||
// 自动初始化:测速 → 创建浏览器 → 设置代理
|
||||
if (this.importAutoSetup && importedEmails.length > 0) {
|
||||
const importedEmailSet = new Set(importedEmails);
|
||||
const setupAccounts = this.accounts.filter(a => importedEmailSet.has(a.email));
|
||||
if (setupAccounts.length > 0) {
|
||||
await new Promise(resolve => {
|
||||
if (typeof requestAnimationFrame === 'function') requestAnimationFrame(() => resolve());
|
||||
else setTimeout(resolve, 0);
|
||||
});
|
||||
await this._runImportSetup(setupAccounts);
|
||||
}
|
||||
if (importedEmails.length > 0) {
|
||||
this.addLog('账号已入库;执行具体任务时会自动创建临时比特浏览器,任务结束后自动删除', 'info');
|
||||
}
|
||||
} else {
|
||||
this.addLog(`导入失败: ${data.msg}`, 'error');
|
||||
@@ -1336,44 +1326,6 @@ function geminiApp() {
|
||||
}
|
||||
},
|
||||
|
||||
async _runImportSetup(accounts) {
|
||||
if (this.isRunning) {
|
||||
this.addLog('⚠️ 有任务正在运行,跳过自动初始化', 'warn');
|
||||
return;
|
||||
}
|
||||
// 大批量任务默认收起日志,避免数百条日志同时参与 DOM 更新。
|
||||
this.logDrawerOpen = accounts.length <= 200;
|
||||
this.clearLogs();
|
||||
this.addLog(`🚀 开始初始化 ${accounts.length} 个账号(测速 / 创建浏览器 / 设置代理)...`, 'info');
|
||||
try {
|
||||
const res = await fetch('/api/operations/run', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
taskType: 'import_setup',
|
||||
accounts,
|
||||
params: { threadCount: parseInt(this.threadCount) },
|
||||
}),
|
||||
});
|
||||
const data = await res.json();
|
||||
if (!data.success) {
|
||||
this.addLog(`❌ 启动失败: ${data.msg}`, 'error');
|
||||
return;
|
||||
}
|
||||
this.currentTaskId = data.taskId;
|
||||
this._rememberTaskBatch('import_setup', accounts, data.taskId);
|
||||
this._activeTaskType = 'import_setup';
|
||||
this._setActiveTaskEmails(this._lastTaskEmails);
|
||||
this._activeTaskStartedAt = this._lastTaskStartedAt;
|
||||
this.isRunning = true;
|
||||
this.isPaused = false;
|
||||
this._rebuildDashboardStats();
|
||||
this.startSSEListener(data.taskId);
|
||||
} catch (e) {
|
||||
this.addLog(`❌ 网络错误: ${e.message}`, 'error');
|
||||
}
|
||||
},
|
||||
|
||||
async deleteSelectedAccounts() {
|
||||
if (this.selectedEmails.size === 0) return;
|
||||
if (this.isDeletingAccounts) {
|
||||
@@ -1564,18 +1516,8 @@ function geminiApp() {
|
||||
this.stagedBatchDetail = null;
|
||||
await Promise.all([this.loadStagingBatches(), this.loadAccounts()]);
|
||||
const restoredAccounts = Array.isArray(data.accounts) ? data.accounts : [];
|
||||
if (restoredAccounts.length === 0) {
|
||||
this.addLog('⚠️ 账号已恢复,但没有取得创建窗口所需的账号数据', 'warn');
|
||||
return;
|
||||
}
|
||||
this.addLog(`正在为恢复的 ${restoredAccounts.length} 个账号自动创建比特浏览器窗口`, 'info');
|
||||
const started = await this.runTask(
|
||||
'create_accounts',
|
||||
{ reuseExistingBrowsers: true },
|
||||
restoredAccounts,
|
||||
);
|
||||
if (!started) {
|
||||
this.addLog('⚠️ 账号已回到主列表,但自动创建窗口任务启动失败,可勾选“刚刚运行”后点击创建浏览器重试', 'warn');
|
||||
if (restoredAccounts.length > 0) {
|
||||
this.addLog('恢复完成;执行具体任务时会自动创建临时比特浏览器', 'info');
|
||||
}
|
||||
} catch (e) {
|
||||
this.addLog(`恢复失败: ${e.message}`, 'error');
|
||||
@@ -2947,7 +2889,6 @@ function geminiApp() {
|
||||
open: '等待打开浏览器...',
|
||||
open_url: '等待打开网页...',
|
||||
delete: '等待删除浏览器...',
|
||||
import_setup: '等待初始化...',
|
||||
custom_pipeline: '等待组合任务...',
|
||||
};
|
||||
return messages[taskType] || '等待处理...';
|
||||
@@ -2972,7 +2913,6 @@ function geminiApp() {
|
||||
ag_get_credential: '获取凭证', aistudio_combo: 'AI Studio 一键组合', aistudio_sync_key: '同步人工AI Key', gemini_cli_get_credential: '获取Cli凭证', ag_revoke_authorization: '取消授权',
|
||||
google_account_ag_credential: '链接提取+获取凭证',
|
||||
open: '打开浏览器', open_manual_aistudio: '打开浏览器(自动保存人工 Key)', open_url: '打开网页', delete: '删除浏览器',
|
||||
import_setup: '账号初始化',
|
||||
};
|
||||
return labels[taskType] || taskType || '任务';
|
||||
},
|
||||
@@ -3429,7 +3369,6 @@ function geminiApp() {
|
||||
},
|
||||
|
||||
// 各操作快捷方法
|
||||
runCreateAccounts() { this.runTask('create_accounts'); },
|
||||
runChangeProxy() { this.runTask('change_proxy'); },
|
||||
runOpenBrowsers() {
|
||||
this.runTask('open_manual_aistudio', { watchTimeoutMs: 30 * 60 * 1000 });
|
||||
|
||||
+6
-4
@@ -204,7 +204,6 @@
|
||||
<div class="btn-group">
|
||||
<span class="btn-group-label">操作</span>
|
||||
<button @click="openBatchStatusModal()" :disabled="selectedCount===0" class="btn btn-orange">更改状态</button>
|
||||
<button @click="runCreateAccounts()" :disabled="isRunning" class="btn btn-primary">创建浏览器</button>
|
||||
<button @click="runDeleteBrowsers()" :disabled="isRunning || selectedCount===0"
|
||||
class="btn btn-red" title="删除所选账号的比特浏览器窗口并清空浏览器编号,账号保留">删除浏览器</button>
|
||||
<button @click="runChangeProxy()" :disabled="isRunning" class="btn btn-primary">换代理</button>
|
||||
@@ -2082,6 +2081,9 @@
|
||||
<input type="checkbox" x-model="importSkipDuplicates" class="h-4 w-4">
|
||||
<span>跳过重复邮箱(已有账号不做任何修改)</span>
|
||||
</label>
|
||||
<div class="text-xs text-blue-600 bg-blue-50 border border-blue-100 rounded p-2">
|
||||
导入只保存账号;执行具体任务时才创建临时比特浏览器窗口,单个账号处理结束后自动删除。
|
||||
</div>
|
||||
|
||||
<!-- 解析预览(第1行) -->
|
||||
<template x-if="importText.trim() && getImportPreview().length > 0">
|
||||
@@ -2162,7 +2164,7 @@
|
||||
<button @click="copyStagedBatch()" class="btn btn-primary">复制全部</button>
|
||||
<button @click="downloadStagedBatch()" class="btn btn-green">导出 TXT</button>
|
||||
<button @click="restoreStagedBatch()" :disabled="isRunning" class="btn btn-gray"
|
||||
title="恢复后自动创建或复用比特浏览器窗口">恢复到主列表并创建窗口</button>
|
||||
title="恢复只回写账号,具体任务执行时再创建临时比特窗口">恢复到主列表</button>
|
||||
<button @click="permanentlyDeleteStagedBatch()" class="btn btn-red">彻底删除文件夹</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2355,13 +2357,13 @@
|
||||
class="w-full" @keydown.enter.prevent="confirmGoogleAccountAgTask()">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-medium text-gray-600 mb-1">并发(1~30)</label>
|
||||
<label class="block text-xs font-medium text-gray-600 mb-1">并发参数(兼容保留)</label>
|
||||
<input type="number" min="1" max="30" step="1" x-model.number="googleAccountAgConcurrency"
|
||||
class="w-full" @keydown.enter.prevent="confirmGoogleAccountAgTask()">
|
||||
</div>
|
||||
</div>
|
||||
<div class="rounded border border-blue-100 bg-blue-50 p-3 text-xs text-blue-700 leading-5 mt-3">
|
||||
供应数据中的辅助邮箱及后续字段会被忽略;数据库已有邮箱会跳过且不覆盖。创建浏览器时固定使用直连(无代理),并发同时用于浏览器创建和反重力凭证获取。
|
||||
供应数据中的辅助邮箱及后续字段会被忽略;数据库已有邮箱会跳过且不覆盖。临时比特浏览器固定使用直连(无代理),并严格按邮箱串行处理:完成一个、删除一个,再开始下一个。
|
||||
</div>
|
||||
<div class="flex gap-2 mt-3">
|
||||
<button @click="showGoogleAccountAgModal=false" class="btn btn-red">取消</button>
|
||||
|
||||
Reference in New Issue
Block a user