From 317cda70c2f63d14a00c9e9b2f0234b7ef995f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=99=B4=E5=A4=A9?= Date: Wed, 4 Mar 2026 15:13:27 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20pairing=20required(metadata-upgrade)=20+?= =?UTF-8?q?=20agents=20=E9=AA=A8=E6=9E=B6=E5=B1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pairing.rs: - platform 改用 std::env::consts::OS (windows/macos/linux), 新增 deviceFamily=desktop,与 device.rs connect frame 保持一致 - 已配对设备若 platform 字段不匹配,自动覆盖更新,避免 Gateway 因 metadata-upgrade 拒绝静默自动配对 agents.js + components.css: - loadAgents 调用前先渲染 3 条骨架屏占位,消除空白等待期 - 添加 .skeleton 闪光动画样式 --- src-tauri/src/commands/pairing.rs | 31 ++++++++++++++++++++++++++++--- src/pages/agents.js | 15 +++++++++++++++ src/style/components.css | 12 ++++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src-tauri/src/commands/pairing.rs b/src-tauri/src/commands/pairing.rs index 28da351..7fe3076 100644 --- a/src-tauri/src/commands/pairing.rs +++ b/src-tauri/src/commands/pairing.rs @@ -47,8 +47,32 @@ pub fn auto_pair_device() -> Result { // 无论是否已配对,都确保 gateway.controlUi.allowedOrigins 已写入 patch_gateway_origins(); - // 检查设备是否已配对 - if paired.get(&device_id).is_some() { + let os_platform = std::env::consts::OS; // "windows" | "macos" | "linux" + + // 如果已配对,档查 platform 字段是否正确;不正确则覆盖更新, + // 避免 Gateway 因 metadata-upgrade 拒绝静默自动配对 + if let Some(existing) = paired.get_mut(&device_id) { + let current_platform = existing + .get("platform") + .and_then(|v| v.as_str()) + .unwrap_or(""); + if current_platform != os_platform { + if let Some(obj) = existing.as_object_mut() { + obj.insert( + "platform".to_string(), + serde_json::Value::String(os_platform.to_string()), + ); + obj.insert( + "deviceFamily".to_string(), + serde_json::Value::String("desktop".to_string()), + ); + } + let new_content = serde_json::to_string_pretty(&paired) + .map_err(|e| format!("序列化 paired.json 失败: {e}"))?; + std::fs::write(&paired_path, new_content) + .map_err(|e| format!("更新 paired.json 失败: {e}"))?; + return Ok("设备已配对(已修正平台字段)".into()); + } return Ok("设备已配对".into()); } @@ -61,7 +85,8 @@ pub fn auto_pair_device() -> Result { paired[&device_id] = serde_json::json!({ "deviceId": device_id, "publicKey": public_key, - "platform": "desktop", + "platform": os_platform, + "deviceFamily": "desktop", "clientId": "openclaw-control-ui", "clientMode": "ui", "role": "operator", diff --git a/src/pages/agents.js b/src/pages/agents.js index d946e15..1496277 100644 --- a/src/pages/agents.js +++ b/src/pages/agents.js @@ -34,8 +34,23 @@ export async function render() { return page } +function renderSkeleton(container) { + const item = () => ` +
+
+
+
+
+
+
+
+
` + container.innerHTML = [item(), item(), item()].join('') +} + async function loadAgents(page, state) { const container = page.querySelector('#agents-list') + renderSkeleton(container) try { state.agents = await api.listAgents() renderAgents(page, state) diff --git a/src/style/components.css b/src/style/components.css index e49918e..34334b3 100644 --- a/src/style/components.css +++ b/src/style/components.css @@ -1,3 +1,15 @@ +/* 骨架屏 */ +.skeleton { + background: linear-gradient(90deg, var(--bg-secondary) 25%, var(--bg-tertiary, var(--bg-card-hover)) 50%, var(--bg-secondary) 75%); + background-size: 200% 100%; + animation: skeleton-shine 1.4s ease infinite; +} + +@keyframes skeleton-shine { + 0% { background-position: 200% 0; } + 100% { background-position: -200% 0; } +} + /* 卡片 */ .card { background: var(--bg-card);