⭐ 此文件是 dev-sessions 文档的标准范例,用于后续需求参考。 原始文件:
claude-code/dev-sessions/1008257-PDF浏览器引用文本到对话框.md该需求功能可能被删除,但本范例永久保留在claude-code/workflow/目录中。
需求 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 中选中了一段英文文本(蓝色高亮区域)
- 选中文本后弹出浮动菜单,菜单包含两个按钮:
- "Copy and Cite"(复制并引用)
- "Quote in Chat"(引用到对话)—— 这就是目标功能的入口
- 右侧:AI Chat 面板,显示正在进行的对话
关键细节:
- 菜单出现在选中文本附近(浮动定位)
- 菜单样式为白色背景卡片,带有圆形图标
- "Quote in Chat" 使用引号图标(💬)
图片2(1854 × 1602 像素)- 对话框中的引用标签
画面内容:
- 左侧:同一 PDF 查看器(同一篇论文)
- 右侧 AI Chat 面板底部输入区域,显示引用成功加入上下文后的状态:
- 输入框上方出现了一个引用标签/芯片(chip):显示
📄 PDF Quote × - 该标签代表已引用的 PDF 文本片段
- 右上角有
×按钮可以移除引用
- 输入框上方出现了一个引用标签/芯片(chip):显示
- 对话列表中还可见 "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:
addPendingTextReference、removePendingTextReference、clearPendingTextReferences
2. PDFViewerIframe.vue
- 引入
useWorkspaceChatStore - 新增
showTextMenu、textMenuPos、selectedTextContent状态 -
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 悬停显示原文 -
canSendcomputed 增加pendingTextReferences.length > 0条件 -
handleSend中将文本引用格式化为 Markdown 引用块前缀,拼入最终问题 - 发送后调用
chatApiStore.clearPendingTextReferences()
修改的文件
src/stores/chatApi.tssrc/components/Workspace/PDFViewerIframe.vuesrc/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 不渲染)