feat(web-admin): add copy-to-clipboard for attachment images
Let users copy images next to download on shared attachment cards, preview toolbars, and list cells so they can paste into chat or docs without saving files first. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
53987bdf22
commit
43e240ad6a
11 files changed
+699
-14
No files matched your search
@@ -0,0 +1,98 @@
|
||||
# Web 附件图片复制到剪贴板
|
||||
|
||||
工单:https://gitea.aichengyan.com/cykj/shanxia2.0/issues/28
|
||||
|
||||
## 背景与问题
|
||||
|
||||
系统多处图片/文件展示提供「下载」,用户希望再提供「复制」,将图片快速写入操作系统剪贴板,便于粘贴到微信、Word 等。场景分布在列表缩略图、表单附件卡、详情只读与预览弹窗,入口需统一,避免逐页发明交互。
|
||||
|
||||
## 已确认决策
|
||||
|
||||
| 项 | 结论 | 依据 |
|
||||
| --- | --- | --- |
|
||||
| 修改端 | 仅 `web-admin`(桌面 Web;移动 H5 若复用同一附件组件则自动获得) | 用户 2026-11-14 确认「只修改 web 端,不改小程序端」 |
|
||||
| 主入口 | 与「下载」同级的显式「复制」按钮;预览弹窗工具栏必有 | 对话方案获用户认可 |
|
||||
| 图片行为 | 写入系统剪贴板为图片(`image/png` 优先) | Clipboard API + 用户诉求 |
|
||||
| 非图片 | 不写入文件本体;可「复制链接」或仅保留下载 | 浏览器对任意文件剪贴板支持差 |
|
||||
| 右键 / 快捷键 | 本期不做主入口(可不做) | 发现成本高、易与表格/输入焦点冲突 |
|
||||
| 小程序 | 本期不改 | 用户明确排除;且无法位图复制 |
|
||||
| Figma 原型 | 免除,按现有下载旁按钮样式实现 | 用户 2026-11-14 选择「1」;此前推荐亦到期可采用 |
|
||||
|
||||
## 方案对比
|
||||
|
||||
| 方案 | 做法 | 优点 | 缺点 |
|
||||
| --- | --- | --- | --- |
|
||||
| A(推荐) | 公共工具函数 + 公共附件/预览组件加按钮 | 一处覆盖列表/表单/详情多数场景;与下载同发现路径 | 少数自建附件 UI 需二次补齐 |
|
||||
| B | 各业务页单独加复制 | 可控精细 | 遗漏多、风格易漂 |
|
||||
| C | 仅右键 / 快捷键 | UI 干净 | B 端发现差,触控与 H5 弱 |
|
||||
|
||||
**采用方案 A。**
|
||||
|
||||
## 范围
|
||||
|
||||
**包含**
|
||||
|
||||
- `web-admin`:剪贴板工具(图片 Blob → `navigator.clipboard.write`)
|
||||
- 复用现有 `fetchAttachmentBlob`(`download-attachment.ts`)取内容
|
||||
- 公共组件入口:
|
||||
- `attachment-upload-field`:卡片操作区 / compact 下载旁;图片预览工具栏
|
||||
- `attachment-preview-dialog`:图片预览工具栏
|
||||
- 主要列表附件单元格(如 `pl-*-attachment-cell`、证书列表单元格等已有下载角标处)按同一模式补「复制」(仅图片显示图片复制;非图片可选复制链接或隐藏)
|
||||
- 成功 / 失败 `ElMessage` 提示;安全上下文或权限失败时明确提示
|
||||
|
||||
**不包含**
|
||||
|
||||
- `miniprogram/` 任何改动
|
||||
- 后端 API / schema 变更(沿用现有预签名下载)
|
||||
- 右键菜单、全局快捷键作为主入口
|
||||
- PDF/Office 等「复制文件本体」进剪贴板
|
||||
- 强制改造所有业务页内联重复附件 UI(优先公共组件;遗漏页可后续补)
|
||||
|
||||
## 前端设计
|
||||
|
||||
### 工具函数
|
||||
|
||||
在 `web-admin/src/utils/clipboard.ts`(或同目录新建 `copy-attachment.ts` 并由 clipboard 导出)增加:
|
||||
|
||||
- `copyImageBlobToClipboard(blob: Blob): Promise<boolean>`
|
||||
- 优先 `ClipboardItem` 写入;若类型非 `image/png`,经 canvas/`createImageBitmap` 转为 PNG 再写(兼容 JPEG 等)
|
||||
- 无 Clipboard API / 非安全上下文 / 权限拒绝 → 返回 false
|
||||
- `copyAttachmentImageToClipboard(file, options?): Promise<boolean>`
|
||||
- 内部:`detectAttachmentPreviewKind` 非 image 则失败或降级复制 URL 文本(由调用方决定文案)
|
||||
- `fetchAttachmentBlob` → `copyImageBlobToClipboard`
|
||||
|
||||
非图片「复制链接」可复用已有 `copyTextToClipboard`。
|
||||
|
||||
### UI 放置
|
||||
|
||||
1. **附件卡片**(`attachment-upload-field`):`下载` 旁增加复制图标按钮;仅当判定为图片时执行图片复制,其它类型可复制链接或只显示下载。
|
||||
2. **预览弹窗工具栏**(upload-field 内嵌预览 + `attachment-preview-dialog`):在重置等按钮后增加「复制」;仅 `kind === 'image'` 时显示。
|
||||
3. **列表缩略图角标**:已有下载角标的单元格,图片项增加复制角标或与下载并列,点击 `@click.stop`,避免触发行预览。
|
||||
|
||||
按钮样式、图标遵循 Fresh Mint / 现有 `action-btn` 与预览工具栏按钮规范(图标 + title 或短文案「复制」)。
|
||||
|
||||
### 数据与网络
|
||||
|
||||
- 剪贴板需要 Blob,不能只拷 DOM。
|
||||
- 使用现有预签名下载路径取 Blob;常命中浏览器缓存,用户体感可接受。
|
||||
- 不新增后端接口。
|
||||
|
||||
### 兼容与降级
|
||||
|
||||
| 情况 | 行为 |
|
||||
| --- | --- |
|
||||
| 现代桌面 Chrome / Edge | 图片写入剪贴板,成功提示「已复制到剪贴板」 |
|
||||
| 权限 / 非 HTTPS / 旧浏览器 | 失败提示「复制失败,请允许剪贴板权限或改用下载」;可选降级复制图片 URL |
|
||||
| 移动 H5(同组件) | 尽力而为;失败走同一提示,不单独做小程序方案 |
|
||||
|
||||
## 验收条件
|
||||
|
||||
1. Web 管理端:在公共附件卡、图片预览弹窗可见「复制」,点击后可将图片粘贴到本机支持图片剪贴板的应用(如预览/Word/微信桌面,视 OS 而定)。
|
||||
2. 非图片附件:不出现误导性的「复制图片」成功;链接复制或仅下载,行为与提示一致。
|
||||
3. 小程序目录无本次改动。
|
||||
4. 无后端变更;相关前端 lint / typecheck 通过(按实施计划执行)。
|
||||
|
||||
## 风险与后续
|
||||
|
||||
- MinIO / 预签名 CORS 若阻止 `fetch` Blob,复制会失败(下载走 `<a download>` 可能仍可用)→ 失败提示引导改用下载;必要时再评估代理拉取。
|
||||
- 少数未走公共组件的页面可能暂无按钮 → 后续按反馈补齐。
|
||||
Reference in new issue
Block a user