From 433eb5d113837b9778363c7fb42a2d2a6ef33fa5 Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Thu, 13 Aug 2026 10:47:54 +0800 Subject: [PATCH] docs: add mobile OA print-to-PDF download design for WeChat Co-authored-by: Cursor --- ...-13-mobile-oa-print-pdf-download-design.md | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-13-mobile-oa-print-pdf-download-design.md diff --git a/docs/superpowers/specs/2026-08-13-mobile-oa-print-pdf-download-design.md b/docs/superpowers/specs/2026-08-13-mobile-oa-print-pdf-download-design.md new file mode 100644 index 00000000..5b71a3c5 --- /dev/null +++ b/docs/superpowers/specs/2026-08-13-mobile-oa-print-pdf-download-design.md @@ -0,0 +1,100 @@ +# 移动端 OA「打印」改为下载 PDF(微信预览) + +> 日期:2026-08-13 +> 范围:`mobile-oa-h5`(打印导出)+ `mobile-h5`(微信宿主文档预览) +> 状态:已确认 +> 关联:`docs/superpowers/specs/2026-07-15-oa-approval-print-pdf-design.md`(web 端 PDF 权威版式) + +## 1. 目标 + +将移动端 OA 详情「打印」与列表长按「打印」(`autoPrint=1`)从当前的 `window.print()`(微信 web-view 内基本不可用)改为与 **web-admin 一致**:前端用钉钉风格模板生成 PDF,并在微信内打开**系统文档预览**(可转发 /「用其他应用打开」保存)。 + +主运行环境:微信小程序内 `mobile-h5` → `web-view` → `mobile-oa-h5`。 + +## 2. 非目标 + +- 不新增后端 PDF 渲染引擎(本期仍前端生成) +- 不改 web-admin 打印实现 +- 关联审批嵌套块本期仍可用「已关联 N 条」摘要(不对齐 web 完整嵌套打印树);若需对齐另开变更 +- 不导出附件二进制;附件行仍展示 URL / 文件名文本(与 web 一致) + +## 3. 方案选型 + +采用 **前端 html2canvas + jspdf → 上传附件存储 → 宿主 `openDocument` 预览**: + +| 步骤 | 负责端 | 说明 | +|------|--------|------| +| 1 | `mobile-oa-h5` | 组装 print model,离屏渲染打印 DOM | +| 2 | `mobile-oa-h5` | `html2canvas` + `jspdf` 生成 PDF Blob(算法对齐 web `oa-approval-print.ts`) | +| 3 | `mobile-oa-h5` | `uploadAttachment` → MinIO(现有 `/web/admin/attachment/upload`,`folder=oa-approval`) | +| 4 | `mobile-oa-h5` | `wx.miniProgram.navigateTo` 打开宿主预览页(带文件 URL + 文件名) | +| 5 | `mobile-h5` | `uni.downloadFile` → `uni.openDocument({ showMenu: true })` | + +不采用:纯 `pdf.save()` / `a[download]`(微信不可靠);后端生成 PDF(版式双端维护成本高)。 + +微信外(普通手机浏览器 / H5 iframe):可回退为 `jspdf` 的 `save()` 直接下载,无需跳转宿主。 + +## 4. 交互 + +| 入口 | 行为 | +|------|------| +| 详情底栏「打印」 | loading → 生成 → 上传 → 跳转预览;失败 toast,留在详情 | +| 列表长按「打印」→ `autoPrint=1` | 详情加载完成后自动走同一导出链路 | + +按钮:导出过程中 `printing` loading,防重复点击。 + +文件名(与 web 一致):`{发起人姓名}提交的{流程名称}.pdf`;缺省用「用户」/「审批单」;非法路径字符替换为 `_`。 + +预览页:打开后自动下载并调起系统预览;失败 toast。**预览调起成功后自动 `navigateBack`** 回详情 web-view,避免预览页在导航栈堆积;用户从系统预览返回后仍在详情。 + +## 5. PDF 版式(对齐 web) + +权威:web `OaApprovalPrintSheet` + `oa-approval-print.ts` / `2026-07-15-oa-approval-print-pdf-design.md`。 + +结构自上而下: + +1. 标题(`appName` 优先) +2. 元信息:公司名固定 `安徽中科兴皖医学研究有限公司` + `创建时间:YYYY-MM-DD` +3. 主表(标签 | 值):审批编号、创建人、创建人部门 + 表单字段 + 审批流程行 +4. 右上角钉钉风印章(状态映射与 web / `resolveStamp` 一致) +5. 页脚:打印时间、打印人 +6. 水印:打印人姓名斜向淡色铺底 +7. 页码:`第 N 页`(canvas 绘制中文,避免 jsPDF 内置字体乱码) + +纸张:A4 竖向;切片与略超一页容差对齐 web(`EPS_MM ≈ 1.5`)。 + +实现方式:可继续用现有 `buildPrintHtml` 字符串模板渲染到离屏 iframe/div,再 `html2canvas`;CSS/印章 DOM 须向 web 打印页收敛,避免与详情页 72px 印章混用两套视觉。 + +## 6. 微信通信约束 + +- `wx.miniProgram.postMessage` **不会立即送达**宿主(多在后退/销毁时触发),**不能**靠 postMessage 传 PDF。 +- 大文件不能塞进 `navigateTo` query;必须先上传,query 只传 **HTTPS 文件 URL + 文件名**。 +- 预签名:优先 `fetchAttachmentDownloadUrl` 得到带 `Content-Disposition` 的地址再下载;失败则回退直连上传返回的 `url`。 + +## 7. 主要改动文件 + +| 路径 | 职责 | +|------|------| +| `mobile-oa-h5/package.json` | 增加依赖 `html2canvas`、`jspdf` | +| `mobile-oa-h5/src/oa/print/exportOaApprovalPdf.js` | 改为 canvas→PDF;微信上传+跳转;浏览器 `save` 回退 | +| `mobile-oa-h5/src/views/OaDetail.vue` | 打印成功/失败文案对齐「导出 PDF」;去掉「系统打印不可用」类提示 | +| `mobile-oa-h5/src/api/oa.js` | 复用已有 `uploadAttachment` / `fetchAttachmentDownloadUrl` | +| `mobile-h5/pages/oa/pdf-preview/index.vue` | 新建:download + openDocument | +| `mobile-h5/pages.json` | 注册 `pages/oa/pdf-preview/index` | + +## 8. 错误处理 + +| 场景 | 表现 | +|------|------| +| 无详情 / 生成失败 | toast,不跳转 | +| 上传失败 | toast,不跳转 | +| 非微信且无 `save` 能力 | toast | +| 宿主 download / openDocument 失败 | 预览页 toast | + +## 9. 验收 + +1. 微信小程序:详情点「打印」→ 出现系统 PDF 预览,可转发 / 用其他应用打开。 +2. 列表长按「打印」:进入详情后自动导出并预览。 +3. PDF 视觉与 web「打印」导出大体一致(标题、表、印章、水印、页脚、页码)。 +4. 普通浏览器打开 `mobile-oa-h5`:点打印直接下载 PDF 文件。 +5. 导出失败时详情页不关闭,可重试。