# 模板填充与预览完整流程（基于 UNO Command 高亮）
## 阶段 1：打开模板（高亮占位符）
| 角色 | 动作 | API/操作详情 |
| :--- | :--- | :--- |
| **前端** | 用户点击"打开模板" | 发起请求。 |
| **后端** | `POST /api/docxtemplater/create-temp-template` | **请求体示例：** `{ templateId: 'templates/合同模板.docx' }` |
| **后端** | 复制和处理文件 | 1. 从 MinIO 复制文件：`templates/合同模板.docx` → `temp/合同模板-temp-{timestamp}.docx`。 2. 提取占位符（例如：`{姓名}`，`{年龄}`）。 |
| **后端** | 返回响应 | **响应体示例：** `{ tempFileId: 'temp/合同模板-temp-1763460000.docx', placeholders: [{ name: '姓名', label: '姓名', ... }, { name: '年龄', label: '年龄', ... }] }` |
| **前端** | 渲染 CollaboraViewer | **组件配置：** `<CollaboraViewer fileId="temp/合同模板-temp-1763460000.docx" mode="edit" highlightTexts={['{姓名}', '{年龄}']} />` |
| **前端** | `useCollaboraHighlight` Hook | 1. 监听 `Document_Loaded` 事件。2. 遍历 `highlightTexts`，依次发送 UNO Command 进行高亮。3. 高亮完成后发送 `.uno:Save` 命令保存修改。 |


### 🔍 前端高亮 UNO Command 示例 (针对 `{姓名}`):
```plain
// 1. 搜索文本
{
  MessageId: "Send_UNO_Command",
  Values: {
    Command: ".uno:ExecuteSearch",
    Args: { SearchItem: { value: "{姓名}", type: "string" } }
  }
}
// 2. 设置背景色（黄色：16776960）
{
  MessageId: "Send_UNO_Command",
  Values: {
    Command: ".uno:CharBackColor",
    Args: { BackColor: { value: 16776960, type: "long" } }
  }
}
// 3. 保存修改（重要：将高亮持久化到 temp 文件）
{
  MessageId: "Send_UNO_Command",
  Values: { Command: ".uno:Save" }
}
```

---

## 阶段 2：填充表单（高亮填充值）
| 角色 | 动作 | API/操作详情 |
| :--- | :--- | :--- |
| **前端** | 用户填写并提交表单 | 发起请求。 |
| **后端** | `POST /api/docxtemplater/fill` | **请求体示例：** `{ templateId: 'templates/合同模板.docx', data: { 姓名: '张三', 年龄: '25' }, outputName: 'filled_合同_张三.docx' }` |
| **后端** | 填充和复制文件 | 1. `docxtemplater` 填充源文件。2. 保存**正式文件**到 MinIO：`contracts/filled_合同_张三_1763460000.docx` (✅)。3. 复制正式文件到 temp：`temp/filled_合同_张三_1763460000-temp.docx`。 |
| **后端** | 返回响应 | **响应体示例：** `{ fileId: 'contracts/filled_合同_张三_1763460000.docx', tempFileId: 'temp/filled_合同_张三_1763460000-temp.docx', filledValues: ['张三', '25'] }` |
| **前端** | 渲染 CollaboraViewer | **组件配置：** `<CollaboraViewer fileId="temp/filled_合同_张三_1763460000-temp.docx" mode="edit" highlightTexts={['张三', '25']} />` |
| **前端** | `useCollaboraHighlight` Hook | 同样使用该 Hook 监听 `Document_Loaded`，遍历 `filledValues` 进行高亮，并发送 `.uno:Save` 命令保存高亮状态到新的临时文件。 |


---

## 阶段 3：清理（删除临时文件）
| 角色 | 动作 | API/操作详情 |
| :--- | :--- | :--- |
| **前端** | 用户关闭页面 | 发起请求。 |
| **后端** | `DELETE /api/docxtemplater/cleanup-temp` | **请求体示例：** `{ tempFileIds: ['temp/合同模板-temp-1763460000.docx', 'temp/filled_合同_张三_1763460000-temp.docx'] }` |
| **后端** | 删除文件 | 遍历并从 MinIO 删除请求中列出的所有临时文件。 |


---

## 总结：核心优势和变动
+ **核心优势：** 利用前端 UNO Command 进行高亮，避免了复杂的后端 DOCX XML 操作，同时通过 Collabora 的 `.uno:Save` 命令确保高亮状态持久化到临时文件中，不污染源文件和最终正式文件。
+ **模式变动：** CollaboraViewer 必须设置为 `mode="edit"` 才能执行 UNO Command 和保存操作，这使得高亮能够生效。虽然用户在此模式下可以看到编辑界面，但由于文件位于临时路径，且最终用户下载的是干净的正式文件，该风险可控。

