From e426f12e22af84711c1fb6fe483f5564dce0a307 Mon Sep 17 00:00:00 2001 From: Nelson <1475262689@qq.com> Date: Thu, 30 Jul 2026 17:14:51 +0800 Subject: [PATCH] fix: highlight full knowledge search terms --- .../components/KnowledgeManagementView.vue | 18 ++++++++----- .../apps/admin-web/src/types/api.ts | 1 + .../app/api/admin_knowledge_lifecycle.py | 26 +++++++++++++++++++ .../backend/tests/test_knowledge_admin.py | 22 ++++++++++++++++ 4 files changed, 60 insertions(+), 7 deletions(-) diff --git a/ai_knowledge_base_v2/apps/admin-web/src/components/KnowledgeManagementView.vue b/ai_knowledge_base_v2/apps/admin-web/src/components/KnowledgeManagementView.vue index 896c297..6edc8bb 100644 --- a/ai_knowledge_base_v2/apps/admin-web/src/components/KnowledgeManagementView.vue +++ b/ai_knowledge_base_v2/apps/admin-web/src/components/KnowledgeManagementView.vue @@ -388,20 +388,24 @@ function matchedLabel(values: string[]) { return labels.join("、"); } -function highlightSnippet(text: string) { - const keyword = contentSearch.keyword.trim(); - if (!keyword) return [{ text, match: false }]; +function highlightSnippet(text: string, terms: string[] = []) { + const keywords = Array.from(new Set([...terms, contentSearch.keyword.trim()].filter(Boolean))) + .sort((left, right) => right.length - left.length); + if (!keywords.length) return [{ text, match: false }]; const parts: Array<{ text: string; match: boolean }> = []; const source = text || ""; const lowerSource = source.toLowerCase(); - const lowerKeyword = keyword.toLowerCase(); let cursor = 0; while (cursor < source.length) { - const index = lowerSource.indexOf(lowerKeyword, cursor); - if (index < 0) { + const next = keywords + .map((keyword) => ({ keyword, index: lowerSource.indexOf(keyword.toLowerCase(), cursor) })) + .filter((item) => item.index >= 0) + .sort((left, right) => left.index - right.index || right.keyword.length - left.keyword.length)[0]; + if (!next) { parts.push({ text: source.slice(cursor), match: false }); break; } + const { index, keyword } = next; if (index > cursor) parts.push({ text: source.slice(cursor, index), match: false }); parts.push({ text: source.slice(index, index + keyword.length), match: true }); cursor = index + keyword.length; @@ -493,7 +497,7 @@ async function confirmAction( {{ item.knowledgeName }} · V{{ item.versionNo }} · {{ item.sectionKey }} · 命中{{ matchedLabel(item.matchedIn) }}

-