27 KiB
AI对话链接跳转与引用高亮优化 - 技术设计文档
文档版本: v1.0
创建日期: 2026-05-30
状态: ✅ 已批准,待实施
方案选择: 方案B - 统一搜索引擎重构
1. 项目背景与问题定义
1.1 当前问题
在AI智能问答模块(QAModule.vue)中,用户点击对话消息中的引用来源或[ref:xxx]标签后:
- PDF文件:只能跳转到指定页码,无法高亮显示关键词位置
- Word/Excel等文件:使用
indexOf精确匹配,关键词截断后容易匹配失败 - 时序问题:文件DOM未完全渲染就执行搜索,导致定位失败
- 用户体验差:无搜索结果反馈、无导航控件、高亮效果短暂
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
核心方法:
class TextExtractor {
// 主入口:根据fileType分发到不同的提取策略
async extract(fileType: string, container: HTMLElement): Promise<Document[]>
// PDF文本提取(从iframe的.textLayer提取)
async extractPdfText(iframe: HTMLIFrameElement): Promise<PdfPage[]>
// DOCX/DOC文本提取(从.docx-wrapper提取分页)
extractDocxText(container: HTMLElement): DocxPage[]
// Excel/CSV文本提取(从表格单元格提取)
extractExcelText(container: HTMLElement): TableCell[]
// 通用DOM文本提取(TreeWalker遍历)
extractDomText(container: HTMLElement): TextNode[]
}
数据结构:
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
核心配置:
const fuseConfig = {
threshold: 0.4, // 匹配阈值(0=精确, 1=宽松)
distance: 100, // 模式匹配的最大距离
includeScore: true, // 返回评分
includeMatches: true, // 返回匹配位置信息
minMatchCharLength: 2, // 最小匹配字符数
tokenize: true, // 启用分词模式
tokenSeparator: /[\s\p{P}]+/u, // 中英文分词正则
keys: ['text'] // 搜索字段
}
核心方法:
class FuzzySearchEngine {
// 初始化索引(每次加载新文档时调用)
initIndex(documents: Document[]): void
// 执行搜索
search(keyword: string, options?: SearchOptions): SearchResult[]
// 关键词预处理(提升中文匹配率)
preprocessKeyword(keyword: string): string
// 格式化原始结果为统一格式
formatResult(rawResult: FuseResult, index: number): SearchResult
}
输出数据结构:
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 // 原始文档数据(用于高亮渲染)
}
中文优化策略:
- 预处理阶段去除中文标点符号(""''【】《》())
- 使用Unicode属性转义
\p{P}匹配所有标点 - 分词时按空格和标点切分
- 设置合理的threshold(0.4)平衡精准度和召回率
3.3 模块三:HighlightRenderer(高亮渲染器)
职责:在文档DOM中创建、管理和销毁高亮标记
文件路径:src/utils/highlightRenderer.js
核心能力:
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)
.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 }
重试机制:
async withRetry<T>(fn: () => T, maxRetries: number, delayMs: number): Promise<T> {
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相关内容"
- 高亮渲染部分失败 → 记录警告日志,继续渲染其他结果
- 全局异常 → 显示错误提示,不阻断用户操作
性能统计:
interface SearchStats {
totalTime: number // 总耗时(ms)
extractionTime: number // 文本提取耗时
searchTime: number // 搜索耗时
renderTime: number // 高亮渲染耗时
resultCount: number // 结果数量
}
4. 集成方案
4.1 QAModule.vue修改点
文件路径:src/components/QAModule.vue
修改函数:navigateToFileReader() (第1126行)
改动内容:
// 优化关键词提取逻辑(第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
import searchCoordinator from '@/utils/searchCoordinator'
// 新增响应式变量
const showNavigationControls = ref(false)
const searchResultCount = ref(0)
const currentHighlightIndex = ref(0)
const searchKeywordPreview = ref('')
4.2.2 修改onMounted逻辑
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模板(搜索导航栏)
<!-- 在reader-container内部、底部添加 -->
<Transition name="slide-up">
<div v-if="showNavigationControls" class="search-nav-bar">
<div class="nav-info">
<SearchOutlined class="nav-icon" />
<span>找到 <strong>{{ searchResultCount }}</strong> 处匹配</span>
<span class="keyword-preview">"{{ searchKeywordPreview }}"</span>
</div>
<div class="nav-actions">
<button
class="nav-btn"
@click="prevHighlight"
:disabled="currentHighlightIndex <= 0"
>
<UpOutlined /> 上一处
</button>
<span class="nav-counter">
{{ currentHighlightIndex + 1 }} / {{ searchResultCount }}
</span>
<button
class="nav-btn"
@click="nextHighlight"
:disabled="currentHighlightIndex >= searchResultCount - 1"
>
下一处 <DownOutlined />
</button>
<button class="nav-btn close-btn" @click="closeSearch">
<CloseOutlined />
</button>
</div>
</div>
</Transition>
4.2.4 新增事件监听
// 监听高亮导航事件(由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 新增方法
// 导航控制方法
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 动画效果
/* 脉冲发光动画(当前激活项) */
@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自动化测试完整流程
- 打开AI对话页面
- 发送问题获得带引用的回答
- 点击引用来源
- 验证:页面跳转 + 高亮显示 + 导航栏出现
- 点击"下一处",验证高亮切换
-
兼容性测试: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官方文档
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天内