From c67a63267f09d385c8e2016ff5ac958b84ba935c Mon Sep 17 00:00:00 2001 From: Estrella Pan Date: Fri, 9 Oct 2026 15:34:31 +0200 Subject: [PATCH] =?UTF-8?q?fix(webui):=20=E5=A4=84=E7=90=86=E5=B8=82?= =?UTF-8?q?=E5=9C=BA=E9=A1=B5=E4=B8=8E=E5=86=85=E7=BD=AE=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E6=96=87=E6=A1=88=E7=9A=84=E5=AE=A1=E6=9F=A5=E6=84=8F=E8=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 设置页与市场页通过 pluginSetVersion 在再次进入时互相同步;刷新逻辑合并为 refreshPluginState - 安装成功后本地更新 installed_version,不再重新下载目录 - 选中的插件变化时关闭确认栏,避免装错插件 - 本机版本比目录新时不提示更新 - 内置插件文案只用于 source 为 builtin 的插件 - README:链接中的行内代码、段落中的“2024.”、分隔线、标题中的“C#” --- .../src/components/setting/config-plugins.vue | 32 +++++++------- webui/src/hooks/usePluginRefresh.ts | 23 ++++++++++ webui/src/pages/index/market/[[id]].vue | 40 ++++++----------- webui/src/pages/index/market/market.test.ts | 5 ++- webui/src/utils/__tests__/markdown.test.ts | 18 ++++++-- .../src/utils/__tests__/plugin-market.test.ts | 23 ++++++---- webui/src/utils/markdown.ts | 21 +++++++-- webui/src/utils/plugin-market.ts | 15 ++++++- webui/src/utils/plugin-text.ts | 43 +++++++++++++------ webui/types/dts/auto-imports.d.ts | 2 + 10 files changed, 149 insertions(+), 73 deletions(-) create mode 100644 webui/src/hooks/usePluginRefresh.ts diff --git a/webui/src/components/setting/config-plugins.vue b/webui/src/components/setting/config-plugins.vue index 507f570b..c5cbcf7a 100644 --- a/webui/src/components/setting/config-plugins.vue +++ b/webui/src/components/setting/config-plugins.vue @@ -9,8 +9,7 @@ import PluginSchemaForm from './plugin-schema-form.vue'; import type { PluginInfo, PluginsOverview } from '#/plugins'; import { apiPlugins } from '@/api/plugins'; import { useConfirm } from '@/hooks/useConfirm'; -import { refreshPluginProviders } from '@/hooks/usePluginProviders'; -import { refreshPluginUi } from '@/hooks/usePluginUi'; +import { pluginSetVersion, refreshPluginState } from '@/hooks/usePluginRefresh'; import { idLabel } from '@/utils/id-label'; import { fillSchemaDefaults, schemaFields } from '@/utils/plugin-schema'; import { @@ -27,13 +26,13 @@ const message = useMessage(); const router = useRouter(); const { confirm } = useConfirm(); const configStore = useConfigStore(); -const { refreshGroup } = configStore; const overview = ref(null); const drafts = ref>>({}); // 并发操作各自占用一个 key,互不覆盖对方的加载态 const busy = ref(new Set()); const loadError = ref(false); +let seenVersion = pluginSetVersion.value; const stateType = { active: 'success', @@ -84,12 +83,8 @@ async function run( busy.value.add(key); try { apply(await action()); - // 只刷新插件卡片保存的字段,保留未保存的下载器实例与 slots 修改 - await refreshGroup('plugins', ['allow_unsigned', 'enabled', 'options']); - // 插件启停会增减下载器/通知渠道候选,同步刷新下拉框 - await refreshPluginProviders(); - // 启停也会增减插件的前端挂载点 - await refreshPluginUi(); + await refreshPluginState(); + seenVersion = pluginSetVersion.value; return true; } catch { // 后端的具体原因(如验签失败)由 axios 拦截器另行提示 @@ -139,7 +134,7 @@ async function setEnabled(plugin: PluginInfo, enabled: boolean) { impact && !(await confirm({ title: t('config.plugins_set.disable_confirm_title', { - name: pluginName(t, plugin.id, plugin.name), + name: pluginName(t, plugin), }), body: impact, confirmText: t('config.plugins_set.disable'), @@ -163,7 +158,7 @@ async function saveOptions(plugin: PluginInfo) { async function uninstall(plugin: PluginInfo) { const confirmed = await confirm({ title: t('config.plugins_set.uninstall_confirm_title', { - name: pluginName(t, plugin.id, plugin.name), + name: pluginName(t, plugin), }), body: [impactText(plugin), t('config.plugins_set.uninstall_confirm_body')] .filter(Boolean) @@ -181,6 +176,13 @@ async function uninstall(plugin: PluginInfo) { } onMounted(load); + +// 设置页被 KeepAlive 缓存:插件市场安装或更新后,再次进入时重新加载列表 +onActivated(() => { + if (seenVersion === pluginSetVersion.value) return; + seenVersion = pluginSetVersion.value; + return load(); +});