From caec568a24852e8e21cd73d8663e38179a8958ad Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Tue, 5 May 2026 00:39:24 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E4=BC=98=E5=8C=96=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dashboard/src/lib/plugin-api/marketplace.ts | 1 + .../src/routes/config/bot/hooks/useAutoSave.ts | 17 +++++++++++++++-- dashboard/src/routes/plugins/MarketplaceTab.tsx | 5 +++++ dashboard/src/routes/plugins/index.tsx | 2 ++ dashboard/src/types/plugin.ts | 2 ++ 5 files changed, 25 insertions(+), 2 deletions(-) diff --git a/dashboard/src/lib/plugin-api/marketplace.ts b/dashboard/src/lib/plugin-api/marketplace.ts index 0842a91a..4e243410 100644 --- a/dashboard/src/lib/plugin-api/marketplace.ts +++ b/dashboard/src/lib/plugin-api/marketplace.ts @@ -121,6 +121,7 @@ export async function fetchPluginList(): Promise> { rating: 0, review_count: 0, installed: false, + source: 'market' as const, published_at: new Date().toISOString(), updated_at: new Date().toISOString(), })) diff --git a/dashboard/src/routes/config/bot/hooks/useAutoSave.ts b/dashboard/src/routes/config/bot/hooks/useAutoSave.ts index 3d8bf7e1..6f338a0b 100644 --- a/dashboard/src/routes/config/bot/hooks/useAutoSave.ts +++ b/dashboard/src/routes/config/bot/hooks/useAutoSave.ts @@ -288,10 +288,23 @@ export function useConfigAutoSave( isInitialLoad: boolean, triggerAutoSave: (sectionName: ConfigSectionName, data: unknown) => void ): void { + const previousSnapshotRef = useRef(null) + useEffect(() => { - if (config && !isInitialLoad) { + if (!config) { + return + } + + const snapshot = JSON.stringify(config) + if (isInitialLoad || previousSnapshotRef.current === null) { + previousSnapshotRef.current = snapshot + return + } + + if (snapshot !== previousSnapshotRef.current) { + previousSnapshotRef.current = snapshot triggerAutoSave(sectionName, config) } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [config]) + }, [config, isInitialLoad]) } diff --git a/dashboard/src/routes/plugins/MarketplaceTab.tsx b/dashboard/src/routes/plugins/MarketplaceTab.tsx index e623530c..096ee129 100644 --- a/dashboard/src/routes/plugins/MarketplaceTab.tsx +++ b/dashboard/src/routes/plugins/MarketplaceTab.tsx @@ -43,6 +43,11 @@ export function MarketplaceTab({ console.warn('[过滤] 跳过无 manifest 的插件:', plugin.id) return false } + + // 全部插件只展示 plugin-repo 中存在的市场插件,本地独有插件只在“已安装”显示。 + if (plugin.source === 'local') { + return false + } // 搜索过滤 const matchesSearch = searchQuery === '' || diff --git a/dashboard/src/routes/plugins/index.tsx b/dashboard/src/routes/plugins/index.tsx index ed529474..64ef02de 100644 --- a/dashboard/src/routes/plugins/index.tsx +++ b/dashboard/src/routes/plugins/index.tsx @@ -239,6 +239,7 @@ function PluginsPageContent() { review_count: 0, installed: true, installed_version: installedPlugin.manifest.version, + source: 'local', published_at: new Date().toISOString(), updated_at: new Date().toISOString(), }) @@ -636,6 +637,7 @@ function PluginsPageContent() { const getFilteredPluginCount = (tab: 'all' | 'installed' | 'updates') => { return plugins.filter(p => { if (!p.manifest) return false + if (tab === 'all' && p.source === 'local') return false const matchesSearch = searchQuery === '' || p.manifest.name?.toLowerCase().includes(searchQuery.toLowerCase()) || p.manifest.description?.toLowerCase().includes(searchQuery.toLowerCase()) || diff --git a/dashboard/src/types/plugin.ts b/dashboard/src/types/plugin.ts index ddbcecaf..db38853e 100644 --- a/dashboard/src/types/plugin.ts +++ b/dashboard/src/types/plugin.ts @@ -82,6 +82,8 @@ export interface PluginInfo { screenshots?: string[] /** 更新日志 */ changelog?: string + /** 插件来源:plugin-repo 市场或本地已安装插件 */ + source?: 'market' | 'local' } /**