diff --git a/src/main.js b/src/main.js index 702770d..3050095 100644 --- a/src/main.js +++ b/src/main.js @@ -619,14 +619,14 @@ async function autoConnectWebSocket() { // TCP 端口就绪探测:等待 Gateway 端口可达后再发起 WS 连接(仅 Tauri 桌面端) if (isTauriRuntime()) { const probeStart = Date.now() - const probeTimeout = 20000 + const probeTimeout = 3000 let portReady = false while (Date.now() - probeStart < probeTimeout) { try { portReady = await api.probeGatewayPort() if (portReady) break } catch {} - await new Promise(r => setTimeout(r, 2000)) + await new Promise(r => setTimeout(r, 300)) } if (!portReady) { console.warn(`[main] Gateway 端口 ${port} 在 ${probeTimeout / 1000}s 内未就绪,仍尝试连接`) diff --git a/src/pages/dashboard.js b/src/pages/dashboard.js index 068a69f..2c483b3 100644 --- a/src/pages/dashboard.js +++ b/src/pages/dashboard.js @@ -148,12 +148,18 @@ async function _loadDashboardDataInner(page, fullRefresh) { if (shouldFetchVersion && (fullRefresh || versionInfoIncomplete(_dashboardVersionCache))) { invalidate('get_version_info') } + const versionP = shouldFetchVersion + ? withTimeout(api.getVersionInfo(), 8000) + .then(v => { + if (v) _dashboardVersionCache = v + return _dashboardVersionCache || {} + }) + .catch(() => _dashboardVersionCache || {}) + : Promise.resolve(_dashboardVersionCache || {}) // 每个请求独立超时:避免单个慢请求拖垮整体渲染 const coreP = Promise.allSettled([ withTimeout(api.getServicesStatus(), 12000), withTimeout(api.readOpenclawConfig(), 5000), - // 版本信息:首次加载或手动刷新时才查询(避免 ARM 设备上频繁查 npm registry) - shouldFetchVersion ? withTimeout(api.getVersionInfo(), 8000) : Promise.resolve(_dashboardVersionCache), withTimeout(api.readPanelConfig(), 5000), ]) const secondaryP = Promise.allSettled([ @@ -165,20 +171,23 @@ async function _loadDashboardDataInner(page, fullRefresh) { const logsP = api.readLogTail('gateway', 20).catch(() => '') // 第一波:服务状态 + 配置 + 版本 → 立即渲染统计卡片 - const [servicesRes, configRes, versionRes, panelConfigRes] = await coreP + const [servicesRes, configRes, panelConfigRes] = await coreP const services = servicesRes.status === 'fulfilled' ? servicesRes.value : [] - const version = (versionRes.status === 'fulfilled' && versionRes.value) - ? (_dashboardVersionCache = versionRes.value) - : (_dashboardVersionCache || {}) + let version = _dashboardVersionCache || {} const config = configRes.status === 'fulfilled' ? configRes.value : null const panelConfig = panelConfigRes.status === 'fulfilled' ? panelConfigRes.value : null const gw = services.find(s => s.label === 'ai.openclaw.gateway') + let agents = [] + versionP.then(v => { + if (!page.isConnected) return + version = v || {} + renderStatCards(page, services, version, agents, config, panelConfig) + }) const shouldLoadStatusSummary = gw?.running === true if (!shouldLoadStatusSummary) { _dashboardStatusSummaryCache = null } if (servicesRes.status === 'rejected') toast(t('dashboard.servicesLoadFail'), 'error') - if (versionRes.status === 'rejected') toast(t('dashboard.versionLoadFail'), 'error') // 自愈:补全关键默认值(先重新读取最新配置再 patch,避免用缓存覆盖其他页面的写入) if (config) { @@ -215,7 +224,7 @@ async function _loadDashboardDataInner(page, fullRefresh) { // 第二波:Agent、MCP、备份 → 更新卡片 + 渲染总览 const [agentsRes, mcpRes, backupsRes, channelsRes] = await secondaryP - const agents = agentsRes.status === 'fulfilled' ? agentsRes.value : [] + agents = agentsRes.status === 'fulfilled' ? agentsRes.value : [] const mcpConfig = mcpRes.status === 'fulfilled' ? mcpRes.value : null const backups = backupsRes.status === 'fulfilled' ? backupsRes.value : [] const channels = channelsRes.status === 'fulfilled' ? (channelsRes.value || []) : []