diff --git a/src/views/portal/course/Index.vue b/src/views/portal/course/Index.vue index 7d1e72fe..a62221ca 100644 --- a/src/views/portal/course/Index.vue +++ b/src/views/portal/course/Index.vue @@ -634,34 +634,43 @@ export default { // window.removeEventListener("scroll", this.handleScroll); }, methods: { - // 判断是否是通过搜索关键字(而不是导航标签) - isKeywordSearch() { - // 如果有keyword且没有其他类型的选中项,则认为是关键字搜索 + getSearchMode() { const hasKeyword = this.keyword && this.keyword.trim() !== ''; - const hasOtherSelections = this.stagList.some(tag => - tag.type !== 0 && tag.checked // 除了关键字类型(0)以外的选中项 - ); - return hasKeyword && !hasOtherSelections; + // 检查是否有导航标签被选中 + const hasNavigationTags = this.stagList.some(tag => { + // 课程类型(1)、热点标签(14)、分类标签(11,12,13) + return [1, 11, 12, 13, 14].includes(tag.type) && tag.checked; + }); + + if (hasKeyword && hasNavigationTags) { + return 'mixed'; // 混合模式:关键字 + 导航标签 + } else if (hasKeyword) { + return 'keyword'; // 纯关键字搜索 + } else if (hasNavigationTags) { + return 'navigation'; // 纯导航标签搜索 + } else { + return 'none'; // 无搜索条件 + } }, // 高亮标签关键字 highlightTagKeyword(tag) { - if (!this.stagList || this.stagList.length === 0) { - return tag; - } + const searchMode = this.getSearchMode(); - // 如果是关键字搜索模式,进行部分匹配高亮 - if (this.isKeywordSearch()) { - return this.highlightPartialMatch(tag); - } - // 否则进行完全匹配高亮 - else { - return this.highlightExactMatch(tag); + switch (searchMode) { + case 'keyword': + return this.highlightPartialMatch(tag); + case 'navigation': + return this.highlightExactMatch(tag); + case 'mixed': + return this.highlightMixedMode(tag); + default: + return tag; } }, - // 部分匹配高亮(关键字搜索模式) + // 部分匹配高亮(纯关键字搜索模式) highlightPartialMatch(tag) { const searchKeywords = this.stagList .filter(searchTag => searchTag.type === 0) // 只处理关键字类型 @@ -684,10 +693,10 @@ export default { return highlightedTag; }, - // 完全匹配高亮(导航标签模式) + // 完全匹配高亮(纯导航标签模式) highlightExactMatch(tag) { const isMatched = this.stagList.some(searchTag => { - // 排除关键字类型,只检查导航标签 + // 只检查导航标签类型 if (searchTag.type === 0) return false; const searchName = searchTag.tagName || searchTag.name; @@ -701,6 +710,51 @@ export default { return tag; }, + // 混合模式高亮(关键字 + 导航标签) + highlightMixedMode(tag) { + // 1. 先检查是否完全匹配导航标签 + const exactMatched = this.stagList.some(searchTag => { + if (searchTag.type === 0) return false; + + const searchName = searchTag.tagName || searchTag.name; + return searchName === tag; + }); + + // 2. 如果完全匹配导航标签,整个标签高亮 + if (exactMatched) { + return `${tag}`; + } + + // 3. 否则检查是否包含关键字,进行部分高亮 + const searchKeywords = this.stagList + .filter(searchTag => searchTag.type === 0) + .map(searchTag => searchTag.tagName || searchTag.name) + .filter(keyword => keyword && keyword.trim()); + + if (searchKeywords.length === 0) { + return tag; + } + + let highlightedTag = tag; + let hasKeywordMatch = false; + + searchKeywords.forEach(keyword => { + if (tag.includes(keyword)) { + const regex = new RegExp(`(${this.escapeRegExp(keyword)})`, 'gi'); + highlightedTag = highlightedTag.replace(regex, '$1'); + hasKeywordMatch = true; + } + }); + + // 4. 如果有关键字匹配,返回部分高亮结果 + if (hasKeywordMatch) { + return highlightedTag; + } + + // 5. 都不匹配,返回原标签 + return tag; + }, + // 辅助方法:转义正则表达式特殊字符 escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); @@ -2652,6 +2706,8 @@ a.custom2 { color: #387DF7 !important; } + + /* 关键字部分匹配高亮样式 */ .keyword-highlight { color: #387DF7 !important; @@ -2666,6 +2722,15 @@ a.custom2 { background-color: transparent !important; } +/* 混合模式下的特殊样式(可选) */ +.mixed-exact-highlight { + color: #387DF7 !important; + font-weight: bold; + background-color: #f0f7ff !important; + padding: 1px 3px; + border-radius: 2px; +} + /* 确保标签基础样式 */ .course-tags ::v-deep .el-tag { color: #333333;