实现Excel转PDF手动转换接口

This commit is contained in:
andy
2026-07-16 18:25:51 +07:00
parent ed37d5f955
commit 8d53b72363
30 changed files with 1995 additions and 52 deletions

View File

@@ -18,6 +18,7 @@
- Reservation OPERA 模拟骨架已确认任务固定生成两条模拟操作支持执行、失败重试、attempt 记录和任务审计列表。
- SuperAgent 查询上下文接口 1、2支持 HMAC 鉴权的订单上下文查询和对象详情查询。
- Debug EML 上传到 SuperAgent 调试链路:受控上传 `.eml`、转存阿里云 OSS、写入 SourceMessage Inbox、调用 SuperAgent Open API 并返回调试结果。
- Excel 转 PDF 手动上传接口:受控上传 `.xls` / `.xlsx`,通过 LibreOffice headless 转 PDF 后上传阿里云 OSS 并返回 PDF URL。
- 登录权限底座:支持用户名密码登录、登出、当前用户上下文、数据库 session token、可访问酒店、权限码和可见菜单。
- 系统管理后台 V1支持用户、角色权限、菜单、酒店和管理操作审计的受控维护接口与前端页面。
@@ -34,6 +35,7 @@
- 现有业务接口强制登录和强制权限拦截。
- 业务审计 actor 全量迁移到当前登录用户。
- Debug EML 上传链路不属于生产普通业务页面能力,生产默认关闭;即使已有登录权限,也不要开放给普通用户。
- Excel 转 PDF 当前只完成手动上传后端接口;邮件附件自动转换、持久化转换任务和 worker 尚未实现。生产默认关闭,启用前必须确认 LibreOffice、字体、OSS、临时目录和访问口令。
## 2. 上线前必须确认
@@ -91,17 +93,13 @@
### 3.3 SourceMessage
| 变量 | 是否 Secret | 上线注意事项 |
| --- | --- | --- |
| `SOURCE_MESSAGE_DEV_ORIGINAL_READ_ACCESS_KEY` | 是 | dev 原文读取临时访问 key。未配置时可兜底使用旧通用变量。 |
| `SOURCE_MESSAGE_TEST_ORIGINAL_READ_ACCESS_KEY` | 是 | test 原文读取临时访问 key。未配置时可兜底使用旧通用变量。 |
| `SOURCE_MESSAGE_PROD_ORIGINAL_READ_ACCESS_KEY` | 是 | prod 原文读取临时访问 key。未配置时原文读取默认关闭。 |
| `SOURCE_MESSAGE_ORIGINAL_READ_ACCESS_KEY` | 是 | 旧通用原文读取 key仅作为兼容兜底。 |
SourceMessage 原文和邮件会话完整正文已迁移到登录权限体系:
注意:
- 原文读取 key 不是用户体系,后续接入正式登录和角色权限后应替换
- 任何能读取原文的调用都必须有调用方和访问场景,并写入审计表
- 前端请求必须携带 `Authorization: Bearer <access_token>`
- 当前用户必须同时拥有 `SOURCE_MESSAGE_READ``SOURCE_MESSAGE_ORIGINAL_READ`
- 后端按 SourceMessage 实际所属酒店校验酒店访问权
- 后端内部写入原文读取审计actor 使用当前登录用户稳定 ID
-`SOURCE_MESSAGE_DEV_ORIGINAL_READ_ACCESS_KEY``SOURCE_MESSAGE_TEST_ORIGINAL_READ_ACCESS_KEY``SOURCE_MESSAGE_PROD_ORIGINAL_READ_ACCESS_KEY``SOURCE_MESSAGE_ORIGINAL_READ_ACCESS_KEY` 已废弃,不再作为部署必备 Secret。
### 3.4 AgentBus
@@ -201,6 +199,31 @@
- Debug EML 和 AgentBus 自动分发复用同一个 SuperAgent Open API SSE 稳定客户端;上线前必须验证 `run.completed + end + final answer` 严格成功条件和 EOF 后 `/events` 恢复。
- 当前共享 Open API client 会自动携带临时 CSRF double-submit header / cookie如果测试机仍返回 `CSRF token missing`,优先检查部署包版本和反向代理是否转发 `X-CSRF-Token``Cookie`
### 3.7 Excel 转 PDF / LibreOffice
| 变量 | 是否 Secret | 上线注意事项 |
| --- | --- | --- |
| `DOCUMENT_CONVERSION_DEV_ENABLED` / `DOCUMENT_CONVERSION_TEST_ENABLED` / `DOCUMENT_CONVERSION_PROD_ENABLED` | 否 | 是否启用 Excel 转 PDF 手动上传接口prod 默认必须保持 `false`,确认运行环境后再开启。 |
| `DOCUMENT_CONVERSION_DEV_ACCESS_KEY` / `DOCUMENT_CONVERSION_TEST_ACCESS_KEY` / `DOCUMENT_CONVERSION_PROD_ACCESS_KEY` | 是 | 文件转换访问口令;未配置时可兜底 `DOCUMENT_CONVERSION_ACCESS_KEY`。不得进入前端源码、镜像、普通日志或文档真实值。 |
| `DOCUMENT_CONVERSION_SOFFICE_PATH` / `DOCUMENT_CONVERSION_*_SOFFICE_PATH` | 否 | `soffice` 可执行文件路径,默认 `soffice`。测试机和生产机路径可能不同。 |
| `DOCUMENT_CONVERSION_TEMP_DIR` / `DOCUMENT_CONVERSION_*_TEMP_DIR` | 否 | 文件转换临时目录。后端运行用户必须有读写权限,目录应有系统清理策略。 |
| `DOCUMENT_CONVERSION_MAX_FILE_BYTES` / `DOCUMENT_CONVERSION_*_MAX_FILE_BYTES` | 否 | 单个 Excel 文件大小上限,默认 `20971520`。 |
| `DOCUMENT_CONVERSION_TIMEOUT_SECONDS` / `DOCUMENT_CONVERSION_*_TIMEOUT_SECONDS` | 否 | 单次 LibreOffice 转换超时秒数,默认 `60`。 |
| `DOCUMENT_CONVERSION_MAX_CONCURRENT` / `DOCUMENT_CONVERSION_*_MAX_CONCURRENT` | 否 | 最大并发转换数,默认 `2`。不要盲目调大,避免 LibreOffice 进程拖垮后端。 |
| `DOCUMENT_CONVERSION_OUTPUT_OSS_PREFIX` / `DOCUMENT_CONVERSION_*_OUTPUT_OSS_PREFIX` | 否 | PDF 输出 OSS 前缀,默认 `document-conversions/excel-to-pdf/`。 |
| `DOCUMENT_CONVERSION_WORKER_ENABLED` / `DOCUMENT_CONVERSION_*_WORKER_ENABLED` | 否 | 自动转换 worker 预留开关CP2 不使用,默认关闭。 |
| `DOCUMENT_CONVERSION_MULTIPART_MAX_FILE_BYTES` / `DOCUMENT_CONVERSION_MULTIPART_MAX_REQUEST_BYTES` | 否 | Spring multipart 框架上限;默认分别为 `25165824` / `29360128`,应高于业务 `MAX_FILE_BYTES`,否则请求会在进入 Controller 前被框架拦截。 |
注意:
- 服务器必须安装 LibreOffice / LibreOffice Calc并确认后端运行用户可以执行 `soffice`
- 服务器必须安装中文、英文、泰文等业务字体;缺少字体会导致 PDF 乱码、缺字或分页变化。
- 每次转换会创建独立临时目录和 LibreOffice profile正常结束、失败或超时后后端会清理但仍建议运维配置临时目录兜底清理。
- 当前接口路径为 `POST /api/system/document-conversions/excel-to-pdf`Header 为 `X-TH-Hotel-Document-Conversion-Key`
- 当前接口只支持 `.xls` / `.xlsx`,不支持 `.xlsm`;后端会校验扩展名和文件头,改后缀的非 Excel 文件会返回受控错误。
- PDF 上传到阿里云 OSS返回 `pdf_url``object_key``pdf_file_name``pdf_size_bytes``duration_millis`
- CP2 不落库,不提供转换历史查询;如果需要自动处理邮件附件,应先进入 M008 后续持久化任务和 worker checkpoint。
## 4. 数据库上线注意事项
当前 SourceMessage 相关 migration
@@ -308,9 +331,8 @@ SourceMessage 普通列表和普通详情只能返回安全摘要:
```text
GET /api/source-messages/{id}/original
Header: X-TH-Hotel-Source-Original-Read-Key
Header: X-TH-Hotel-Actor
Header: X-TH-Hotel-Access-Scene
Header: Authorization: Bearer <access_token>
Required permission: SOURCE_MESSAGE_READ + SOURCE_MESSAGE_ORIGINAL_READ
```
前端展示 `htmlBody` 前必须 sanitize。后端返回 `htmlSanitizeRequired=true` 是提醒前端不要直接信任 HTML。
@@ -418,15 +440,13 @@ GET /api/source-messages/{id}/original
```text
AGENTBUS_PROBE_ENABLED=false
AGENTBUS_CAPTURE_ENABLED=false
SOURCE_MESSAGE_PROD_ORIGINAL_READ_ACCESS_KEY=
SOURCE_MESSAGE_ORIGINAL_READ_ACCESS_KEY=
```
说明:
- 关闭 `AGENTBUS_PROBE_ENABLED` 可以停止 WebSocket 入站连接。
- 关闭 `AGENTBUS_CAPTURE_ENABLED` 可以保留连接但暂停写入 Inbox。
- 清空当前 profile 对应的 `SOURCE_MESSAGE_*_ORIGINAL_READ_ACCESS_KEY`,且不配置旧通用变量,可以关闭原文读取接口
- 如需临时关闭前端邮件原文 / 会话完整正文读取,应从相关角色移除 `SOURCE_MESSAGE_ORIGINAL_READ``SOURCE_MESSAGE_READ`,或禁用对应用户入口;旧原文读取 key 已废弃,不能作为关闭开关
数据库回滚注意: