diff --git a/plugins/pdf-office-workbench/CHANGELOG.md b/plugins/pdf-office-workbench/CHANGELOG.md
index d92c66b98..d3a6266cd 100644
--- a/plugins/pdf-office-workbench/CHANGELOG.md
+++ b/plugins/pdf-office-workbench/CHANGELOG.md
@@ -1,5 +1,10 @@
# Changelog
+## v0.2.1 - 2026-09-01
+
+- 适配 ZTools 3.2:合并、拆分和重命名生成的 PDF 可直接拖到外部应用,并采用 5 分钟、单次、精确真实路径授权。
+- 新增 2.4.0 宿主版本门禁;低版本或真实宿主版本不可识别时在业务事件绑定前显示升级提示,2.4–3.1 保留打开所在文件夹流程。
+
## v0.2.0
- 接入真实 PDF 文件读写:选择、合并、按页拆分和输出结果。
diff --git a/plugins/pdf-office-workbench/README.md b/plugins/pdf-office-workbench/README.md
index a95ffcb3a..7018d01bf 100644
--- a/plugins/pdf-office-workbench/README.md
+++ b/plugins/pdf-office-workbench/README.md
@@ -4,6 +4,13 @@
当前范围聚焦 PDF 与票据流程;Word、Excel、PPT 的原生编辑/转换仍属于后续能力,不在本版本中宣称支持。
+## ZTools 兼容性
+
+- ZTools 3.2.0:生成的 PDF 可直接拖到外部应用。
+- 外拖授权仅覆盖最近 5 分钟内由合并、拆分或重命名成功产生的普通 PDF,使用一次后立即失效。
+- ZTools 2.4–3.1:保留打开所在文件夹的结果操作。
+- 低于 2.4.0,或真实 ZTools 宿主无法提供可比较版本号:显示升级提示。仅未注入 `window.ztools` 的浏览器开发预览放行。
+
## 首批能力
- 选择多个 PDF 并真实合并为一个 PDF。
diff --git a/plugins/pdf-office-workbench/index.html b/plugins/pdf-office-workbench/index.html
index b6b26cb76..549e83415 100644
--- a/plugins/pdf-office-workbench/index.html
+++ b/plugins/pdf-office-workbench/index.html
@@ -123,7 +123,16 @@
文件队列
import { extractInvoiceFields } from './src/core/index.mjs';
const services = window.services;
- const state = { files: [], lastPath: '' };
+ const compatibility = !window.ztools
+ ? { supported: true }
+ : (() => {
+ try { return services?.hostCompatibility?.() || { supported: false }; }
+ catch (_) { return { supported: false }; }
+ })();
+ if (!compatibility.supported) {
+ document.querySelector('main').innerHTML = '需要升级 ZTools
当前 ZTools 版本过低或无法识别(最低支持 2.4.0)。为了获得更完整、稳定的体验,请升级后再使用 PDF 办公工坊。
';
+ } else {
+ const state = { files: [], lastPath: '', outputPaths: [] };
const $ = (selector) => document.querySelector(selector);
const output = $('#output');
const status = $('#status');
@@ -146,6 +155,11 @@ 文件队列
status.className = `status${isError ? ' error' : ''}`;
}
+ function outputPaths(value) {
+ const entries = Array.isArray(value) ? value : [value];
+ return entries.map((entry) => entry?.path).filter((entry) => typeof entry === 'string' && entry.length > 0);
+ }
+
function render() {
const files = $('#files');
$('#summary').textContent = state.files.length
@@ -184,6 +198,7 @@ 文件队列
try {
const result = await task();
state.lastPath = Array.isArray(result) ? result.at(-1)?.path || '' : result?.path || '';
+ state.outputPaths = outputPaths(result);
if (state.lastPath) $('#open-result').disabled = false;
show(result);
setStatus('完成');
@@ -214,9 +229,15 @@ 文件队列
});
$('#invoice').addEventListener('click', () => { show(extractInvoiceFields($('#invoice-input').value)); setStatus('字段提取完成'); });
$('#open-result').addEventListener('click', () => state.lastPath && services.reveal(state.lastPath));
+ $('#open-result').draggable = services.canStartDrag?.() || false;
+ $('#open-result').addEventListener('dragstart', (event) => {
+ event.preventDefault();
+ if (state.outputPaths.length) services.startDrag(state.outputPaths).catch((error) => setStatus(error?.message || String(error), true));
+ });
window.addEventListener('pdf-office-enter', event => addFiles(event.detail.files));
render();
+ }