Skip to content

Commit a3c25ec

Browse files
authored
fix: preserve repo source on plugin reinstall
* fix: preserve repo source on plugin reinstall * fix(dashboard): align extension market matching with repo identity Use normalized repo keys as the primary identity when matching installed extensions with marketplace plugins in useExtensionPage. Only fall back to name matching for installed extensions that do not have a repo, and normalize name lookups consistently on both sides. Also clear stale online_version when no marketplace plugin is matched.
1 parent bec0de2 commit a3c25ec

1 file changed

Lines changed: 34 additions & 33 deletions

File tree

dashboard/src/views/extension/useExtensionPage.js

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
import axios from "axios";
2-
import { useCommonStore } from "@/stores/common";
1+
import { pluginSidebarState } from "@/composables/usePluginSidebarItems";
32
import { useI18n, useModuleI18n } from "@/i18n/composables";
4-
import { getPlatformDisplayName } from "@/utils/platformUtils";
3+
import { useCommonStore } from "@/stores/common";
54
import { resolveErrorMessage } from "@/utils/errorUtils";
5+
import { getValidHashTab, replaceTabRoute } from "@/utils/hashRouteTabs.mjs";
6+
import { getPlatformDisplayName } from "@/utils/platformUtils";
67
import {
7-
buildSearchQuery,
8-
matchesPluginSearch,
9-
normalizeStr,
10-
toInitials,
11-
toPinyinText,
8+
buildSearchQuery,
9+
matchesPluginSearch,
10+
normalizeStr,
11+
toInitials,
12+
toPinyinText,
1213
} from "@/utils/pluginSearch";
13-
import { getValidHashTab, replaceTabRoute } from "@/utils/hashRouteTabs.mjs";
14-
import { ref, computed, onMounted, onUnmounted, reactive, watch } from "vue";
14+
import axios from "axios";
15+
import { computed, onMounted, onUnmounted, reactive, ref, watch } from "vue";
1516
import { useRoute, useRouter } from "vue-router";
16-
import { pluginSidebarState } from "@/composables/usePluginSidebarItems";
1717

1818
const buildFailedPluginItems = (raw) => {
1919
return Object.entries(raw || {}).map(([dirName, info]) => {
@@ -624,12 +624,16 @@ export const useExtensionPage = () => {
624624
const findMarketPluginForExtension = (extension) => {
625625
if (!extension) return null;
626626
const repo = normalizeInstallUrl(extension.repo).toLowerCase();
627+
628+
if (repo) {
629+
return (
630+
pluginMarketData.value.find(
631+
(plugin) => normalizeInstallUrl(plugin?.repo).toLowerCase() === repo,
632+
) || null
633+
);
634+
}
635+
627636
return (
628-
pluginMarketData.value.find(
629-
(plugin) =>
630-
repo &&
631-
normalizeInstallUrl(plugin?.repo).toLowerCase() === repo,
632-
) ||
633637
pluginMarketData.value.find((plugin) => plugin.name === extension.name) ||
634638
null
635639
);
@@ -655,19 +659,20 @@ export const useExtensionPage = () => {
655659
data.forEach((extension) => {
656660
const repoKey = extension.repo ? normalizeInstallUrl(extension.repo).toLowerCase() : undefined;
657661
const onlinePlugin = repoKey ? onlinePluginsMap.get(repoKey) : null;
658-
662+
659663
// 使用 marketplace_name 进行市场匹配(后端已统一为减号格式)
660664
const normalizedExtensionName = normalizeStr(extension.marketplace_name);
661665
const onlinePluginByName = onlinePluginsNameMap.get(normalizedExtensionName);
662-
663-
const matchedPlugin = onlinePlugin || onlinePluginByName;
666+
667+
const matchedPlugin = repoKey ? onlinePlugin : onlinePluginByName;
664668

665669
if (matchedPlugin) {
666670
extension.online_version = matchedPlugin.version;
667671
extension.has_update =
668672
extension.version !== matchedPlugin.version &&
669673
matchedPlugin.version !== tm("status.unknown");
670674
} else {
675+
extension.online_version = "";
671676
extension.has_update = false;
672677
}
673678
});
@@ -1243,27 +1248,25 @@ export const useExtensionPage = () => {
12431248

12441249
const checkAlreadyInstalled = () => {
12451250
const data = Array.isArray(extension_data?.data) ? extension_data.data : [];
1246-
// repo 匹配:两边统一使用 normalizeInstallUrl
1247-
const installedRepos = new Set(
1248-
data
1249-
.filter((ext) => ext.repo)
1250-
.map((ext) => normalizeInstallUrl(ext.repo).toLowerCase()),
1251-
);
12521251
// 使用 marketplace_name 进行市场匹配(后端已统一为减号格式)
1253-
const installedNames = new Set(data.map((ext) => normalizeStr(ext.marketplace_name)));
12541252
// 创建映射用于查询已安装插件的详细信息
12551253
const installedByRepo = new Map(
12561254
data
12571255
.filter((ext) => ext.repo)
12581256
.map((ext) => [normalizeInstallUrl(ext.repo).toLowerCase(), ext]),
12591257
);
1260-
const installedByName = new Map(data.map((ext) => [ext.marketplace_name, ext]));
1261-
1258+
const installedByName = new Map(
1259+
data
1260+
.filter((ext) => !ext.repo)
1261+
.map((ext) => [normalizeStr(ext.marketplace_name || ext.name), ext]),
1262+
);
1263+
12621264
for (let i = 0; i < pluginMarketData.value.length; i++) {
12631265
const plugin = pluginMarketData.value[i];
1266+
const repoKey = plugin.repo ? normalizeInstallUrl(plugin.repo).toLowerCase() : undefined;
12641267
const matchedInstalled =
1265-
(plugin.repo && installedByRepo.get(normalizeInstallUrl(plugin.repo).toLowerCase())) ||
1266-
installedByName.get(plugin.name);
1268+
(repoKey && installedByRepo.get(repoKey)) ||
1269+
installedByName.get(normalizeStr(plugin.name));
12671270

12681271
// 兜底:市场源未提供字段时,回填本地已安装插件中的元数据,便于在市场页直接展示
12691272
if (matchedInstalled) {
@@ -1279,9 +1282,7 @@ export const useExtensionPage = () => {
12791282
}
12801283
}
12811284

1282-
plugin.installed =
1283-
installedRepos.has(normalizeInstallUrl(plugin.repo).toLowerCase()) ||
1284-
installedNames.has(normalizeStr(plugin.name));
1285+
plugin.installed = !!matchedInstalled;
12851286
}
12861287

12871288
let installed = [];

0 commit comments

Comments
 (0)