|
1 | 1 | import axios from "axios"; |
2 | | -import { pinyin } from "pinyin-pro"; |
3 | 2 | import { useCommonStore } from "@/stores/common"; |
4 | 3 | import { useI18n, useModuleI18n } from "@/i18n/composables"; |
5 | 4 | import { getPlatformDisplayName } from "@/utils/platformUtils"; |
6 | 5 | import { resolveErrorMessage } from "@/utils/errorUtils"; |
| 6 | +import { |
| 7 | + buildSearchQuery, |
| 8 | + matchesPluginSearch, |
| 9 | + normalizeStr, |
| 10 | + toInitials, |
| 11 | + toPinyinText, |
| 12 | +} from "@/utils/pluginSearch"; |
7 | 13 | import { ref, computed, onMounted, onUnmounted, reactive, watch } from "vue"; |
8 | 14 | import { useRoute, useRouter } from "vue-router"; |
9 | 15 | import { useDisplay } from "vuetify"; |
@@ -240,37 +246,6 @@ export const useExtensionPage = () => { |
240 | 246 | }); |
241 | 247 |
|
242 | 248 | // 插件市场拼音搜索 |
243 | | - const normalizeStr = (s) => (s ?? "").toString().toLowerCase().trim(); |
244 | | - const toPinyinText = (s) => |
245 | | - pinyin(s ?? "", { toneType: "none" }) |
246 | | - .toLowerCase() |
247 | | - .replace(/\s+/g, ""); |
248 | | - const toInitials = (s) => |
249 | | - pinyin(s ?? "", { pattern: "first", toneType: "none" }) |
250 | | - .toLowerCase() |
251 | | - .replace(/\s+/g, ""); |
252 | | - const marketCustomFilter = (value, query, item) => { |
253 | | - const q = normalizeStr(query); |
254 | | - if (!q) return true; |
255 | | - |
256 | | - const candidates = new Set(); |
257 | | - if (value != null) candidates.add(String(value)); |
258 | | - if (item?.name) candidates.add(String(item.name)); |
259 | | - if (item?.trimmedName) candidates.add(String(item.trimmedName)); |
260 | | - if (item?.display_name) candidates.add(String(item.display_name)); |
261 | | - if (item?.desc) candidates.add(String(item.desc)); |
262 | | - if (item?.author) candidates.add(String(item.author)); |
263 | | - |
264 | | - for (const v of candidates) { |
265 | | - const nv = normalizeStr(v); |
266 | | - if (nv.includes(q)) return true; |
267 | | - const pv = toPinyinText(v); |
268 | | - if (pv.includes(q)) return true; |
269 | | - const iv = toInitials(v); |
270 | | - if (iv.includes(q)) return true; |
271 | | - } |
272 | | - return false; |
273 | | - }; |
274 | 249 |
|
275 | 250 | const plugin_handler_info_headers = computed(() => [ |
276 | 251 | { title: tm("table.headers.eventType"), key: "event_type_h" }, |
@@ -347,47 +322,24 @@ export const useExtensionPage = () => { |
347 | 322 | // 通过搜索过滤插件 |
348 | 323 | const filteredPlugins = computed(() => { |
349 | 324 | const plugins = filteredExtensions.value; |
350 | | - let filtered = plugins; |
351 | | - |
352 | | - if (pluginSearch.value) { |
353 | | - const search = pluginSearch.value.toLowerCase(); |
354 | | - filtered = plugins.filter((plugin) => { |
355 | | - const pluginName = (plugin.name ?? "").toLowerCase(); |
356 | | - const pluginDesc = (plugin.desc ?? "").toLowerCase(); |
357 | | - const pluginAuthor = (plugin.author ?? "").toLowerCase(); |
358 | | - const supportPlatforms = Array.isArray(plugin.support_platforms) |
359 | | - ? plugin.support_platforms.join(" ").toLowerCase() |
360 | | - : ""; |
361 | | - const astrbotVersion = (plugin.astrbot_version ?? "").toLowerCase(); |
362 | | - |
363 | | - return ( |
364 | | - pluginName.includes(search) || |
365 | | - pluginDesc.includes(search) || |
366 | | - pluginAuthor.includes(search) || |
367 | | - supportPlatforms.includes(search) || |
368 | | - astrbotVersion.includes(search) |
369 | | - ); |
370 | | - }); |
371 | | - } |
| 325 | + const query = buildSearchQuery(pluginSearch.value); |
| 326 | + const filtered = query |
| 327 | + ? plugins.filter((plugin) => matchesPluginSearch(plugin, query)) |
| 328 | + : plugins; |
372 | 329 |
|
373 | 330 | return sortPluginsByName([...filtered]); |
374 | 331 | }); |
375 | 332 |
|
376 | 333 | // 过滤后的插件市场数据(带搜索) |
377 | 334 | const filteredMarketPlugins = computed(() => { |
378 | | - if (!debouncedMarketSearch.value) { |
| 335 | + const query = buildSearchQuery(debouncedMarketSearch.value); |
| 336 | + if (!query) { |
379 | 337 | return pluginMarketData.value; |
380 | 338 | } |
381 | | - |
382 | | - const search = debouncedMarketSearch.value.toLowerCase(); |
383 | | - return pluginMarketData.value.filter((plugin) => { |
384 | | - // 使用自定义过滤器 |
385 | | - return ( |
386 | | - marketCustomFilter(plugin.name, search, plugin) || |
387 | | - marketCustomFilter(plugin.desc, search, plugin) || |
388 | | - marketCustomFilter(plugin.author, search, plugin) |
389 | | - ); |
390 | | - }); |
| 339 | + |
| 340 | + return pluginMarketData.value.filter((plugin) => |
| 341 | + matchesPluginSearch(plugin, query), |
| 342 | + ); |
391 | 343 | }); |
392 | 344 |
|
393 | 345 | // 所有插件列表,推荐插件排在前面 |
@@ -1563,7 +1515,6 @@ export const useExtensionPage = () => { |
1563 | 1515 | normalizeStr, |
1564 | 1516 | toPinyinText, |
1565 | 1517 | toInitials, |
1566 | | - marketCustomFilter, |
1567 | 1518 | plugin_handler_info_headers, |
1568 | 1519 | pluginHeaders, |
1569 | 1520 | filteredExtensions, |
|
0 commit comments