# AI对话链接跳转与引用高亮优化 - 技术设计文档 **文档版本**: v1.0 **创建日期**: 2026-05-30 **状态**: ✅ 已批准,待实施 **方案选择**: 方案B - 统一搜索引擎重构 --- ## 1. 项目背景与问题定义 ### 1.1 当前问题 在AI智能问答模块(QAModule.vue)中,用户点击对话消息中的引用来源或[ref:xxx]标签后: 1. **PDF文件**:只能跳转到指定页码,**无法高亮显示关键词位置** 2. **Word/Excel等文件**:使用`indexOf精确匹配`,关键词截断后容易匹配失败 3. **时序问题**:文件DOM未完全渲染就执行搜索,导致定位失败 4. **用户体验差**:无搜索结果反馈、无导航控件、高亮效果短暂 ### 1.2 业务影响 - ❌ 用户无法快速定位到引用的具体内容位置 - ❌ 需要手动翻页查找,效率低下 - ❌ 多个匹配项时无法逐个浏览 - ❌ 降低知识管理系统的易用性和专业性 ### 1.3 目标用户 - 企业员工(制度文件查阅者) - HR/行政人员(制度发布者) - 管理员(系统维护者) ### 1.4 成功标准 ✅ 点击任意格式的引用 → 自动跳转 + 持续高亮显示 ✅ 支持模糊匹配(容错率≥90%) ✅ 提供上/下一处导航功能 ✅ 高亮效果美观且持久(手动关闭前不消失) ✅ 响应时间 < 2秒 --- ## 2. 解决方案架构 ### 2.1 整体架构图 ``` ┌─────────────────────────────────────────────────────┐ │ QAModule.vue │ │ [引用点击] → navigateToFileReader(ref) │ │ ↓ │ │ 提取: { fileId, filename, page, context, rawData } │ └──────────────────────┬──────────────────────────────┘ ↓ router.push(query参数) ┌─────────────────────────────────────────────────────┐ │ ReaderPage.vue │ │ │ │ ┌───────────────────────────────────────────┐ │ │ │ UniversalSearchEngine (新增) │ │ │ │ │ │ │ │ ┌─────────┐ ┌─────────┐ ┌────────────┐ │ │ │ │ │ Text │ │ Fuzzy │ │ Highlight │ │ │ │ │ │Extractor│ │ Search │ │ Renderer │ │ │ │ │ │ (提取) │ │ Engine │ │ (渲染) │ │ │ │ │ └────┬────┘ └────┬────┘ └─────┬──────┘ │ │ │ │ └──────────┼──────────┘ │ │ │ │ ↓ │ │ │ │ ┌──────────────────┐ │ │ │ │ │ SearchCoordinator │ │ │ │ │ │ (流程协调器) │ │ │ │ │ └────────┬─────────┘ │ │ │ └───────────────┼───────────────────────┘ │ │ ↓ │ │ SearchResult[] + UI Navigation Bar │ └─────────────────────────────────────────────────────┘ ``` ### 2.2 核心技术选型 | 组件 | 技术方案 | 版本 | 选型理由 | |------|---------|------|---------| | **模糊搜索引擎** | Fuse.js | 7.0.0 | 轻量(10KB)、支持中文、零依赖 | | **文本提取** | DOM TreeWalker API | 原生 | 无需依赖、浏览器原生支持 | | **高亮渲染** | Range + Custom Elements | 原生 | 精确控制、性能优秀 | | **PDF处理** | PDF.js textLayer | 已集成 | 复用现有pdfjs-viewer | --- ## 3. 模块详细设计 ### 3.1 模块一:TextExtractor(文本提取器) **职责**:从不同格式文件的DOM中提取结构化文本数据 **文件路径**:`src/utils/textExtractor.js` **核心方法**: ```typescript class TextExtractor { // 主入口:根据fileType分发到不同的提取策略 async extract(fileType: string, container: HTMLElement): Promise // PDF文本提取(从iframe的.textLayer提取) async extractPdfText(iframe: HTMLIFrameElement): Promise // DOCX/DOC文本提取(从.docx-wrapper提取分页) extractDocxText(container: HTMLElement): DocxPage[] // Excel/CSV文本提取(从表格单元格提取) extractExcelText(container: HTMLElement): TableCell[] // 通用DOM文本提取(TreeWalker遍历) extractDomText(container: HTMLElement): TextNode[] } ``` **数据结构**: ```typescript interface Document { text: string // 纯文本内容 type: 'text' | 'page' | 'cell' location?: { page?: number // 页码(PDF/DOCX) cellIndex?: [number, number] // 单元格坐标 [row, col] } element: HTMLElement // 对应的DOM元素引用 } ``` **关键实现细节**: - PDF:遍历`.textLayer > span`元素,按`data-page`属性分组 - DOCX:查找`.docx-wrapper > div`作为页面容器 - Excel:遍历`table tr td`,记录行列索引 - 通用:使用`TreeWalker(SHOW_TEXT)`过滤有意义的文本节点(长度≥2) --- ### 3.2 模块二:FuzzySearchEngine(模糊搜索引擎) **职责**:基于Fuse.js实现智能模糊匹配和相关性排序 **文件路径**:`src/utils/fuzzySearchEngine.js` **核心配置**: ```javascript const fuseConfig = { threshold: 0.4, // 匹配阈值(0=精确, 1=宽松) distance: 100, // 模式匹配的最大距离 includeScore: true, // 返回评分 includeMatches: true, // 返回匹配位置信息 minMatchCharLength: 2, // 最小匹配字符数 tokenize: true, // 启用分词模式 tokenSeparator: /[\s\p{P}]+/u, // 中英文分词正则 keys: ['text'] // 搜索字段 } ``` **核心方法**: ```typescript class FuzzySearchEngine { // 初始化索引(每次加载新文档时调用) initIndex(documents: Document[]): void // 执行搜索 search(keyword: string, options?: SearchOptions): SearchResult[] // 关键词预处理(提升中文匹配率) preprocessKeyword(keyword: string): string // 格式化原始结果为统一格式 formatResult(rawResult: FuseResult, index: number): SearchResult } ``` **输出数据结构**: ```typescript interface SearchResult { id: string // 唯一标识 type: 'text' | 'pdf' | 'table' score: number // 相似度评分 (0-1, 越高越匹配) matchedText: string // 匹配到的文本片段 context: string // 上下文(前后各50字符) location: { container?: HTMLElement startOffset?: number endOffset?: number pageNumber?: number // PDF专用 rect?: { x, y, width, height } // PDF专用 cellIndex?: [number, number] // 表格专用 } originalData: Document // 原始文档数据(用于高亮渲染) } ``` **中文优化策略**: 1. 预处理阶段去除中文标点符号(""''【】《》()) 2. 使用Unicode属性转义`\p{P}`匹配所有标点 3. 分词时按空格和标点切分 4. 设置合理的threshold(0.4)平衡精准度和召回率 --- ### 3.3 模块三:HighlightRenderer(高亮渲染器) **职责**:在文档DOM中创建、管理和销毁高亮标记 **文件路径**:`src/utils/highlightRenderer.js` **核心能力**: ```typescript class HighlightRenderer { // 渲染所有搜索结果的高亮 renderAll(results: SearchResult[]): number // 创建单个高亮(根据type分发) private createHighlight(result: SearchResult, index: number): Highlight // DOM类型高亮(text/docx/markdown/html等) private createDomHighlight(result, index): DomHighlight // PDF类型高亮(在iframe中创建overlay层) private createPdfHighlight(result, index): PdfHighlight // 表格类型高亮(Excel/CSV单元格) private createTableHighlight(result, index): TableHighlight // 导航控制 navigateTo(index: number): void next(): void prev(): void // 清除所有高亮 clearAll(): void } ``` **高亮样式规范**: #### DOM高亮(.search-highlight) ```css .search-highlight { background: linear-gradient(135deg, #fff3cd 0%, #ffe69c 100%); border-bottom: 2px solid #ffc107; border-radius: 2px; padding: 1px 2px; box-shadow: 0 1px 3px rgba(255, 193, 7, 0.3); cursor: pointer; } .search-highlight.active { background: linear-gradient(135deg, #ffd43b 0%, #fab005 100%); border-bottom: 3px solid #f59f00; animation: highlight-glow 2s ease-in-out infinite; } ``` #### PDF高亮(.pdf-highlight-overlay) - 使用绝对定位的div覆盖在文本上方 - 背景色:`rgba(255, 235, 59, 0.3)` - 边框:`2px solid #ffc107` - 包含角标显示序号 #### 表格高亮(.table-highlight) - 绿色系配色(区别于文本黄色) - 背景:`linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%)` - 边框:`2px solid #28a745` **交互特性**: - ✅ 点击高亮标记可跳转到该位置 - ✅ 当前激活项带脉冲发光动画 - ✅ 序号标签(1, 2, 3...)便于识别 - ✅ hover效果(轻微放大+阴影加深) --- ### 3.4 模块四:SearchCoordinator(协调控制器) **职责**:编排整个搜索→定位→高亮的完整流程,处理异常和重试 **文件路径**:`src/utils/searchCoordinator.js` **核心流程**: ``` execute(params) ↓ Step 1: 文本提取 (withRetry, 最多重试3次) ↓ Step 2: 页码过滤(如果指定了targetPage) ↓ Step 3: 初始化Fuse.js索引 → 执行搜索 ↓ Step 4: 渲染高亮 → 导航到第一个结果 ↓ 返回: { success, resultCount, stats } ``` **重试机制**: ```typescript async withRetry(fn: () => T, maxRetries: number, delayMs: number): Promise { for (let i = 0; i < maxRetries; i++) { try { return await fn() } catch (error) { if (i < maxRetries - 1) { await sleep(delayMs) // 等待DOM渲染完成 } else { throw error // 最后一次重试失败则抛出异常 } } } } ``` **错误处理**: - 文本提取失败 → 返回友好提示"无法提取文档内容" - 未找到匹配 → 返回"未找到XXX相关内容" - 高亮渲染部分失败 → 记录警告日志,继续渲染其他结果 - 全局异常 → 显示错误提示,不阻断用户操作 **性能统计**: ```typescript interface SearchStats { totalTime: number // 总耗时(ms) extractionTime: number // 文本提取耗时 searchTime: number // 搜索耗时 renderTime: number // 高亮渲染耗时 resultCount: number // 结果数量 } ``` --- ## 4. 集成方案 ### 4.1 QAModule.vue修改点 **文件路径**:`src/components/QAModule.vue` **修改函数**:`navigateToFileReader()` (第1126行) **改动内容**: ```javascript // 优化关键词提取逻辑(第1159-1175行) const keyword = '' // 优先级1: ref.context(引用上下文) if (ref.context) { keyword = ref.context.substring(0, 150) // 增加长度限制至150字符 } // 优先级2: ref.rawData中的多个字段 else if (ref.rawData) { const raw = ref.rawData keyword = raw.content || raw.context || raw.preview || raw.excerpt || raw.query || raw.question || '' if (keyword) keyword = keyword.substring(0, 150) } // 优先级3: ref.location中的文本描述 if (!keyword && ref.location && ref.location.length > 4) { const locText = ref.location.replace(/第\d+页|page\s*\d+/gi, '').trim() if (locText.length >= 4) keyword = locText.substring(0, 120) } // 清洗关键词 if (keyword) { keyword = cleanSearchKeyword(keyword) if (keyword.length < 4) keyword = '' // 最小长度要求降至4字符 } ``` **改动理由**: - 增加关键词长度限制(100→150),提高匹配成功率 - 扩展rawData字段检查范围 - 降低最小长度要求(4字符),适应短文本场景 --- ### 4.2 ReaderPage.vue集成 **文件路径**:`src/views/ReaderPage.vue` #### 4.2.1 新增imports ```javascript import searchCoordinator from '@/utils/searchCoordinator' // 新增响应式变量 const showNavigationControls = ref(false) const searchResultCount = ref(0) const currentHighlightIndex = ref(0) const searchKeywordPreview = ref('') ``` #### 4.2.2 修改onMounted逻辑 ```javascript onMounted(async () => { // ... 现有代码保持不变 ... if (fileId) { await loadFile(fileId, fileTitle, fileExtension, page) // ✨ 新增:自动执行搜索高亮 if (keyword?.trim()) { const renderDelays = { pdf: 1000, docx: 1500, pptx: 1200, xlsx: 800, default: 500 } const delay = renderDelays[fileType.value] || renderDelays.default setTimeout(async () => { const container = scrollContainerRef.value if (!container) return const result = await searchCoordinator.execute({ keyword, fileType: fileType.value, container, targetPage: page }) if (result.success) { showNavigationControls.value = true searchResultCount.value = result.resultCount searchKeywordPreview.value = keyword.substring(0, 20) + '...' message.success({ content: `找到 ${result.resultCount} 处匹配内容`, duration: 3 }) } else { message.warning({ content: result.message || '未找到相关内容', duration: 3 }) } }, delay) } } }) ``` #### 4.2.3 新增UI模板(搜索导航栏) ```html
``` #### 4.2.4 新增事件监听 ```javascript // 监听高亮导航事件(由HighlightRenderer触发) onMounted(() => { window.addEventListener('highlightNavigate', (e) => { const { currentIndex, total } = e.detail currentHighlightIndex.value = currentIndex searchResultCount.value = total }) }) onUnmounted(() => { window.removeEventListener('highlightNavigate') searchCoordinator.clearAllHighlights() // 清理高亮 }) ``` #### 4.2.5 新增方法 ```javascript // 导航控制方法 const nextHighlight = () => { searchCoordinator.nextHighlight() } const prevHighlight = () => { searchCoordinator.prevHighlight() } const closeSearch = () => { searchCoordinator.clearAllHighlights() showNavigationControls.value = false currentHighlightIndex.value = 0 searchResultCount.value = 0 } ``` --- ## 5. CSS样式规范 ### 5.1 高亮基础样式 已在"3.3 HighlightRenderer"章节详细定义,此处补充动画和导航栏样式。 ### 5.2 动画效果 ```css /* 脉冲发光动画(当前激活项) */ @keyframes highlight-glow { 0%, 100% { box-shadow: 0 3px 8px rgba(245, 159, 0, 0.6); } 50% { box-shadow: 0 4px 16px rgba(245, 159, 0, 0.9), 0 0 20px rgba(245, 159, 0, 0.4); } } /* 缩放脉冲(首次出现) */ @keyframes highlight-pulse { 0% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.05); opacity: 0.8; } 100% { transform: scale(1); opacity: 1; } } ``` ### 5.3 搜索导航栏 固定在阅读器底部中央,包含: - 左侧:搜索图标 + 匹配数量 + 关键词预览 - 中间:当前位置计数器(如 "2 / 5") - 右侧:上一处 / 下一处 / 关闭按钮 详见设计文档第3.3节的CSS代码。 --- ## 6. 数据流与时序 ### 6.1 完整交互时序图 ``` 用户点击引用来源组件 ↓ [QAModule.vue] navigateToFileReader(ref) ├─ 提取 filename, page, context/rawData ├─ 清洗生成 keyword (≤150字符) └─ router.push({ query: { id, title, extension, page, keyword, from: 'qa' } }) ↓ [Vue Router] 路由跳转到 /reader ↓ [ReaderPage.vue] onMounted() ├─ 解析路由参数 (id, page, keyword...) ├─ loadFile(id, title, extension, page) │ ├─ 调用API获取文件Blob │ ├─ 根据fileType渲染文档 (PDF/Word/Excel/...) │ └─ hasFileLoaded = true │ └─ setTimeout(delay) ← 等待DOM渲染完成 ↓ [searchCoordinator.execute()] │ ├─ Step 1: textExtractor.extract(fileType, container) │ ├─ withRetry(fn, 3, 200ms) ← 重试机制 │ └─ 返回 documents[] │ ├─ Step 2: 过滤目标页码(可选) │ ├─ Step 3: fuzzySearchEngine │ ├─ initIndex(documents) │ ├─ preprocessKeyword(keyword) │ └─ search() → results[] │ ├─ Step 4: highlightRenderer.renderAll(results) │ ├─ 遍历results创建高亮mark/overlay │ ├─ navigateTo(0) ← 跳转到第一个结果 │ └─ 返回 highlightCount │ └─ 返回 { success, resultCount, stats } ↓ 更新UI状态: ├─ showNavigationControls = true ├─ searchResultCount = N └─ 显示成功提示Toast ``` ### 6.2 时间估算 | 步骤 | 耗时 | 说明 | |------|------|------| | 文本提取 | 50-200ms | 取决于文档大小 | | Fuse.js索引构建 | 10-50ms | 取决于文本块数量 | | 搜索执行 | 5-20ms | Fuse.js高效算法 | | 高亮渲染 | 30-100ms | DOM操作 | | **总计** | **95-370ms** | **< 400ms,用户体验流畅** | 加上等待DOM渲染的delay(500-1500ms),总响应时间约**0.6-2秒**。 --- ## 7. 边界情况处理 ### 7.1 异常场景 | 场景 | 处理策略 | |------|---------| | **关键词为空** | 不执行搜索,仅跳转到指定页码 | | **文档内容为空** | 提示"无法提取文档内容",仍完成页面跳转 | | **无匹配结果** | 提示"未找到XXX相关内容",保持在目标页面 | | **部分高亮失败** | 记录警告日志,成功渲染的其他高亮正常显示 | | **PDF iframe跨域受限** | 降级为仅页码跳转,提示"PDF高亮暂不可用" | | **大文档(>10MB)** | 文本提取限流,只提取前1000个文本块 | | **用户快速连续点击** | 防抖处理(300ms),取消上一次搜索 | | **网络请求失败** | 显示错误提示,保留已渲染的高亮 | ### 7.2 兼容性保障 - **浏览器兼容**:Chrome 90+, Firefox 88+, Safari 14+, Edge 90+ - **Vue版本**:Vue 3.2+ (Composition API) - **移动端适配**:导航栏响应式布局,触摸友好的按钮尺寸 - **无障碍访问**:高亮元素添加aria-label,键盘导航支持(Tab/Enter) --- ## 8. 性能优化策略 ### 8.1 文本提取优化 - **懒加载**:只在需要搜索时才提取文本(非页面加载时) - **分批处理**:大文档分段提取,避免阻塞主线程 - **缓存机制**:相同文档不重复提取(基于fileId + hash缓存) ### 8.2 搜索引擎优化 - **增量更新**:文档内容变化时只更新受影响的索引条目 - **结果限制**:默认返回Top 20结果,避免过多DOM操作 - **Web Worker**:(可选)将Fuse.js搜索移至Worker线程(针对超大文档) ### 8.3 高亮渲染优化 - **虚拟滚动**:只渲染可视区域内的高亮(针对超多匹配项) - **批量DOM操作**:使用DocumentFragment减少reflow - **防抖清除**:快速切换时延迟清理旧高亮 ### 8.4 内存管理 - **及时清理**:离开页面时调用`clearAllHighlights()` - **引用释放**:断开DOM元素与JavaScript对象的循环引用 - **事件解绑**:onUnmounted时移除所有事件监听器 --- ## 9. 测试计划 ### 9.1 单元测试 | 测试模块 | 测试用例数 | 覆盖率目标 | |---------|-----------|-----------| | TextExtractor | 15 | ≥90% | | FuzzySearchEngine | 20 | ≥95% | | HighlightRenderer | 25 | ≥85% | | SearchCoordinator | 18 | ≥90% | **关键测试场景**: - PDF文本提取(含多页、空页、特殊字符) - 中文模糊匹配(同义词、错别字、截断关键词) - DOM高亮创建/销毁(内存泄漏检测) - 重试机制验证(模拟DOM未就绪) ### 9.2 集成测试 - **E2E测试**:使用Cypress自动化测试完整流程 1. 打开AI对话页面 2. 发送问题获得带引用的回答 3. 点击引用来源 4. 验证:页面跳转 + 高亮显示 + 导航栏出现 5. 点击"下一处",验证高亮切换 - **兼容性测试**:BrowserStack云测试平台 - Chrome/Firefox/Safari/Edge 最新3个版本 - Windows/macOS/Linux 桌面端 - iOS/Android 移动端(可选) ### 9.3 性能测试 - **加载性能**:Lighthouse Performance Score ≥ 90 - **搜索响应时间**:P99 < 2秒 - **内存占用**:高亮渲染后内存增长 < 50MB - **CPU占用**:搜索过程中CPU峰值 < 60% --- ## 10. 实施路线图 ### Phase 1:核心引擎开发(Day 1-2) **Day 1上午**: - [ ] 安装依赖:`npm install fuse.js@7.0.0` - [ ] 创建`src/utils/textExtractor.js` - [ ] 实现PDF/DOCX/Excel/DOM文本提取方法 - [ ] 编写单元测试(TextExtractor) **Day 1下午**: - [ ] 创建`src/utils/fuzzySearchEngine.js` - [ ] 配置Fuse.js中文优化参数 - [ ] 实现`preprocessKeyword`和`search`方法 - [ ] 编写单元测试(FuzzySearchEngine) **Day 2上午**: - [ ] 创建`src/utils/highlightRenderer.js` - [ ] 实现DOM/PDF/表格三种高亮类型 - [ ] 添加导航控制逻辑 - [ ] 编写单元测试(HighlightRenderer) **Day 2下午**: - [ ] 创建`src/utils/searchCoordinator.js` - [ ] 实现编排逻辑和重试机制 - [ ] 集成测试(4个模块联调) ### Phase 2:UI集成与调试(Day 3) **Day 3上午**: - [ ] 修改`QAModule.vue`的`navigateToFileReader` - [ ] 修改`ReaderPage.vue`的`onMounted` - [ ] 添加搜索导航栏UI模板 - [ ] 编写CSS样式(高亮+导航栏+动画) **Day 3下午**: - [ ] 本地开发环境调试 - [ ] 测试PDF高亮功能(重点) - [ ] 测试Word/Excel/TXT等多种格式 - [ ] 修复发现的bug ### Phase 3:打磨与优化(Day 4) **Day 4上午**: - [ ] 错误处理完善(边界情况) - [ ] 性能优化(内存/CPU) - [ ] 用户反馈收集(内部测试) **Day 4下午**: - [ ] 代码审查和重构 - [ ] 文档编写(使用指南) - [ ] 准备发布 --- ## 11. 风险评估与应对 ### 11.1 技术风险 | 风险项 | 概率 | 影响 | 应对措施 | |--------|------|------|---------| | **PDF iframe跨域限制** | 中 | 高 | 降级方案:仅页码跳转 + Toast提示 | | **Fuse.js中文分词不准** | 低 | 中 | 自定义tokenizer或引入jieba分词 | | **大文档性能问题** | 中 | 中 | 分批处理 + Web Worker + 虚拟滚动 | | **DOM高亮破坏文档结构** | 低 | 高 | 使用Range API + 异常捕获回滚 | ### 11.2 进度风险 - **风险**:Phase 2集成调试超出预期 - **应对**:预留1天buffer time,优先保证核心功能可用 --- ## 12. 成功验收标准 ### 功能完整性 ✅ - [ ] 点击PDF引用 → 跳转页码 + overlay高亮显示 - [ ] 点击Word引用 → DOM高亮 + 持续显示 - [ ] 点击Excel引用 → 单元格高亮 + 角标序号 - [ ] 模糊匹配成功率 ≥ 90%(测试集验证) - [ ] 导航栏正确显示匹配数量和当前位置 - [ ] 上/下一处按钮工作正常 ### 性能指标 ⚡ - [ ] 搜索+高亮总耗时 < 2秒(P99) - [ ] 内存增长 < 50MB(相对于无高亮状态) - [ ] CPU峰值 < 60%(搜索过程中) - [ ] Lighthouse Performance Score ≥ 90 ### 用户体验 😊 - [ ] 高亮视觉效果醒目但不刺眼 - [ ] 动画流畅(60fps) - [ ] 错误提示友好清晰 - [ ] 移动端触摸操作顺畅 - [ ] 键盘可访问(Tab/Enter导航) ### 代码质量 🔧 - [ ] 单元测试覆盖率 ≥ 85% - [ ] 无console警告(生产环境) - [ ] ESLint检查通过(0 error, 0 warning) - [ ] 代码注释完整(JSDoc标准) --- ## 13. 后续迭代方向(可选) ### Phase 4:增强功能(v2.0) - [ ] **多关键词同时高亮**:支持AND/OR逻辑组合 - [ ] **高亮导出**:将高亮标注导出为PDF注释 - [ ] **历史记录**:保存用户的搜索历史和高亮偏好 - [ ] **快捷键支持**:Ctrl+F唤起搜索框,F3跳转下一个 - [ ] **AI语义搜索**:升级为向量相似度匹配(需后端支持) ### Phase 5:平台扩展(v3.0) - [ ] **Web Worker迁移**:将搜索引擎移至Worker线程 - [ ] **IndexedDB缓存**:离线缓存文本提取结果 - [ ] **PWA支持**:离线模式下仍可使用基本搜索功能 - [ ] **插件机制**:允许第三方开发者自定义高亮样式 --- ## 附录A:关键技术参考 ### A.1 Fuse.js官方文档 https://fusejs.io/ ### A.2 Range API(MDN) https://developer.mozilla.org/en-US/docs/Web/API/Range ### A.3 TreeWalker API(MDN) https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker ### A.4 PDF.js textLayer https://github.com/nickmoss/pdfjs-viewer-textlayer --- ## 附录B:术语表 | 术语 | 定义 | |------|------| | **RAG** | Retrieval-Augmented Generation(检索增强生成) | | **SSE** | Server-Sent Events(服务器推送事件) | | **Fuse.js** | 轻量级模糊搜索库 | | **TreeWalker** | DOM树遍历API | | **Range** | DOM范围选择API | | **Overlay** | 覆盖层(用于PDF高亮) | --- **文档维护者**:AI Code Assistant **最后更新**:2026-05-30 **下次评审日期**:实施完成后3天内