docs: add design for contract print dialog Word export
Capture the agreed frontend HTML-to-DOCX approach for CRM contract print dialog. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
f43ef91d70
commit
32f51274eb
1 file changed
+112
@@ -0,0 +1,112 @@
|
||||
# 合同管理:打印弹窗「生成 Word」设计
|
||||
|
||||
日期:2026-09-05
|
||||
范围:`web-admin` 合同管理打印弹窗(`/#/crm/contract` 及相关详情入口)
|
||||
状态:已评审(方案 1 前端 HTML→DOCX,用户确认继续)
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
合同管理打印弹窗已支持富文本预览/编辑、打印与「生成 PDF」。业务希望增加「生成 Word」,下载可编辑的 `.docx`,方便改完后再发给客户。
|
||||
|
||||
目标:
|
||||
|
||||
- 与当前打印预览内容同源(占位符已替换)
|
||||
- 正文、表格可在 Word 中继续编辑
|
||||
- 红章跟随弹窗「显示/隐藏红章」开关
|
||||
- 水印 / Logo 规则与现有「生成 PDF」一致
|
||||
|
||||
## 2. 采用方案
|
||||
|
||||
**方案 1**:前端将打印弹窗当前 HTML 转为 DOCX 并下载。
|
||||
|
||||
库选型:`@turbodocx/html-to-docx`(浏览器可用,表格/图片支持相对成熟),下载沿用已有 `file-saver`。
|
||||
|
||||
不采用:
|
||||
|
||||
- 方案 2(后端 Pandoc / LibreOffice 转换)——需新接口与部署依赖;合同导出现为纯前端,本期成本过高
|
||||
- 方案 3(将 PDF 截图嵌入 Word)——几乎不可编辑,与「改完再发给客户」冲突
|
||||
|
||||
## 3. 入口与交互
|
||||
|
||||
### 3.1 位置
|
||||
|
||||
合同管理打印弹窗底栏,「生成 PDF」旁增加「生成 Word」。
|
||||
|
||||
需同步两处入口:
|
||||
|
||||
- `web-admin/src/views/crm/contract/components/ContractDetailDialog.vue`
|
||||
- `web-admin/src/views/crm/contract/detail.vue`
|
||||
|
||||
按钮须带前置 `el-icon`(与现有打印 / PDF 一致,例如 Document 类图标)。
|
||||
|
||||
### 3.2 行为
|
||||
|
||||
1. 点击「生成 Word」→ loading(独立 `wordGenerating`,不与 PDF loading 互相覆盖)
|
||||
2. 成功 → 下载 `.docx`
|
||||
3. 文件名:与 PDF 同规则——`{合同名称或合同编号}合同.docx`,非法文件名字符替换为 `-`
|
||||
4. 失败 → 提示「生成 Word 失败,请重试」,不关闭打印弹窗
|
||||
5. 不影响既有「打印」「生成 PDF」行为
|
||||
|
||||
## 4. 导出链路
|
||||
|
||||
```
|
||||
打印弹窗当前 HTML(contractContent)
|
||||
→ 按需刷新占位符(与 PDF 同源:getContractDetail + replacePlaceholders)
|
||||
→ 红章:直接使用弹窗当前 HTML(开=已含印章图;关=已 strip)
|
||||
→ 水印 / Logo:按合同号供方编码规则(与 PDF 一致)
|
||||
→ 预处理:相对图片路径转绝对 URL;SX 水印改为可进 Word 的 <img>(不用 CSS background)
|
||||
→ @turbodocx/html-to-docx → Blob → file-saver 下载
|
||||
```
|
||||
|
||||
无后端接口变更。
|
||||
|
||||
## 5. 红章 / 水印 / Logo 约定
|
||||
|
||||
### 5.1 红章
|
||||
|
||||
- 与弹窗开关一致:显示则导出含印章图;隐藏则不含
|
||||
- 导出前将印章等图片的相对 `src` 转为绝对 URL,尽量保留宽高
|
||||
- 已知局限:Word 对 `position: absolute` 支持弱,印章可能不完全叠在签字区正中,允许用户在 Word 中微调
|
||||
|
||||
### 5.2 水印与 Logo(对齐 PDF)
|
||||
|
||||
- 从合同编号解析供方编码(`^([A-Z]+)/X-JT`);解析不到默认 `SX`
|
||||
- 供方为 `SX`:导出前在文档内容区插入半透明水印图(`/watermask.jpg` 绝对 URL,居中、约半宽、低透明度,尽量贴近 PDF 观感);不依赖 CSS `background-image` / `::before`
|
||||
- 非 `SX`:去掉 Logo(与 PDF 一致的匹配规则),不加水印
|
||||
|
||||
## 6. 改动范围
|
||||
|
||||
| 文件 / 依赖 | 变更 |
|
||||
|---|---|
|
||||
| `web-admin/package.json` | 增加 `@turbodocx/html-to-docx` |
|
||||
| `web-admin/src/utils/crm/contract-html-to-docx.ts`(新建) | 组装导出 HTML(水印/Logo 预处理、绝对 URL)并调用库生成 Blob |
|
||||
| `ContractDetailDialog.vue` | 底栏按钮 + `handleGenerateWordFromDialog` |
|
||||
| `detail.vue` | 底栏按钮 + 对应 handler(复用工具函数) |
|
||||
|
||||
后端:不改。报价单、调价函、运输单据等其它打印弹窗:本期不做。
|
||||
|
||||
## 7. 非目标
|
||||
|
||||
- 不追求与打印预览像素级一致
|
||||
- 不做服务端 Word 生成或落库
|
||||
- 不改合同模板存库结构
|
||||
- 不扩展到报价单等其它模块
|
||||
- 不把 Word 生成做成截图式不可编辑文档
|
||||
|
||||
## 8. 验收
|
||||
|
||||
| 场景 | 期望 |
|
||||
|---|---|
|
||||
| 按钮入口 | 合同打印弹窗底栏有「生成 Word」,与「生成 PDF」同级;两处入口均有 |
|
||||
| 下载 | 可下载可编辑 `.docx`;正文/表格可改 |
|
||||
| 红章开 | 导出 Word 含印章图 |
|
||||
| 红章关 | 导出 Word 不含印章图 |
|
||||
| SX 合同 | 含水印;保留 Logo 规则与 PDF 一致 |
|
||||
| 非 SX 合同 | 无水印;Logo 已去除 |
|
||||
| 失败 | 有错误提示;弹窗仍可继续打印 / 生成 PDF |
|
||||
| 回归 | 既有打印、生成 PDF 行为不变 |
|
||||
|
||||
## 9. 已知局限(可接受)
|
||||
|
||||
- 印章叠放位置、水印跨页表现、复杂表格宽度可能需在 Word 中微调
|
||||
- 上述局限符合「下载后修改再发给客户」的用途,不作为阻塞项
|
||||
Reference in new issue
Block a user