1008257-PDF浏览器引用文本到对话框.md 6.39 KB

需求 1008257 - PDF 浏览器引用文本到对话框上下文

原始需求(一字不差)

需求标题:【工作台】PDF的浏览器-引用文本到对话框的上下文

状态:规划中 | 负责人:尹帮会 | 优先级:Middle | 创建者:Ryan章桦

创建时间:2026-03-11 14:31:11 | 修改时间:2026-03-13 21:01:56

原始描述

在PDF文件中选择文本,出现菜单,选择"引用文本到对话框":

[图片1: https://file.tapd.cn//tfl/captures/2026-03/tapd_67139335_base64_1773210470_797.png]

对话框中会出现对PDF文件的引用,鼠标悬停的时候,还可以看到引用的文本内容:

[图片2: https://file.tapd.cn//tfl/captures/2026-03/tapd_67139335_base64_1773210606_307.png]

然后进行提问,会得到针对性的结果

AI Plan(TAPD 自动生成,仅供参考)

### 需求摘要
在 PDF 文件中选择文本,出现菜单,选择"引用文本到对话框":对话框中会出现对 PDF 文件的引用,
鼠标悬停时可以看到引用的文本内容,然后进行提问,会得到针对性的结果。

### 改动文件清单
1. linkmed-vue3/src/components/Workspace/PDFViewerIframe.vue:添加文本选择和菜单功能
2. linkmed-vue3/src/components/AgentPanel/AgentChatAgent.vue:添加引用显示和悬停效果
3. linkmed-vue3/src/api/chat.ts:添加引用相关的接口
4. linkmed-vue3/src/stores/chatApi.ts:添加引用相关的状态

### 验收用例
1. 文本选择和菜单:在 PDF 中选择文本,出现菜单
2. 引用到对话框:选择"引用文本到对话框",对话框中出现引用
3. 悬停显示:鼠标悬停在引用上时显示引用的文本内容
4. 提问和回复:提问后得到针对性的结果

复杂度:Medium

图片理解

图片1(1854 × 1602 像素)- PDF 文本选中菜单

画面内容

  • 左侧:PDF 查看器,显示一篇物理医学期刊论文(Physics in Medicine & Biology)
  • 用户在 PDF 中选中了一段英文文本(蓝色高亮区域)
  • 选中文本后弹出浮动菜单,菜单包含两个按钮:
    1. "Copy and Cite"(复制并引用)
    2. "Quote in Chat"(引用到对话)—— 这就是目标功能的入口
  • 右侧:AI Chat 面板,显示正在进行的对话

关键细节

  • 菜单出现在选中文本附近(浮动定位)
  • 菜单样式为白色背景卡片,带有圆形图标
  • "Quote in Chat" 使用引号图标(💬)

图片2(1854 × 1602 像素)- 对话框中的引用标签

画面内容

  • 左侧:同一 PDF 查看器(同一篇论文)
  • 右侧 AI Chat 面板底部输入区域,显示引用成功加入上下文后的状态:
    • 输入框上方出现了一个引用标签/芯片(chip):显示 📄 PDF Quote ×
    • 该标签代表已引用的 PDF 文本片段
    • 右上角有 × 按钮可以移除引用
  • 对话列表中还可见 "1 source" 标签(表明已有来源引用)

悬停行为(需推断):

  • 鼠标悬停在 PDF Quote × 标签上时,应弹出 tooltip 显示引用的原始文本内容

关键细节

  • 引用标签样式:小型 chip,带文件类型图标 + "PDF Quote" 文字 + × 删除按钮
  • 标签位于聊天输入框上方(与截图功能的缩略图区域并列)
  • 标签颜色为浅灰/白色背景

实现方案

数据流

PDFViewerIframe mouseup → 显示浮动菜单
  → 点击「Quote in Chat」
  → chatApiStore.addPendingTextReference(text, fileName, fileId)
  → AgentChat.vue 渲染引用标签(.text-references chip)
  → 鼠标悬停显示原始引用文本(el-tooltip)
  → 用户发送时,引用文本格式化为 Markdown 引用块前缀拼入问题
  → 发送后 clearPendingTextReferences()

1. chatApi.ts(store)

  • 新增 PendingTextReference 接口(text, fileName, fileId)
  • ChatApiState 添加 pendingTextReferences: PendingTextReference[]
  • 新增 actions:addPendingTextReferenceremovePendingTextReferenceclearPendingTextReferences

2. PDFViewerIframe.vue

  • 引入 useWorkspaceChatStore
  • 新增 showTextMenutextMenuPosselectedTextContent 状态
  • handleTextMouseUp:mouseup 时读取 window.getSelection(),计算菜单位置
  • handleGlobalMouseDown:点击菜单外关闭菜单
  • quoteTextToChat:调用 store 添加引用,显示成功 ElMessage
  • template 中添加 .pdf-text-menu 浮动菜单(含「Copy and Cite」和「Quote in Chat」按钮)

3. AgentChat.vue

  • template 中在输入框上方添加 .text-references 文本引用 chip 区域
  • 每个 chip 显示:📄 PDF Quote + 删除 × 按钮 + el-tooltip 悬停显示原文
  • canSend computed 增加 pendingTextReferences.length > 0 条件
  • handleSend 中将文本引用格式化为 Markdown 引用块前缀,拼入最终问题
  • 发送后调用 chatApiStore.clearPendingTextReferences()

修改的文件

  • src/stores/chatApi.ts
  • src/components/Workspace/PDFViewerIframe.vue
  • src/components/AgentPanel/AgentChat.vue

测试结果

  • npm run type-check 通过,无 TypeScript 错误

测试覆盖

单元测试(vitest)

文件1:src/test/stores/chatApi-pdf-context.test.ts(chatApi store 部分,28 个用例)

测试组 用例
pendingTextReferences 初始状态 初始为空数组
addPendingTextReference 添加单条;连续添加多条;保存数字/字符串 fileId
removePendingTextReference 按索引删除;删除第一条;删除最后一条
clearPendingTextReferences 清空所有;对空数组操作不报错
互不干扰 清空文本引用不影响截图;删除截图不影响文本引用

文件2:src/test/features/text-reference-format.test.ts(格式化逻辑部分,7 个用例)

测试组 用例
buildFinalQuestion 无引用返回原始问题;有1条引用格式正确;多条引用用空行分隔;有引用无问题返回纯引用;文件名包在《》中;引用文本以>开头;保留特殊字符

E2E 测试(Playwright)

文件:e2e/tests/workspace-features.spec.ts(含 1008257 相关 3 个用例)

  • 工作台存在 PDF 查看器组件挂载点(.pdf-viewer-js 等)
  • PDF 查看器工具栏存在功能按钮(.pdf-toolbar)
  • AgentChat 文本引用区域初始状态正确隐藏(无引用时 .text-references 不渲染)