1008258-PDF截图引用到对话框.md 6.38 KB

需求 1008258 - PDF 浏览器截图引用到对话框上下文

原始需求(一字不差)

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

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

创建时间:2026-03-11 14:33:37 | 修改时间:2026-03-13 20:07:40

原始描述

1.点击按钮,开启截图功能

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

2.截完图之后,会把图片加入到对话框的上下文

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

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

### 需求摘要
在工作台的PDF浏览器中添加截图功能,截图后将图片加入到对话框的上下文。

### 改动文件清单
1. linkmed-vue3/src/components/Workspace/PDFViewerIframe.vue:添加截图按钮和截图功能
2. linkmed-vue3/src/components/Workspace/WorkspaceChat.vue:添加处理截图的逻辑
3. linkmed-vue3/src/stores/chatApi.ts:添加状态管理逻辑
4. linkmed-vue3/src/api/files.ts:可能需要添加文件上传相关接口

### 验收用例
1. 截图功能:点击截图按钮可以开启截图功能
2. 图片添加到对话框:截图后图片会加入到对话框的上下文
3. 图片显示:对话框中可以正常显示截图图片

复杂度:Medium

图片理解

图片1(1860 × 1598 像素)- 截图按钮激活状态

画面内容

  • 左侧:PDF 查看器,显示物理医学期刊论文
  • 红色方框标注:PDF 查看器顶部工具栏右侧,有一个被红框圈出的区域,该区域显示一个 ×(关闭/取消)图标
  • 这说明:截图模式已处于激活状态,工具栏上显示的是「取消截图」的 × 按钮,而非激活前的相机图标
  • 右侧:AI Chat 面板正常显示

关键理解

  • 截图模式激活后,工具栏上的截图按钮变为 ×(取消截图)
  • 截图激活时,整个 PDF 区域上方会叠加遮罩层,支持拖拽选区

图片2(1856 × 1604 像素)- 截图加入对话框上下文

画面内容

  • 左侧:同一 PDF 查看器
  • 右侧底部:AI Chat 输入区域
  • 红色箭头标注:输入框区域下方偏右位置,可以看到一个小图片缩略图(截图预览)
  • 该截图缩略图出现在聊天输入框的上下文附件区域,说明截图已成功加入对话上下文

关键细节

  • 截图缩略图位于输入框上方的附件预览区
  • 缩略图较小(约 80×60px),可能带有删除按钮
  • 截图作为图片附件被加入到本次提问的上下文中

实现方案

数据流

PDF 工具栏截图按钮(相机图标)点击
  → toggleScreenshotMode() 激活,按钮变为 ×
  → PDF 区域叠加透明遮罩层 .screenshot-overlay
  → 用户 mousedown → 拖拽 → mouseup 形成选区
  → captureScreenshotRegion():遍历 PDF canvas,合成选区截图(处理 devicePixelRatio)
  → chatApiStore.addPendingScreenshot(base64DataURL)
  → AgentChat.vue .screenshot-previews 显示缩略图
  → 用户发送时,msg.screenshots 传给 AgentPanelBody
  → 上传文件获取 fileId → 加入 context
  → clearPendingScreenshots()

1. chatApi.ts(store)

  • 新增 PendingScreenshot 类型(base64 data URL 字符串)
  • ChatApiState 添加 pendingScreenshots: PendingScreenshot[]
  • 新增 actions:addPendingScreenshotremovePendingScreenshotclearPendingScreenshots

2. PDFViewerIframe.vue

  • 工具栏新增截图按钮(相机图标 fa-camera),激活后变为 × 取消按钮
  • 激活时在 PDF 查看器上方叠加全屏透明遮罩 .screenshot-overlay(cursor: crosshair)
  • 鼠标 mousedown/mousemove/mouseup 事件实现拖拽选区(半透明蓝色选框)
  • captureScreenshotRegion:遍历所有页面的 canvas,根据选区坐标合成截图(处理 devicePixelRatio)
  • Esc 键监听取消截图模式
  • 截图完成后自动关闭截图模式,调用 chatApiStore.addPendingScreenshot,显示成功提示

3. AgentChat.vue

  • 在输入框上方添加 .screenshot-previews 截图缩略图区域
  • 每个缩略图:80×60px 图片预览 + 右上角 × 删除按钮
  • canSend computed 增加 pendingScreenshots.length > 0 条件(有截图时也可发送)
  • handleSend 中将截图数组通过 msg.screenshots 传给父组件,发送后调用 clearPendingScreenshots

4. AgentPanelBody.vue

  • 导入 createUploadSessionuploadBatch from @/api/files
  • handleSendAsk:解析 msg.screenshots,将 base64 转为 File 对象,通过 createUploadSession + uploadBatch 上传,将得到的 fileId 加入 contextArray
  • handleSendAgent:同上,将截图 fileId 加入 newContextFileIds

修改的文件

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

测试结果

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

测试覆盖

单元测试(vitest)

文件1:src/test/stores/chatApi-pdf-context.test.ts(chatApi store 截图部分,18 个相关用例)

测试组 用例
pendingScreenshots 初始状态 初始为空数组
addPendingScreenshot 添加单张截图;连续添加多张;base64 原样保存不处理
removePendingScreenshot 按索引删除;删除第一张;删除最后一张
clearPendingScreenshots 清空所有;对空数组操作不报错
互不干扰 清空截图不影响文本引用;清空文本引用不影响截图

文件2:src/test/features/text-reference-format.test.ts(截图 base64 转 File 逻辑,7 个用例)

测试组 用例
base64ToFile 转换为 File 实例;MIME 类型正确;文件名含 screenshot;文件名含 index;无 MIME 默认 image/png;文件大小>0;多张截图文件名不同

E2E 测试(Playwright)

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

  • PDF 查看器工具栏存在截图按钮(.screenshot-btn 或 fa-camera)
  • AgentChat 截图预览区域初始状态正确隐藏(无截图时 .screenshot-previews 不渲染)
  • 对话框输入区域整体结构完整(.chat-input-container 存在)