From 6794b723792479e29031154cac16c7138bc5f31a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=99=B4=E5=A4=A9?= Date: Thu, 26 Mar 2026 03:31:06 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=BE=AE=E4=BF=A1=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=E6=80=A7=E6=A3=80=E6=B5=8B=20+=20=E4=B8=8D?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=E6=97=B6=E6=98=BE=E7=A4=BA=E7=BA=A2=E8=89=B2?= =?UTF-8?q?=E8=AD=A6=E5=91=8A=E5=BC=95=E5=AF=BC=E9=87=8D=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - messaging.rs: check_weixin_plugin_status 新增 compatible/compatError 字段,检测 SDK 模块是否存在 - channels.js: 不兼容时显示红色警告 + 安装按钮变为「重新安装兼容版本」 --- src-tauri/src/commands/messaging.rs | 54 +++++++++++++++++++++++++++++ src/pages/channels.js | 10 +++++- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src-tauri/src/commands/messaging.rs b/src-tauri/src/commands/messaging.rs index 11dd6c7..854917c 100644 --- a/src-tauri/src/commands/messaging.rs +++ b/src-tauri/src/commands/messaging.rs @@ -1090,12 +1090,66 @@ pub async fn check_weixin_plugin_status() -> Result { _ => false, }; + // 兼容性检查:检测插件是否能在当前 OpenClaw 版本下正常加载 + let mut compatible = true; + let mut compat_error = String::new(); + if installed { + // 检查插件引用的 SDK 模块是否存在(channel-config-schema 是 2026.3.14+ 新增的) + if let Some(cli_path) = crate::utils::resolve_openclaw_cli_path() { + let cli_dir = std::path::Path::new(&cli_path) + .parent() + .and_then(|p| p.parent()) + .unwrap_or(std::path::Path::new("")); + let sdk_path = cli_dir + .join("dist") + .join("plugin-sdk") + .join("root-alias.cjs") + .join("channel-config-schema.js"); + if !sdk_path.exists() { + // 也检查 npm 全局路径 + let npm_sdk_exists = { + #[cfg(target_os = "windows")] + { + std::env::var("APPDATA") + .ok() + .map(|appdata| { + let base = std::path::PathBuf::from(appdata) + .join("npm") + .join("node_modules"); + ["openclaw", "@qingchencloud/openclaw-zh"] + .iter() + .any(|pkg| { + base.join(pkg) + .join("dist") + .join("plugin-sdk") + .join("root-alias.cjs") + .join("channel-config-schema.js") + .exists() + }) + }) + .unwrap_or(false) + } + #[cfg(not(target_os = "windows"))] + { + false + } + }; + if !npm_sdk_exists { + compatible = false; + compat_error = "插件版本与当前 OpenClaw 不兼容(缺少 channel-config-schema 模块),请点击「一键安装插件」重新安装兼容版本".to_string(); + } + } + } + } + Ok(json!({ "installed": installed, "installedVersion": installed_version, "latestVersion": latest_version, "updateAvailable": update_available, "extensionDir": ext_dir.to_string_lossy(), + "compatible": compatible, + "compatError": compat_error, })) } diff --git a/src/pages/channels.js b/src/pages/channels.js index 08d9f4c..d9c8fa1 100644 --- a/src/pages/channels.js +++ b/src/pages/channels.js @@ -1325,7 +1325,15 @@ async function openConfigDialog(pid, page, state, accountId) { if (!s) { statusEl.textContent = t('channels.pluginStatusFailed'); return } const parts = [] const installBtn = modal.querySelector('[data-channel-action="install"]') - if (s.installed) { + if (s.installed && s.compatible === false) { + parts.push(`⚠ ${t('channels.pluginIncompatible') || '插件版本不兼容'}`) + parts.push(`${t('channels.version')} ${s.installedVersion || '?'}`) + parts.push(`
${s.compatError || '请点击「一键安装插件」重新安装兼容版本'}`) + if (installBtn) { + installBtn.textContent = t('channels.reinstallCompatible') || '重新安装兼容版本' + installBtn.style.background = 'var(--error)' + } + } else if (s.installed) { parts.push(`● ${t('channels.pluginInstalled')}`) parts.push(`${t('channels.version')} ${s.installedVersion || t('channels.unknown')}`) if (s.updateAvailable && s.latestVersion) {