From a221c74b7433b6f8fd636cfeba06e3a4cc40b181 Mon Sep 17 00:00:00 2001 From: lingyun14 Date: Wed, 27 May 2026 22:00:42 +0800 Subject: [PATCH] Fix/plugin metadata repo type guard (#8207) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 修复插件 repo 字段类型导致前端报错 * fix: 修复插件 repo 字段类型导致前端报错 * fix: 使用 normalizeInstallUrl 统一 repo 字段处理 * fix:优化 installedRepos 构建方式 --- astrbot/dashboard/routes/plugin.py | 4 ++-- .../src/views/extension/useExtensionPage.js | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/astrbot/dashboard/routes/plugin.py b/astrbot/dashboard/routes/plugin.py index 5f21aabd5..989e940fb 100644 --- a/astrbot/dashboard/routes/plugin.py +++ b/astrbot/dashboard/routes/plugin.py @@ -1281,7 +1281,7 @@ class PluginRoute(Route): for plugin, logo_url, pages in results: _t = { "name": plugin.name, - "repo": "" if plugin.repo is None else plugin.repo, + "repo": "" if plugin.repo is None else str(plugin.repo), "author": plugin.author, "desc": plugin.desc, "version": plugin.version, @@ -1333,7 +1333,7 @@ class PluginRoute(Route): .ok( { "name": plugin.name, - "repo": "" if plugin.repo is None else plugin.repo, + "repo": "" if plugin.repo is None else str(plugin.repo), "author": plugin.author, "desc": plugin.desc, "version": plugin.version, diff --git a/dashboard/src/views/extension/useExtensionPage.js b/dashboard/src/views/extension/useExtensionPage.js index e23716acd..8db1a9c33 100644 --- a/dashboard/src/views/extension/useExtensionPage.js +++ b/dashboard/src/views/extension/useExtensionPage.js @@ -640,14 +640,14 @@ export const useExtensionPage = () => { pluginMarketData.value.forEach((plugin) => { if (plugin.repo) { - onlinePluginsMap.set(plugin.repo.toLowerCase(), plugin); + onlinePluginsMap.set(normalizeInstallUrl(plugin.repo).toLowerCase(), plugin); } onlinePluginsNameMap.set(plugin.name, plugin); }); const data = Array.isArray(extension_data?.data) ? extension_data.data : []; data.forEach((extension) => { - const repoKey = extension.repo?.toLowerCase(); + const repoKey = extension.repo ? normalizeInstallUrl(extension.repo).toLowerCase() : undefined; const onlinePlugin = repoKey ? onlinePluginsMap.get(repoKey) : null; const onlinePluginByName = onlinePluginsNameMap.get(extension.name); const matchedPlugin = onlinePlugin || onlinePluginByName; @@ -1233,21 +1233,21 @@ export const useExtensionPage = () => { const checkAlreadyInstalled = () => { const data = Array.isArray(extension_data?.data) ? extension_data.data : []; - const installedRepos = new Set(data.map((ext) => ext.repo?.toLowerCase())); - const installedNames = new Set( - data.map((ext) => normalizeStr(ext.name).replace(/_/g, "-")), - ); //统一格式,以防下面的匹配不生效 const installedByRepo = new Map( data .filter((ext) => ext.repo) - .map((ext) => [ext.repo.toLowerCase(), ext]), + .map((ext) => [normalizeInstallUrl(ext.repo).toLowerCase(), ext]), ); + const installedRepos = new Set(installedByRepo.keys()); + const installedNames = new Set( + data.map((ext) => normalizeStr(ext.name).replace(/_/g, "-")), + ); //统一格式,以防下面的匹配不生效 const installedByName = new Map(data.map((ext) => [ext.name, ext])); for (let i = 0; i < pluginMarketData.value.length; i++) { const plugin = pluginMarketData.value[i]; const matchedInstalled = - (plugin.repo && installedByRepo.get(plugin.repo.toLowerCase())) || + (plugin.repo && installedByRepo.get(normalizeInstallUrl(plugin.repo).toLowerCase())) || installedByName.get(plugin.name); // 兜底:市场源未提供字段时,回填本地已安装插件中的元数据,便于在市场页直接展示 @@ -1265,7 +1265,7 @@ export const useExtensionPage = () => { } plugin.installed = - installedRepos.has(plugin.repo?.toLowerCase()) || + (plugin.repo && installedRepos.has(normalizeInstallUrl(plugin.repo).toLowerCase())) || installedNames.has(normalizeStr(plugin.name).replace(/_/g, "-")); //统一格式,防止匹配失败 }