From dccd4c2cc71589123306e182605e5b39e9fa5299 Mon Sep 17 00:00:00 2001 From: Futureppo Date: Thu, 2 Oct 2025 21:37:21 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20package.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dashboard/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/dashboard/package.json b/dashboard/package.json index 56d6540e5..9c5d6f1e9 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -27,6 +27,7 @@ "lodash": "4.17.21", "marked": "^15.0.7", "markdown-it": "^14.1.0", + "pinyin-pro": "^3.26.0", "pinia": "2.1.6", "remixicon": "3.5.0", "vee-validate": "4.11.3", From 1056914fe2246157d0f6dead440b2d05670af7c4 Mon Sep 17 00:00:00 2001 From: Futureppo Date: Thu, 2 Oct 2025 21:37:50 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20ExtensionPage.vue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dashboard/src/views/ExtensionPage.vue | 29 ++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/dashboard/src/views/ExtensionPage.vue b/dashboard/src/views/ExtensionPage.vue index 0560cc018..0dfd4430b 100644 --- a/dashboard/src/views/ExtensionPage.vue +++ b/dashboard/src/views/ExtensionPage.vue @@ -5,6 +5,7 @@ import ConsoleDisplayer from '@/components/shared/ConsoleDisplayer.vue'; import ReadmeDialog from '@/components/shared/ReadmeDialog.vue'; import ProxySelector from '@/components/shared/ProxySelector.vue'; import axios from 'axios'; +import { pinyin } from 'pinyin-pro'; import { useCommonStore } from '@/stores/common'; import { useI18n, useModuleI18n } from '@/i18n/composables'; @@ -65,6 +66,32 @@ const marketSearch = ref(""); const filterKeys = ['name', 'desc', 'author']; const refreshingMarket = ref(false); +// 插件市场拼音搜索 +const normalizeStr = (s) => (s ?? '').toString().toLowerCase().trim(); +const toPinyinText = (s) => pinyin(s ?? '', { toneType: 'none' }).toLowerCase().replace(/\s+/g, ''); +const toInitials = (s) => pinyin(s ?? '', { pattern: 'first', toneType: 'none' }).toLowerCase().replace(/\s+/g, ''); +const marketCustomFilter = (value, query, item) => { + const q = normalizeStr(query); + if (!q) return true; + + const candidates = new Set(); + if (value != null) candidates.add(String(value)); + if (item?.name) candidates.add(String(item.name)); + if (item?.trimmedName) candidates.add(String(item.trimmedName)); + if (item?.desc) candidates.add(String(item.desc)); + if (item?.author) candidates.add(String(item.author)); + + for (const v of candidates) { + const nv = normalizeStr(v); + if (nv.includes(q)) return true; + const pv = toPinyinText(v); + if (pv.includes(q)) return true; + const iv = toInitials(v); + if (iv.includes(q)) return true; + } + return false; +}; + const plugin_handler_info_headers = computed(() => [ { title: tm('table.headers.eventType'), key: 'event_type_h' }, { title: tm('table.headers.description'), key: 'desc', maxWidth: '250px' }, @@ -772,7 +799,7 @@ onMounted(async () => { + :loading="loading_" v-model:search="marketSearch" :filter-keys="filterKeys" :custom-filter="marketCustomFilter">