@agile-team/mach-report 2.3.2 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +40 -5
  2. package/dist/ReportPreview-CL9J9MEE.js +1907 -0
  3. package/dist/ReportPreview-DJvv3h8m.cjs +6 -0
  4. package/dist/grid-geometry-BNIvw52m.cjs +1 -0
  5. package/dist/{grid-geometry-Dw7BlENr.js → grid-geometry-C8hGoe9o.js} +10 -10
  6. package/dist/index.cjs +5 -5
  7. package/dist/index.d.cts +74 -0
  8. package/dist/index.d.ts +74 -0
  9. package/dist/index.js +946 -782
  10. package/dist/number-format-BA_KwrZe.js +55 -0
  11. package/dist/number-format-CZ2T_5kF.cjs +1 -0
  12. package/dist/pdf.cjs +1 -1
  13. package/dist/pdf.d.cts +6 -0
  14. package/dist/pdf.d.ts +6 -0
  15. package/dist/pdf.js +2 -2
  16. package/dist/{plugin-2lqgTX26.cjs → plugin-BkK2mm_p.cjs} +1 -1
  17. package/dist/{plugin-5R00MJQs.js → plugin-DRnvIbdP.js} +1 -1
  18. package/dist/render-plan-CCTL4F9v.cjs +1 -0
  19. package/dist/{render-plan-I9AHvQv7.js → render-plan-CXBWRog4.js} +12 -7
  20. package/dist/style.css +1 -1
  21. package/dist/vue/async.d.cts +598 -1
  22. package/dist/vue/async.d.ts +598 -1
  23. package/dist/vue/index.d.cts +820 -10
  24. package/dist/vue/index.d.ts +820 -10
  25. package/dist/vue-async.cjs +1 -1
  26. package/dist/vue-async.js +3 -3
  27. package/dist/vue.cjs +1 -1
  28. package/dist/vue.js +96 -73
  29. package/dist/xlsx.cjs +24 -24
  30. package/dist/xlsx.d.cts +209 -0
  31. package/dist/xlsx.d.ts +209 -0
  32. package/dist/xlsx.js +9805 -9284
  33. package/package.json +1 -1
  34. package/dist/ReportPreview-B-mwUSk9.cjs +0 -6
  35. package/dist/ReportPreview-DKjr4cwO.js +0 -1688
  36. package/dist/defaults-D4o0NCLo.js +0 -9
  37. package/dist/defaults-DOO1yHwx.cjs +0 -1
  38. package/dist/grid-geometry-bkciiZ4Q.cjs +0 -1
  39. package/dist/render-plan-CfJ3wf1l.cjs +0 -1
@@ -0,0 +1,1907 @@
1
+ import { computed as F, unref as E, ref as A, onScopeDispose as Re, getCurrentScope as en, watch as _, shallowRef as ye, defineComponent as ct, nextTick as tn, openBlock as k, createElementBlock as M, createElementVNode as S, toDisplayString as R, Fragment as Fe, createCommentVNode as j, normalizeClass as de, renderList as ze, createTextVNode as st, withKeys as Ct, inject as He, provide as It, useCssVars as nn, watchEffect as kt, onMounted as rn, onUnmounted as an, normalizeStyle as ce, createBlock as on, createVNode as ln, renderSlot as sn } from "vue";
2
+ import { renderPlanToImages as un, renderPage as St, getReportCellContext as Mt, createReportCellEdit as cn, applyReportCellEdit as dn, ReportCellEditError as Dt, paginateTemplate as fn, validateRenderPlan as Ft, ReportSourceError as pn, renderPlanToCanvas as mn } from "@agile-team/mach-report";
3
+ import { c as Ot } from "./page-window-index-CIuT4BAv.js";
4
+ import { i as vn, b as gn } from "./render-plan-CXBWRog4.js";
5
+ import { b as it, c as hn, d as bn, a as wn } from "./plugin-DRnvIbdP.js";
6
+ function Bt(e) {
7
+ return e == null ? [] : Array.isArray(e) ? e.map(String).filter((t) => t !== "") : String(e).split(",").map((t) => t.trim()).filter((t) => t !== "");
8
+ }
9
+ function Yr(e) {
10
+ return Bt(e).join(",");
11
+ }
12
+ class at extends Error {
13
+ constructor(t) {
14
+ super(t), this.name = "PlanLoadError";
15
+ }
16
+ }
17
+ function Zr(e = {}) {
18
+ const { baseUrl: t = "", headers: o, credentials: r, timeoutMs: n = 3e4 } = e, a = t.replace(/\/+$/, "");
19
+ return async ({ url: l, method: c, params: m, signal: b }) => {
20
+ let f = `${a}${l}`;
21
+ if (m && Object.keys(m).length > 0) {
22
+ const w = f.indexOf("#"), I = w >= 0 ? f.slice(w) : "", P = w >= 0 ? f.slice(0, w) : f, O = P.indexOf("?"), C = O >= 0 ? P.slice(0, O) : P, D = new URLSearchParams(O >= 0 ? P.slice(O + 1) : "");
23
+ for (const [H, K] of Object.entries(m)) D.set(H, K);
24
+ f = `${C}?${D}${I}`;
25
+ }
26
+ const p = (w, I) => {
27
+ const P = new at(w);
28
+ return Object.defineProperty(P, "cause", { value: I, configurable: !0, writable: !0 }), P;
29
+ };
30
+ if (b?.aborted)
31
+ throw p(`请求已取消: ${l}`, b.reason);
32
+ const h = new AbortController();
33
+ let i;
34
+ const x = () => {
35
+ h.signal.aborted || (i = "external", h.abort(b?.reason));
36
+ };
37
+ b?.addEventListener("abort", x, { once: !0 });
38
+ const $ = setTimeout(() => {
39
+ h.signal.aborted || (i = "timeout", h.abort());
40
+ }, n);
41
+ try {
42
+ const w = await fetch(f, {
43
+ method: c.toUpperCase(),
44
+ headers: { Accept: "application/json", ...o },
45
+ credentials: r,
46
+ signal: h.signal
47
+ });
48
+ if (!w.ok)
49
+ throw new at(`HTTP ${w.status} ${l}`);
50
+ return await w.json();
51
+ } catch (w) {
52
+ throw i === "timeout" ? p(`请求超时(${n}ms): ${l}`, w) : i === "external" ? p(`请求已取消: ${l}`, w) : w instanceof at ? w : p(`请求失败(${l}): ${w instanceof Error ? w.message : String(w)}`, w);
53
+ } finally {
54
+ clearTimeout($), b?.removeEventListener("abort", x);
55
+ }
56
+ };
57
+ }
58
+ function yn(e, t, o = {}) {
59
+ const r = o.pxPerMm ?? 3.7795275590551185, n = F(() => Math.max(0, E(o.gapPx) ?? 18)), a = A(0), l = A(800), c = F(() => {
60
+ const w = e.value?.pages ?? [];
61
+ return Ot(w.map((I) => I.pageHeightMm * r), n.value);
62
+ }), m = F(() => {
63
+ let w = 0;
64
+ for (const I of e.value?.pages ?? []) w = Math.max(w, I.pageWidthMm * r);
65
+ return { w, h: c.value.totalHeightPx };
66
+ }), b = F(() => c.value.window(
67
+ l.value / t.value,
68
+ a.value / t.value,
69
+ E(o.overscan) ?? 1
70
+ )), f = F(() => {
71
+ const w = e.value;
72
+ if (!w) return [];
73
+ const { start: I, end: P } = b.value;
74
+ return w.pages.slice(I, P + 1).map((O, C) => ({ page: O, index: I + C }));
75
+ });
76
+ let p = 0, h = !1;
77
+ function i(w) {
78
+ w && (a.value = w.scrollTop, l.value = w.clientHeight || 800);
79
+ }
80
+ function x(w, I) {
81
+ return (P) => {
82
+ p || h || (p = requestAnimationFrame(() => {
83
+ if (p = 0, h || (i(P), I.value <= 0)) return;
84
+ const O = Math.max(0, P.scrollTop + 32) / t.value;
85
+ w.value = Math.min(I.value, c.value.pageAt(O) + 1);
86
+ }));
87
+ };
88
+ }
89
+ function $() {
90
+ h = !0, p && cancelAnimationFrame(p), p = 0;
91
+ }
92
+ return Re($), {
93
+ contentSize: m,
94
+ windowRange: b,
95
+ visiblePages: f,
96
+ makeScrollHandler: x,
97
+ refreshViewport: i,
98
+ pageOffsetPx: (w) => c.value.offsetAt(w),
99
+ destroy: $
100
+ };
101
+ }
102
+ function xn(e) {
103
+ const t = A(1), o = A("fit");
104
+ let r = 0;
105
+ function n() {
106
+ r && cancelAnimationFrame(r), r = 0;
107
+ }
108
+ function a() {
109
+ n(), r = requestAnimationFrame(() => {
110
+ if (r = 0, o.value !== "fit") return;
111
+ const c = e();
112
+ !c?.viewport || c.viewport.clientWidth <= 48 || !Number.isFinite(c.pageWidthPx) || (t.value = Math.min(1, (c.viewport.clientWidth - 48) / Math.max(1, c.pageWidthPx)));
113
+ });
114
+ }
115
+ function l(c) {
116
+ if (c === "fit")
117
+ o.value = "fit", a();
118
+ else {
119
+ if (!Number.isFinite(c)) return;
120
+ n(), o.value = "raw", t.value = Math.min(3, Math.max(0.3, c / 100));
121
+ }
122
+ }
123
+ return en() && Re(n), { zoom: t, zoomMode: o, applyFitZoom: a, setZoom: l };
124
+ }
125
+ const Ne = 8;
126
+ function je() {
127
+ return new Promise((e) => setTimeout(e, 0));
128
+ }
129
+ function Ae(e) {
130
+ return `p${e.pageWidthMm}x${e.pageHeightMm}`.replace(/[.+]/g, "_");
131
+ }
132
+ function dt(e) {
133
+ const t = /* @__PURE__ */ new Map();
134
+ return e.pages.forEach((n) => {
135
+ t.has(Ae(n)) || t.set(Ae(n), n);
136
+ }), `<!doctype html><html><head><meta charset="utf-8"><style>${`.mr-page{margin:0 auto;page-break-after:always;}
137
+ .mr-page tr{break-inside:avoid;page-break-inside:avoid;}
138
+ .mr-comp{break-inside:avoid;page-break-inside:avoid;}
139
+ ${[...t.values()].map(
140
+ (n) => `@page ${Ae(n)}{size:${n.pageWidthMm}mm ${n.pageHeightMm}mm;margin:0;}`
141
+ ).join(`
142
+ `)}
143
+ body{margin:0;background:#fff;}`}</style></head><body>`;
144
+ }
145
+ function ft(e) {
146
+ const t = St(e, 96, {}, document);
147
+ return t.style.page = Ae(e), t.outerHTML;
148
+ }
149
+ function Wt(e) {
150
+ return { head: dt(e), pageChunks: e.pages.map(ft) };
151
+ }
152
+ async function Jr(e, t = {}) {
153
+ const o = {
154
+ schemaVersion: "mach-report-batch-print",
155
+ pages: e.flatMap((l) => l.pages)
156
+ };
157
+ if (o.pages.length === 0) return;
158
+ const r = dt(o), n = document.createElement("iframe");
159
+ n.style.cssText = "position:fixed;right:0;bottom:0;width:0;height:0;border:0;visibility:hidden;", document.body.appendChild(n);
160
+ let a = !1;
161
+ try {
162
+ const l = n.contentDocument;
163
+ l.open(), l.write(r);
164
+ for (let c = 0; c < o.pages.length; c++)
165
+ l.write(ft(o.pages[c])), c % Ne === Ne - 1 && (t.onProgress?.(c + 1, o.pages.length), await je());
166
+ l.write("</body></html>"), l.close(), await je(), t.onProgress?.(o.pages.length, o.pages.length), a = !0, n.contentWindow?.focus(), n.contentWindow?.print();
167
+ } catch (l) {
168
+ t.onError?.(l instanceof Error ? `批量打印失败: ${l.message}` : "批量打印失败");
169
+ } finally {
170
+ a ? setTimeout(() => n.remove(), 6e4) : n.remove();
171
+ }
172
+ }
173
+ function Pn(e) {
174
+ const { head: t, pageChunks: o } = Wt(e);
175
+ return {
176
+ html: `${`<!doctype html><html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40"><head><meta charset="utf-8"><!--[if gte mso 9]><xml><w:WordDocument><w:View>Print</w:View><w:Zoom>100</w:Zoom></w:WordDocument></xml><![endif]-->${t.replace(/^<!doctype html><html><head>/, "")}`}${o.join("")}</body></html>`,
177
+ filename: "mach-report.doc"
178
+ };
179
+ }
180
+ function En(e, t) {
181
+ let o = null, r = !1, n = !1, a = 0;
182
+ const l = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map();
183
+ let m = null, b = null, f = null, p = null, h = null;
184
+ function i(u, d) {
185
+ return !n && e.value === u && a === d;
186
+ }
187
+ function x() {
188
+ if (n) return;
189
+ const u = [...l.values()].reverse().find((d) => i(d.plan, d.epoch))?.format ?? null;
190
+ u !== m && (m = u, t.onBusy?.(u));
191
+ }
192
+ function $(u, d, y) {
193
+ const T = {};
194
+ return l.set(T, { plan: u, epoch: d, format: y }), x(), T;
195
+ }
196
+ function w(u) {
197
+ l.delete(u), x();
198
+ }
199
+ function I() {
200
+ for (const [u, d] of c)
201
+ i(d.plan, d.epoch) || (u.close(), c.delete(u));
202
+ }
203
+ function P() {
204
+ a++, C(), x(), I();
205
+ }
206
+ const O = _(e, P, { flush: "sync" });
207
+ function C() {
208
+ o?.remove(), o = null;
209
+ }
210
+ function D() {
211
+ n = !0, a++, O(), C(), I(), l.clear(), t.onPrinting?.(!1);
212
+ }
213
+ function H(u, d) {
214
+ const y = URL.createObjectURL(u);
215
+ setTimeout(() => URL.revokeObjectURL(y), 1e4);
216
+ const T = document.createElement("a");
217
+ T.href = y, T.download = d, T.click();
218
+ }
219
+ async function K() {
220
+ if (r) return;
221
+ const u = e.value;
222
+ if (n || !u || u.pages.length === 0) return;
223
+ const d = a;
224
+ r = !0, t.onPrinting?.(!0), C();
225
+ const y = dt(u);
226
+ o = document.createElement("iframe"), o.style.cssText = "position:fixed;right:0;bottom:0;width:0;height:0;border:0;visibility:hidden;", document.body.appendChild(o);
227
+ const T = o;
228
+ try {
229
+ const B = T.contentDocument;
230
+ B.open(), B.write(y);
231
+ for (let V = 0; V < u.pages.length; V++)
232
+ if (B.write(ft(u.pages[V])), V % Ne === Ne - 1 && await je(), T !== o) return;
233
+ if (B.write("</body></html>"), B.close(), await je(), !i(u, d) || T !== o) return;
234
+ T.contentWindow?.focus(), T.contentWindow?.print();
235
+ } catch {
236
+ T === o && C(), i(u, d) && t.onError("调用打印失败,请改用导出 PDF", "print");
237
+ } finally {
238
+ r = !1, n || t.onPrinting?.(!1);
239
+ }
240
+ }
241
+ function X(u, d) {
242
+ if (b?.plan === u && b.epoch === d) return b.promise;
243
+ const y = Promise.resolve().then(() => {
244
+ if (!i(u, d)) throw new Error("报表已切换或卸载");
245
+ return t.getPdfExporter()(u, (T) => {
246
+ i(u, d) && t.onWarning?.(T);
247
+ });
248
+ }).finally(() => {
249
+ b?.promise === y && (b = null);
250
+ });
251
+ return b = { plan: u, epoch: d, promise: y }, y;
252
+ }
253
+ async function Q() {
254
+ const u = e.value;
255
+ if (n || !u || u.pages.length === 0) return;
256
+ const d = a;
257
+ if (f?.plan === u && f.epoch === d) return f.promise;
258
+ const y = $(u, d, "PDF"), T = (async () => {
259
+ try {
260
+ const B = await X(u, d);
261
+ if (!i(u, d)) return;
262
+ H(new Blob([B], { type: "application/pdf" }), "mach-report.pdf");
263
+ } catch (B) {
264
+ i(u, d) && t.onError(B instanceof Error ? `PDF 导出失败: ${B.message}` : "PDF 导出失败", "pdf");
265
+ } finally {
266
+ w(y), f?.token === y && (f = null);
267
+ }
268
+ })();
269
+ return f = { plan: u, epoch: d, promise: T, token: y }, T;
270
+ }
271
+ async function Y() {
272
+ const u = e.value;
273
+ if (n || !u || u.pages.length === 0) return;
274
+ const d = a;
275
+ if (p?.plan === u && p.epoch === d) return p.promise;
276
+ const y = { ...t.getXlsxOptions?.() }, T = $(u, d, "Excel"), B = (async () => {
277
+ try {
278
+ const { renderPlanToXlsx: V } = await import("@agile-team/mach-report/xlsx");
279
+ if (!i(u, d)) return;
280
+ const { buffer: ee, warnings: oe } = await V(u, y);
281
+ if (!i(u, d) || (oe.length > 0 && t.onWarning?.(`Excel 导出有 ${oe.length} 条提示:${oe.slice(0, 2).join(";")}`), !i(u, d))) return;
282
+ H(new Blob([ee], {
283
+ type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
284
+ }), "mach-report.xlsx");
285
+ } catch (V) {
286
+ i(u, d) && t.onError(V instanceof Error ? `Excel 导出失败: ${V.message}` : "Excel 导出失败", "export");
287
+ } finally {
288
+ w(T), p?.token === T && (p = null);
289
+ }
290
+ })();
291
+ return p = { plan: u, epoch: d, promise: B, token: T }, B;
292
+ }
293
+ async function se() {
294
+ const u = e.value;
295
+ if (n || !u || u.pages.length === 0) return;
296
+ const d = a;
297
+ if (h?.plan === u && h.epoch === d) return h.promise;
298
+ const y = $(u, d, "图片"), T = (async () => {
299
+ try {
300
+ const { blobs: B } = await un(u, {
301
+ dpr: Math.min(2, typeof devicePixelRatio == "number" ? devicePixelRatio : 1)
302
+ });
303
+ if (!i(u, d)) return;
304
+ B.forEach((V, ee) => {
305
+ H(V, B.length > 1 ? `mach-report-page-${ee + 1}.png` : "mach-report.png");
306
+ });
307
+ } catch (B) {
308
+ i(u, d) && t.onError(
309
+ B instanceof Error ? `图片导出失败: ${B.message}` : "图片导出失败",
310
+ "export"
311
+ );
312
+ } finally {
313
+ w(y), h?.token === y && (h = null);
314
+ }
315
+ })();
316
+ return h = { plan: u, epoch: d, promise: T, token: y }, T;
317
+ }
318
+ function U() {
319
+ const u = e.value;
320
+ if (!(n || !u || u.pages.length === 0))
321
+ try {
322
+ const { html: d, filename: y } = Pn(u);
323
+ H(new Blob([d], { type: "application/msword;charset=utf-8" }), y);
324
+ } catch (d) {
325
+ t.onError(
326
+ d instanceof Error ? `Word 导出失败: ${d.message}` : "Word 导出失败",
327
+ "export"
328
+ );
329
+ }
330
+ }
331
+ async function me(u) {
332
+ const d = e.value;
333
+ if (!(n || !d || d.pages.length === 0)) {
334
+ if (u === "pdf") {
335
+ await Q();
336
+ return;
337
+ }
338
+ if (u === "xlsx" || u === "excel") {
339
+ await Y();
340
+ return;
341
+ }
342
+ if (u === "png" || u === "image") {
343
+ await se();
344
+ return;
345
+ }
346
+ if (u === "word" || u === "doc") {
347
+ U();
348
+ return;
349
+ }
350
+ if (u !== "html") {
351
+ t.onError(`不支持的导出格式:${u}`, "export");
352
+ return;
353
+ }
354
+ try {
355
+ const { head: y, pageChunks: T } = Wt(d), B = `${y}${T.join("")}</body></html>`;
356
+ H(new Blob([B], { type: "text/html;charset=utf-8" }), "mach-report.html");
357
+ } catch (y) {
358
+ t.onError(y instanceof Error ? `HTML 导出失败: ${y.message}` : "HTML 导出失败", "export");
359
+ }
360
+ }
361
+ }
362
+ function J() {
363
+ const u = e.value;
364
+ if (n || !u || u.pages.length === 0) return;
365
+ const d = a, y = window.open("", "_blank");
366
+ if (!y) {
367
+ t.onError("浏览器拦截了弹窗,请允许弹窗后重试", "pdf");
368
+ return;
369
+ }
370
+ c.set(y, { plan: u, epoch: d });
371
+ const T = $(u, d, "PDF");
372
+ X(u, d).then((B) => {
373
+ if (!i(u, d) || y.closed) {
374
+ c.delete(y) && y.close();
375
+ return;
376
+ }
377
+ const V = URL.createObjectURL(new Blob([B], { type: "application/pdf" }));
378
+ setTimeout(() => URL.revokeObjectURL(V), 6e4);
379
+ const ee = y.document;
380
+ ee.title = "PDF 预览", ee.documentElement.style.height = "100%", ee.body.style.cssText = "margin:0;height:100%;";
381
+ const oe = ee.createElement("iframe");
382
+ oe.title = "PDF 预览", oe.style.cssText = "display:block;width:100%;height:100%;border:0;", oe.src = V, ee.body.replaceChildren(oe), c.delete(y);
383
+ }).catch((B) => {
384
+ y.close(), c.delete(y), i(u, d) && t.onError(B instanceof Error ? `PDF 预览失败: ${B.message}` : "PDF 预览失败", "pdf");
385
+ }).finally(() => w(T));
386
+ }
387
+ return {
388
+ print: K,
389
+ exportAs: me,
390
+ exportImages: se,
391
+ exportWord: U,
392
+ openPdfWindow: J,
393
+ invalidatePending: P,
394
+ releasePrintFrame: C,
395
+ dispose: D
396
+ };
397
+ }
398
+ const At = "mrp-hit";
399
+ function $n(e) {
400
+ e.querySelectorAll(`mark.${At}`).forEach((o) => {
401
+ const r = o.parentNode;
402
+ if (r) {
403
+ for (; o.firstChild; ) r.insertBefore(o.firstChild, o);
404
+ o.remove(), r.normalize();
405
+ }
406
+ });
407
+ }
408
+ function Cn(e, t) {
409
+ const o = t.trim();
410
+ if (!o) return 0;
411
+ const r = o.toLowerCase(), n = document.createTreeWalker(e, NodeFilter.SHOW_TEXT, {
412
+ acceptNode(c) {
413
+ const m = c.parentElement;
414
+ return !m || m.closest("mark") || /^(SCRIPT|STYLE)$/.test(m.tagName) ? NodeFilter.FILTER_REJECT : (c.nodeValue ?? "").toLowerCase().includes(r) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
415
+ }
416
+ }), a = [];
417
+ for (let c = n.nextNode(); c; c = n.nextNode()) a.push(c);
418
+ let l = 0;
419
+ for (const c of a) {
420
+ const m = c.nodeValue ?? "", b = m.toLowerCase(), f = c.parentElement;
421
+ if (!f) continue;
422
+ const p = document.createDocumentFragment();
423
+ let h = 0, i = b.indexOf(r);
424
+ for (; i >= 0; ) {
425
+ i > h && p.appendChild(document.createTextNode(m.slice(h, i)));
426
+ const x = document.createElement("mark");
427
+ x.className = At, x.textContent = m.slice(i, i + o.length), p.appendChild(x), l++, h = i + o.length, i = b.indexOf(r, h);
428
+ }
429
+ h < m.length && p.appendChild(document.createTextNode(m.slice(h))), f.replaceChild(p, c);
430
+ }
431
+ return l;
432
+ }
433
+ const kn = /* @__PURE__ */ new Set(["line", "rect", "ellipse", "chart"]);
434
+ function* Mn(e) {
435
+ for (const t of e.cells ?? [])
436
+ for (const o of t ?? [])
437
+ yield o?.text ?? "", yield* o?.children ?? [];
438
+ }
439
+ function* Fn(e) {
440
+ if (gn(e))
441
+ for (const t of e.richParagraphs)
442
+ for (const o of t.segments ?? [])
443
+ yield (o.kind === "field" ? o.field : o.text) ?? "";
444
+ else e.lines?.length ? yield* e.lines : yield e.text ?? "";
445
+ }
446
+ function* Rn(e) {
447
+ const t = [e.values()];
448
+ for (; t.length > 0; ) {
449
+ const o = t[t.length - 1].next();
450
+ if (o.done) {
451
+ t.pop();
452
+ continue;
453
+ }
454
+ const r = o.value;
455
+ if (typeof r == "string") {
456
+ yield r;
457
+ continue;
458
+ }
459
+ yield "", !vn(r) && (r.kind === "text" ? t.push(Fn(r)) : r.grid ? t.push(Mn(r.grid)) : kn.has(r.kind) || (yield r.fallbackText ?? ""));
460
+ }
461
+ }
462
+ function* Tn(e) {
463
+ for (let t = 0; t < e.pages.length; t++) {
464
+ for (const o of Rn(e.pages[t].components)) yield { text: o, pageIndex: t };
465
+ yield { text: "", pageIndex: t };
466
+ }
467
+ }
468
+ function In(e, t) {
469
+ const o = e.toLowerCase();
470
+ let r = 0;
471
+ for (let n = o.indexOf(t); n >= 0; n = o.indexOf(t, n + t.length)) r++;
472
+ return r;
473
+ }
474
+ function Sn(e) {
475
+ const { plan: t, gotoPage: o, highlight: r, clearHighlights: n } = e, a = A(!1), l = A(""), c = A(0), m = A(0), b = A(!1);
476
+ let f = [];
477
+ const p = F(() => {
478
+ if (m.value === 0) return null;
479
+ const C = c.value;
480
+ let D = 0, H = f.length - 1;
481
+ for (; D < H; ) {
482
+ const X = D + H >>> 1;
483
+ f[X].cumulative <= C ? D = X + 1 : H = X;
484
+ }
485
+ const K = f[D];
486
+ return K ? { pageIndex: K.pageIndex, occurrence: C - (f[D - 1]?.cumulative ?? 0) } : null;
487
+ });
488
+ let h = null, i = null, x = 0;
489
+ function $() {
490
+ x++, h && clearTimeout(h), i && clearTimeout(i), h = i = null, b.value = !1;
491
+ }
492
+ function w(C) {
493
+ l.value = C, c.value = 0, m.value = 0, f = [], b.value = !1;
494
+ const D = C.trim().toLowerCase(), H = t.value;
495
+ if (!D || !H) return;
496
+ b.value = !0;
497
+ const K = x, X = Tn(H), Q = [];
498
+ let Y = 0;
499
+ function se() {
500
+ if (i = null, K !== x || H !== t.value) return;
501
+ const U = performance.now();
502
+ let me = 0;
503
+ for (; me < 5e3 && performance.now() - U < 4; ) {
504
+ const J = X.next();
505
+ if (J.done) {
506
+ f = Q, m.value = Y, b.value = !1, f[0] && o(f[0].pageIndex + 1);
507
+ return;
508
+ }
509
+ const u = In(J.value.text, D);
510
+ if (u > 0) {
511
+ Y += u;
512
+ const d = Q[Q.length - 1];
513
+ d?.pageIndex === J.value.pageIndex ? d.cumulative = Y : Q.push({ pageIndex: J.value.pageIndex, cumulative: Y });
514
+ }
515
+ me++;
516
+ }
517
+ i = setTimeout(se, 0);
518
+ }
519
+ se();
520
+ }
521
+ function I(C) {
522
+ if ($(), l.value = C, c.value = m.value = 0, f = [], !C.trim()) {
523
+ w("");
524
+ return;
525
+ }
526
+ b.value = !0, h = setTimeout(() => {
527
+ h = null, w(C);
528
+ }, Math.max(0, E(e.debounceMs) ?? 200));
529
+ }
530
+ function P(C) {
531
+ const D = m.value;
532
+ if (D === 0 || b.value) return;
533
+ c.value = (c.value + C + D) % D;
534
+ const H = p.value;
535
+ H && o(H.pageIndex + 1);
536
+ }
537
+ function O() {
538
+ $(), l.value = "", c.value = m.value = 0, f = [];
539
+ }
540
+ return _(t, O, { flush: "sync" }), Re(O), {
541
+ visible: a,
542
+ query: l,
543
+ matchIndex: c,
544
+ matchCount: m,
545
+ activeMatch: p,
546
+ searching: b,
547
+ toggle: () => {
548
+ a.value = !a.value;
549
+ },
550
+ onInput: I,
551
+ onNav: P,
552
+ apply: (C) => {
553
+ l.value.trim() && r(C, l.value.trim());
554
+ },
555
+ clear: (C) => {
556
+ n(C);
557
+ },
558
+ reset: O
559
+ };
560
+ }
561
+ function Dn(e, t) {
562
+ const o = F(() => {
563
+ if (e.value) return !0;
564
+ if (typeof location > "u") return !1;
565
+ try {
566
+ return new URLSearchParams(location.search).get("mrp-debug") === "1";
567
+ } catch {
568
+ return !1;
569
+ }
570
+ }), r = F(() => !o.value || !t.plan.value ? 0 : Math.round(JSON.stringify(t.plan.value).length / 1024)), n = F(() => !o.value || !t.plan.value ? null : {
571
+ pages: t.pageCount.value,
572
+ window: `${t.windowRange.value.start}-${t.windowRange.value.end}`,
573
+ zoom: `${Math.round(t.zoom.value * 100)}%`,
574
+ loadMs: `${t.loadMs.value}ms`,
575
+ planKB: r.value
576
+ });
577
+ return { enabled: o, debugStats: n };
578
+ }
579
+ function On(e, t) {
580
+ const { thumbsRoot: o, visible: r, renderThumbCanvas: n } = t, a = A(0), l = A(800), c = F(() => (e.value?.pages ?? []).map(
581
+ (P) => Math.round(P.pageHeightMm / P.pageWidthMm * 116)
582
+ )), m = F(() => Ot(c.value.map((P) => P + 20), 8)), b = F(() => m.value.window(l.value, a.value, 1)), f = F(() => {
583
+ if (!r.value) return [];
584
+ const { start: P, end: O } = b.value;
585
+ return c.value.slice(P, O + 1).map((C, D) => ({ index: P + D, height: C }));
586
+ });
587
+ let p = 0, h = 0, i = !1;
588
+ function x() {
589
+ const P = o.value;
590
+ P && (a.value = P.scrollTop, l.value = P.clientHeight || 800);
591
+ }
592
+ function $() {
593
+ i || h || (h = requestAnimationFrame(() => {
594
+ h = 0, x();
595
+ }));
596
+ }
597
+ function w() {
598
+ if (f.value, p && cancelAnimationFrame(p), p = 0, i || !r.value || !e.value || !o.value) return;
599
+ x();
600
+ const P = f.value, O = e.value, C = o.value;
601
+ let D = 0;
602
+ function H() {
603
+ if (p = 0, !(i || !r.value || e.value !== O || o.value !== C)) {
604
+ for (let K = 0; D < P.length && K < 2; K++, D++) {
605
+ const X = P[D].index, Q = C.querySelector(`[data-thumb="${X + 1}"]`);
606
+ if (!Q || Q.childElementCount > 0) continue;
607
+ const Y = n(X);
608
+ Y && (Y.style.width = "100%", Y.style.height = "100%", Y.style.display = "block", Q.appendChild(Y));
609
+ }
610
+ D < P.length && (p = requestAnimationFrame(H));
611
+ }
612
+ }
613
+ p = requestAnimationFrame(H);
614
+ }
615
+ function I() {
616
+ i = !0, p && cancelAnimationFrame(p), h && cancelAnimationFrame(h), p = h = 0;
617
+ }
618
+ return Re(I), { schedule: w, destroy: I, onScroll: $, windowRange: b, visibleThumbs: f };
619
+ }
620
+ function Bn() {
621
+ const e = ye(0);
622
+ return {
623
+ loadMs: e,
624
+ start() {
625
+ return typeof performance < "u" ? performance.now() : 0;
626
+ },
627
+ end(t) {
628
+ e.value = t ? Math.round(performance.now() - t) : 0;
629
+ }
630
+ };
631
+ }
632
+ const Wn = { class: "mrp-toolbar" }, An = { class: "mrp-title" }, Ln = ["disabled"], zn = { class: "mrp-pageinfo" }, Hn = ["disabled"], Nn = ["disabled"], jn = {
633
+ key: 2,
634
+ class: "mrp-search"
635
+ }, qn = ["placeholder", "value"], Un = {
636
+ key: 0,
637
+ class: "mrp-search-count",
638
+ role: "status"
639
+ }, Vn = ["disabled"], Kn = ["disabled"], Yn = ["disabled"], Zn = ["disabled"], Jn = ["disabled"], Gn = ["disabled"], Xn = ["disabled"], Qn = ["disabled"], _n = ["disabled"], er = /* @__PURE__ */ ct({
640
+ __name: "ReportToolbar",
641
+ props: {
642
+ pageCount: {},
643
+ currentPage: {},
644
+ zoomMode: {},
645
+ zoom: {},
646
+ showExport: { type: Boolean },
647
+ showPrint: { type: Boolean },
648
+ showPdfWindow: { type: Boolean },
649
+ messages: {},
650
+ search: {},
651
+ thumbsVisible: { type: Boolean },
652
+ showImport: { type: Boolean },
653
+ busy: { type: Boolean }
654
+ },
655
+ emits: ["goto", "zoom", "export", "print", "pdf-window", "search-input", "search-nav", "search-toggle", "thumbs-toggle", "import-excel"],
656
+ setup(e) {
657
+ const t = e, o = A(null);
658
+ _(
659
+ () => t.search.visible,
660
+ (n) => {
661
+ n && tn(() => o.value?.focus());
662
+ }
663
+ );
664
+ function r(n, a, l) {
665
+ return n.replace("{cur}", String(a)).replace("{total}", String(l));
666
+ }
667
+ return (n, a) => (k(), M("div", Wn, [
668
+ S("span", An, R(e.messages.title), 1),
669
+ e.pageCount > 0 ? (k(), M(Fe, { key: 0 }, [
670
+ S("button", {
671
+ class: "mrp-nav",
672
+ type: "button",
673
+ disabled: e.currentPage <= 1,
674
+ onClick: a[0] || (a[0] = (l) => n.$emit("goto", e.currentPage - 1))
675
+ }, R(e.messages.prevPage), 9, Ln),
676
+ S("span", zn, R(r(e.messages.pageInfo, e.currentPage, e.pageCount)), 1),
677
+ S("button", {
678
+ class: "mrp-nav",
679
+ type: "button",
680
+ disabled: e.currentPage >= e.pageCount,
681
+ onClick: a[1] || (a[1] = (l) => n.$emit("goto", e.currentPage + 1))
682
+ }, R(e.messages.nextPage), 9, Hn)
683
+ ], 64)) : j("", !0),
684
+ a[18] || (a[18] = S("span", { class: "mrp-spacer" }, null, -1)),
685
+ e.showImport ? (k(), M("button", {
686
+ key: 1,
687
+ class: "mrp-nav mrp-import-excel",
688
+ type: "button",
689
+ disabled: e.busy,
690
+ onClick: a[2] || (a[2] = (l) => n.$emit("import-excel"))
691
+ }, R(e.messages.importExcel ?? "导入 Excel 模板"), 9, Nn)) : j("", !0),
692
+ e.search.visible ? (k(), M("div", jn, [
693
+ S("input", {
694
+ ref_key: "searchInputRef",
695
+ ref: o,
696
+ class: "mrp-search-input",
697
+ type: "text",
698
+ placeholder: e.messages.searchPlaceholder,
699
+ value: e.search.query,
700
+ onInput: a[3] || (a[3] = (l) => n.$emit("search-input", l.target.value))
701
+ }, null, 40, qn),
702
+ e.search.query ? (k(), M("span", Un, R(e.search.searching ? e.messages.searching ?? "搜索中…" : r(e.messages.matchInfo, e.search.matchCount > 0 ? e.search.matchIndex + 1 : 0, e.search.matchCount)), 1)) : j("", !0),
703
+ S("button", {
704
+ class: "mrp-nav",
705
+ type: "button",
706
+ disabled: e.search.matchCount === 0,
707
+ onClick: a[4] || (a[4] = (l) => n.$emit("search-nav", -1))
708
+ }, R(e.messages.prevMatch), 9, Vn),
709
+ S("button", {
710
+ class: "mrp-nav",
711
+ type: "button",
712
+ disabled: e.search.matchCount === 0,
713
+ onClick: a[5] || (a[5] = (l) => n.$emit("search-nav", 1))
714
+ }, R(e.messages.nextMatch), 9, Kn)
715
+ ])) : j("", !0),
716
+ S("button", {
717
+ class: de(["mrp-nav", { "mrp-active": e.search.visible }]),
718
+ type: "button",
719
+ title: "Ctrl+F",
720
+ onClick: a[6] || (a[6] = (l) => n.$emit("search-toggle"))
721
+ }, " 🔍 ", 2),
722
+ S("button", {
723
+ class: de(["mrp-nav", { "mrp-active": e.thumbsVisible }]),
724
+ type: "button",
725
+ onClick: a[7] || (a[7] = (l) => n.$emit("thumbs-toggle"))
726
+ }, " ▦ " + R(e.messages.thumbnails), 3),
727
+ S("button", {
728
+ class: de(["mrp-nav", { "mrp-active": e.zoomMode === "fit" }]),
729
+ type: "button",
730
+ onClick: a[8] || (a[8] = (l) => n.$emit("zoom", "fit"))
731
+ }, R(e.messages.fitWidth), 3),
732
+ S("button", {
733
+ class: de(["mrp-nav", { "mrp-active": e.zoomMode === "raw" && Math.round(e.zoom * 100) === 100 }]),
734
+ type: "button",
735
+ onClick: a[9] || (a[9] = (l) => n.$emit("zoom", 100))
736
+ }, " 100% ", 2),
737
+ S("button", {
738
+ class: de(["mrp-nav", { "mrp-active": e.zoomMode === "raw" && Math.round(e.zoom * 100) === 150 }]),
739
+ type: "button",
740
+ onClick: a[10] || (a[10] = (l) => n.$emit("zoom", 150))
741
+ }, " 150% ", 2),
742
+ e.showExport ? (k(), M("button", {
743
+ key: 3,
744
+ class: "mrp-nav",
745
+ type: "button",
746
+ disabled: e.busy,
747
+ onClick: a[11] || (a[11] = (l) => n.$emit("export", "html"))
748
+ }, R(e.messages.exportHtml), 9, Yn)) : j("", !0),
749
+ e.showExport ? (k(), M("button", {
750
+ key: 4,
751
+ class: "mrp-nav",
752
+ type: "button",
753
+ disabled: e.busy,
754
+ onClick: a[12] || (a[12] = (l) => n.$emit("export", "pdf"))
755
+ }, R(e.messages.exportPdf), 9, Zn)) : j("", !0),
756
+ e.showExport ? (k(), M("button", {
757
+ key: 5,
758
+ class: "mrp-nav",
759
+ type: "button",
760
+ disabled: e.busy,
761
+ onClick: a[13] || (a[13] = (l) => n.$emit("export", "xlsx"))
762
+ }, R(e.messages.exportExcel), 9, Jn)) : j("", !0),
763
+ e.showExport ? (k(), M("button", {
764
+ key: 6,
765
+ class: "mrp-nav",
766
+ type: "button",
767
+ disabled: e.busy,
768
+ onClick: a[14] || (a[14] = (l) => n.$emit("export", "png"))
769
+ }, R(e.messages.exportImage), 9, Gn)) : j("", !0),
770
+ e.showExport ? (k(), M("button", {
771
+ key: 7,
772
+ class: "mrp-nav",
773
+ type: "button",
774
+ disabled: e.busy,
775
+ onClick: a[15] || (a[15] = (l) => n.$emit("export", "word"))
776
+ }, R(e.messages.exportWord), 9, Xn)) : j("", !0),
777
+ e.showPrint ? (k(), M("button", {
778
+ key: 8,
779
+ class: "mrp-nav",
780
+ type: "button",
781
+ disabled: e.busy,
782
+ onClick: a[16] || (a[16] = (l) => n.$emit("print"))
783
+ }, R(e.messages.print), 9, Qn)) : j("", !0),
784
+ e.showPdfWindow ? (k(), M("button", {
785
+ key: 9,
786
+ class: "mrp-nav",
787
+ type: "button",
788
+ disabled: e.busy,
789
+ onClick: a[17] || (a[17] = (l) => n.$emit("pdf-window"))
790
+ }, R(e.messages.pdfWindow), 9, _n)) : j("", !0)
791
+ ]));
792
+ }
793
+ }), pt = (e, t) => {
794
+ const o = e.__vccOpts || e;
795
+ for (const [r, n] of t)
796
+ o[r] = n;
797
+ return o;
798
+ }, tr = /* @__PURE__ */ pt(er, [["__scopeId", "data-v-1c2568a7"]]), nr = { class: "mrp-params" }, rr = { class: "mrp-params-title" }, ar = { class: "mrp-params-grid" }, or = { class: "mrp-param-label" }, lr = {
799
+ key: 0,
800
+ class: "mrp-param-star"
801
+ }, sr = ["value", "onChange"], ir = {
802
+ value: "",
803
+ disabled: "",
804
+ hidden: ""
805
+ }, ur = ["value"], cr = ["type", "placeholder", "value", "onInput"], dr = { class: "mrp-params-actions" }, fr = /* @__PURE__ */ ct({
806
+ __name: "ReportParamPanel",
807
+ props: {
808
+ defs: {},
809
+ modelValue: {},
810
+ messages: {},
811
+ attempted: { type: Boolean }
812
+ },
813
+ emits: ["update:modelValue", "query", "reset"],
814
+ setup(e, { emit: t }) {
815
+ const o = e, r = t, n = A({ ...o.modelValue });
816
+ _(
817
+ () => o.modelValue,
818
+ (m) => {
819
+ n.value = { ...m };
820
+ }
821
+ );
822
+ const a = F(
823
+ () => o.defs.map((m) => ({
824
+ def: m,
825
+ label: m.label ?? m.field,
826
+ value: n.value[m.field] ?? ""
827
+ }))
828
+ );
829
+ function l(m, b) {
830
+ n.value = { ...n.value, [m]: b }, r("update:modelValue", { ...n.value });
831
+ }
832
+ function c(m) {
833
+ const b = o.defs.find((f) => f.field === m);
834
+ return o.attempted && b?.required === !0 && !(n.value[m] ?? "").trim();
835
+ }
836
+ return (m, b) => (k(), M("div", nr, [
837
+ S("span", rr, R(e.messages.paramsTitle), 1),
838
+ S("div", ar, [
839
+ (k(!0), M(Fe, null, ze(a.value, (f) => (k(), M("label", {
840
+ key: f.def.field,
841
+ class: de(["mrp-param", { "mrp-param-missing": c(f.def.field) }])
842
+ }, [
843
+ S("span", or, [
844
+ st(R(f.label), 1),
845
+ f.def.required ? (k(), M("i", lr, "*")) : j("", !0)
846
+ ]),
847
+ (f.def.type ?? "text") === "select" ? (k(), M("select", {
848
+ key: 0,
849
+ class: "mrp-param-input",
850
+ value: f.value,
851
+ onChange: (p) => l(f.def.field, p.target.value),
852
+ onKeydown: b[0] || (b[0] = Ct((p) => m.$emit("query"), ["enter"]))
853
+ }, [
854
+ S("option", ir, R(f.def.placeholder ?? `请选择${f.label}`), 1),
855
+ (k(!0), M(Fe, null, ze(f.def.options ?? [], (p) => (k(), M("option", {
856
+ key: p.value,
857
+ value: p.value
858
+ }, R(p.label), 9, ur))), 128))
859
+ ], 40, sr)) : (k(), M("input", {
860
+ key: 1,
861
+ class: "mrp-param-input",
862
+ type: f.def.type === "number" ? "number" : f.def.type === "date" ? "date" : "text",
863
+ placeholder: f.def.placeholder ?? `请输入${f.label}`,
864
+ value: f.value,
865
+ onInput: (p) => l(f.def.field, p.target.value),
866
+ onKeydown: b[1] || (b[1] = Ct((p) => m.$emit("query"), ["enter"]))
867
+ }, null, 40, cr))
868
+ ], 2))), 128))
869
+ ]),
870
+ S("div", dr, [
871
+ S("button", {
872
+ class: "mrp-nav mrp-param-query",
873
+ type: "button",
874
+ onClick: b[2] || (b[2] = (f) => m.$emit("query"))
875
+ }, R(e.messages.query), 1),
876
+ S("button", {
877
+ class: "mrp-nav",
878
+ type: "button",
879
+ onClick: b[3] || (b[3] = (f) => m.$emit("reset"))
880
+ }, R(e.messages.reset), 1)
881
+ ])
882
+ ]));
883
+ }
884
+ }), pr = /* @__PURE__ */ pt(fr, [["__scopeId", "data-v-aafce92d"]]), mr = {
885
+ title: "报表预览",
886
+ prevPage: "‹ 上一页",
887
+ nextPage: "下一页 ›",
888
+ pageInfo: "{cur} / {total}",
889
+ fitWidth: "适宽",
890
+ exportHtml: "导出 HTML",
891
+ exportPdf: "导出 PDF",
892
+ exportExcel: "导出 Excel",
893
+ exportImage: "导出图片",
894
+ exportWord: "导出 Word",
895
+ exporting: "正在生成 {format}…",
896
+ print: "打印",
897
+ pdfWindow: "PDF 窗口",
898
+ loading: "报表渲染中…",
899
+ empty: "暂无预览数据",
900
+ errorPrefix: "",
901
+ retry: "重试",
902
+ pdfFontUnavailable: "PDF 字体尚未就绪,请联系管理员检查字体配置;预览及其它导出仍可使用。",
903
+ searchPlaceholder: "搜索报表内容",
904
+ matchInfo: "{cur}/{total}",
905
+ prevMatch: "‹",
906
+ nextMatch: "›",
907
+ thumbnails: "缩略图",
908
+ paramsTitle: "查询条件",
909
+ query: "查 询",
910
+ reset: "重 置",
911
+ paramRequired: "请填写{label}",
912
+ searching: "搜索中…",
913
+ importExcel: "导入 Excel 模板",
914
+ importing: "正在导入 Excel…",
915
+ editCell: "编辑单元格",
916
+ editingHint: "双击单元格编辑 · Enter 确认 · Esc 取消",
917
+ saving: "正在保存修改…",
918
+ editInvalidNumber: "请输入有效数字;清空表示无值",
919
+ editInvalidBoolean: "请输入 true / false、是 / 否或 1 / 0",
920
+ editConflict: "该单元格已变化,请重新打开编辑"
921
+ }, vr = {
922
+ shellBg: "#525659",
923
+ shellFg: "#e8e8e8",
924
+ toolbarBg: "#323639",
925
+ toolbarBorder: "#22252a",
926
+ toolbarFg: "#e8e8e8",
927
+ btnFg: "#cfcfcf",
928
+ btnBorder: "#4a4d52",
929
+ btnHoverBg: "#414549",
930
+ btnHoverFg: "#ffffff",
931
+ btnActiveBg: "#2d5fb8"
932
+ };
933
+ function gr(e = {}) {
934
+ return { ...e, defaults: e.defaults ?? {}, presets: e.presets ?? {} };
935
+ }
936
+ function Gr(e) {
937
+ return e;
938
+ }
939
+ const he = {
940
+ showExport: !0,
941
+ showPrint: !0,
942
+ showPdfWindow: !0,
943
+ showParams: !0,
944
+ gapPx: 18,
945
+ pdfFontUrl: "/simhei.ttf",
946
+ logger: console
947
+ }, Xr = { warn: () => {
948
+ }, info: () => {
949
+ } };
950
+ function Le(e, t) {
951
+ return {
952
+ ...e,
953
+ ...t,
954
+ theme: { ...e?.theme, ...t?.theme },
955
+ messages: { ...e?.messages, ...t?.messages },
956
+ preview: { ...e?.preview, ...t?.preview },
957
+ xlsx: { ...e?.xlsx, ...t?.xlsx }
958
+ };
959
+ }
960
+ function hr(e, t) {
961
+ const o = t ? e?.presets?.[t] : e?.defaultPreset ? e?.presets?.[e.defaultPreset] : void 0, r = Le(e?.defaults, o);
962
+ return {
963
+ showExport: r.showExport ?? he.showExport,
964
+ showPrint: r.showPrint ?? he.showPrint,
965
+ showPdfWindow: r.showPdfWindow ?? he.showPdfWindow,
966
+ showParams: r.showParams ?? he.showParams,
967
+ gapPx: r.gapPx ?? he.gapPx,
968
+ pdfFontUrl: r.pdfFontUrl ?? he.pdfFontUrl,
969
+ theme: { ...vr, ...r.theme },
970
+ messages: { ...mr, ...r.messages },
971
+ logger: r.logger ?? he.logger,
972
+ preview: {
973
+ overscanPages: Rt(r.preview?.overscanPages, 1, 10, !0),
974
+ searchDebounceMs: Rt(r.preview?.searchDebounceMs, 200, 2e3)
975
+ },
976
+ xlsx: { ...r.xlsx },
977
+ editable: r.editable ?? !1,
978
+ excelImport: r.excelImport ?? !1
979
+ };
980
+ }
981
+ function Rt(e, t, o, r = !1) {
982
+ if (e == null || !Number.isFinite(e)) return t;
983
+ const n = Math.max(0, Math.min(o, e));
984
+ return r ? Math.floor(n) : n;
985
+ }
986
+ function br(e) {
987
+ const t = {};
988
+ return e.shellBg != null && (t["--mrp-shell-bg"] = e.shellBg), e.shellFg != null && (t["--mrp-shell-fg"] = e.shellFg), e.toolbarBg != null && (t["--mrp-toolbar-bg"] = e.toolbarBg), e.toolbarBorder != null && (t["--mrp-toolbar-border"] = e.toolbarBorder), e.toolbarFg != null && (t["--mrp-toolbar-fg"] = e.toolbarFg), e.btnFg != null && (t["--mrp-btn-fg"] = e.btnFg), e.btnBorder != null && (t["--mrp-btn-border"] = e.btnBorder), e.btnHoverBg != null && (t["--mrp-btn-hover-bg"] = e.btnHoverBg), e.btnHoverFg != null && (t["--mrp-btn-hover-fg"] = e.btnHoverFg), e.btnActiveBg != null && (t["--mrp-btn-active-bg"] = e.btnActiveBg), t;
989
+ }
990
+ function Qr(e) {
991
+ const t = He(it, null), o = F(() => {
992
+ const r = t?.value ?? null, n = "defaults" in e || "presets" in e || "defaultPreset" in e ? gr(e) : { defaults: e, presets: {} };
993
+ if (!r) return n;
994
+ const a = { ...r.presets, ...n.presets };
995
+ for (const l of Object.keys(a))
996
+ a[l] = Le(
997
+ Le(r.presets[l], n.defaults),
998
+ n.presets[l]
999
+ );
1000
+ return {
1001
+ defaults: Le(r.defaults, n.defaults),
1002
+ presets: a,
1003
+ defaultPreset: n.defaultPreset ?? r.defaultPreset
1004
+ };
1005
+ });
1006
+ It(it, o);
1007
+ }
1008
+ function wr() {
1009
+ return He(it, F(() => null));
1010
+ }
1011
+ const Tt = /* @__PURE__ */ new Map(), we = /* @__PURE__ */ new Map(), yr = 15e3;
1012
+ function ut(e, t) {
1013
+ return Object.assign(new Error(e), { cause: t });
1014
+ }
1015
+ function Me(e, t) {
1016
+ return `PDF 字体 ${JSON.stringify(e)}:${t}。请部署支持报表文字的字体文件,并将 pdfFontUrl 配置为可访问的字体 URL;西文报表可设为空串`;
1017
+ }
1018
+ function qe(e) {
1019
+ if (e?.reason instanceof Error && e.reason.name === "AbortError") return e.reason;
1020
+ const t = ut("PDF 字体检查已取消", e?.reason);
1021
+ return t.name = "AbortError", t;
1022
+ }
1023
+ async function xr(e, t) {
1024
+ let o = !1;
1025
+ const r = setTimeout(() => {
1026
+ o = !0, t.abort();
1027
+ }, yr);
1028
+ try {
1029
+ const n = await fetch(e, { method: "HEAD", signal: t.signal });
1030
+ if (t.signal.aborted) throw qe(t.signal);
1031
+ if (n.status === 405 || n.status === 501 || n.type === "opaque")
1032
+ return {
1033
+ status: "unverified",
1034
+ fontUrl: e,
1035
+ message: `PDF 字体 ${JSON.stringify(e)} 无法通过 HEAD 检查验证;仍可尝试导出,届时会加载并校验字体`
1036
+ };
1037
+ if (!n.ok) {
1038
+ const l = new Error(`字体请求返回 HTTP ${n.status}`);
1039
+ return { status: "error", fontUrl: e, message: Me(e, l.message), cause: l };
1040
+ }
1041
+ const a = n.headers.get("content-type") ?? "";
1042
+ if (/text\/html|application\/xhtml\+xml/i.test(a)) {
1043
+ const l = new Error("字体 URL 返回 HTML 页面(可能是 SPA 路由回退),不是字体文件");
1044
+ return { status: "error", fontUrl: e, message: Me(e, l.message), cause: l };
1045
+ }
1046
+ if (/^text\//i.test(a) || /(?:\/|\+)json(?:\s*;|$)/i.test(a)) {
1047
+ const l = new Error(`字体 URL 返回 ${a} 文本响应,不是字体文件`);
1048
+ return { status: "error", fontUrl: e, message: Me(e, l.message), cause: l };
1049
+ }
1050
+ return {
1051
+ status: "available",
1052
+ fontUrl: e,
1053
+ message: "PDF 字体资源可达;文字覆盖范围将在实际导出时校验"
1054
+ };
1055
+ } catch (n) {
1056
+ if (t.signal.aborted && !o) throw qe(t.signal);
1057
+ return {
1058
+ status: "error",
1059
+ fontUrl: e,
1060
+ message: Me(e, o ? "字体检查超时,请检查网络或字体服务" : "字体检查失败,请检查网络、字体服务或跨域访问配置"),
1061
+ cause: n
1062
+ };
1063
+ } finally {
1064
+ clearTimeout(r);
1065
+ }
1066
+ }
1067
+ function Pr(e, t) {
1068
+ if (t?.aborted) return Promise.reject(qe(t));
1069
+ if (!e)
1070
+ return Promise.resolve({ status: "disabled", fontUrl: e, message: "已停用自定义 PDF 字体;内置字体用于西文,其他文字会在导出时校验" });
1071
+ const o = Tt.get(e);
1072
+ if (o) return Promise.resolve(o);
1073
+ let r = we.get(e);
1074
+ if (!r) {
1075
+ const a = new AbortController();
1076
+ r = { controller: a, promise: xr(e, a), subscribers: 0 };
1077
+ const l = r;
1078
+ we.set(e, l), l.promise = l.promise.then((c) => (!a.signal.aborted && c.status === "available" && Tt.set(e, c), c)).finally(() => {
1079
+ we.get(e) === l && we.delete(e);
1080
+ });
1081
+ }
1082
+ const n = r;
1083
+ return n.subscribers++, new Promise((a, l) => {
1084
+ let c = !1;
1085
+ const m = () => c ? !1 : (c = !0, n.subscribers--, t?.removeEventListener("abort", b), !0), b = () => {
1086
+ m() && (n.subscribers === 0 && (we.get(e) === n && we.delete(e), n.controller.abort()), l(qe(t)));
1087
+ };
1088
+ t?.addEventListener("abort", b, { once: !0 }), n.promise.then(
1089
+ (f) => {
1090
+ m() && a(f);
1091
+ },
1092
+ (f) => {
1093
+ m() && l(f);
1094
+ }
1095
+ ), t?.aborted && b();
1096
+ });
1097
+ }
1098
+ function Er(e = { fontUrl: "/simhei.ttf" }) {
1099
+ let t = null;
1100
+ const o = async (r, n) => {
1101
+ t || (t = await import("@agile-team/mach-report/pdf"));
1102
+ let a = null;
1103
+ if (e.fontUrl)
1104
+ try {
1105
+ if (a = await t.loadFontWithCache(e.fontUrl, { strict: !0 }), !a?.byteLength) throw new Error("字体文件为空或加载失败");
1106
+ } catch (p) {
1107
+ const h = p instanceof Error ? p.message : String(p);
1108
+ throw ut(Me(e.fontUrl, h), p);
1109
+ }
1110
+ let l;
1111
+ try {
1112
+ l = await t.renderPlanToPdf(r, a ? { customFontBytes: a } : {});
1113
+ } catch (p) {
1114
+ if (!a) throw p;
1115
+ const h = p instanceof Error ? p.message : String(p);
1116
+ throw ut(`PDF 生成失败:${h}。当前字体 URL 为 ${JSON.stringify(e.fontUrl)};请确认该文件是有效字体,或重新配置 pdfFontUrl`, p);
1117
+ }
1118
+ const { bytes: c, unsupportedTextCount: m, pageErrors: b, fidelityWarnings: f } = l;
1119
+ if (m > 0)
1120
+ throw new Error(`PDF 中有 ${m} 行文字无法编码;请部署支持所用文字的字体并配置 pdfFontUrl`);
1121
+ if (b.length > 0)
1122
+ throw new Error(`PDF 有 ${b.length} 页渲染失败:${b[0]}`);
1123
+ return f.length > 0 && n?.(`PDF 有 ${f.length} 处版式降级:${f.slice(0, 2).join(";")}`), c;
1124
+ };
1125
+ return o.checkFont = (r) => Pr(e.fontUrl, r), o;
1126
+ }
1127
+ class pe extends Error {
1128
+ constructor(t, o, r) {
1129
+ super(o), this.name = "MachReportError", this.code = t, this.cause = r;
1130
+ }
1131
+ }
1132
+ function $r(e) {
1133
+ return e instanceof pe ? { code: e.code, cause: e.cause } : { code: "render", cause: e };
1134
+ }
1135
+ function Cr(e) {
1136
+ const t = e.closest(".mrp-page-holder"), o = e.closest("[data-mr-component-index]");
1137
+ if (!t || !o) return null;
1138
+ const r = {
1139
+ pageIndex: Number(t.dataset.page) - 1,
1140
+ componentIndex: Number(o.dataset.mrComponentIndex),
1141
+ rowIndex: Number(e.dataset.mrRowIndex),
1142
+ columnIndex: Number(e.dataset.mrColumnIndex)
1143
+ };
1144
+ return Object.values(r).every((n) => Number.isInteger(n) && n >= 0) ? r : null;
1145
+ }
1146
+ function kr(e, t, o) {
1147
+ const r = e.ownerDocument.createElement("textarea");
1148
+ return r.className = "mrp-cell-editor", r.setAttribute("aria-label", t), r.value = o == null ? "" : String(o), r.style.cssText = "position:absolute;inset:0;width:100%;height:100%;min-height:20px;box-sizing:border-box;z-index:10;resize:none;margin:0;padding:2px 4px;border:2px solid #2563eb;outline:none;background:#fff;color:#111;font:inherit;line-height:1.25;white-space:pre-wrap;", e.appendChild(r), r;
1149
+ }
1150
+ function Mr(e) {
1151
+ const t = ye(null), o = A(!1), r = ye([]);
1152
+ let n = null;
1153
+ function a() {
1154
+ const i = t.value;
1155
+ t.value = null, o.value = !1, n = null, i?.controller.abort(), i?.input.remove();
1156
+ }
1157
+ function l() {
1158
+ a(), r.value = [];
1159
+ }
1160
+ function c(i) {
1161
+ return t.value === i && !i.controller.signal.aborted && e.plan.value === i.plan;
1162
+ }
1163
+ function m(i) {
1164
+ const x = e.options.value, $ = Mt(i.plan, i.address);
1165
+ if (!(typeof x == "object" ? x === i.options : x === !0) || !$?.editable || i.options.canEdit?.($) === !1)
1166
+ throw new Dt("readonly");
1167
+ }
1168
+ async function b(i) {
1169
+ try {
1170
+ m(i);
1171
+ const x = cn(i.plan, i.address, i.input.value);
1172
+ if (Object.is(x.value, x.previousValue))
1173
+ return a(), !0;
1174
+ const $ = { signal: i.controller.signal }, w = await i.options.validate?.(structuredClone(x), $);
1175
+ if (!c(i)) return !1;
1176
+ if (w) throw new Error(w);
1177
+ if (m(i), await i.options.save?.(structuredClone(x), $), !c(i)) return !1;
1178
+ m(i);
1179
+ const I = dn(i.plan, x);
1180
+ return a(), r.value = [...r.value, x], e.plan.value = I, e.onChange(structuredClone(x)), !0;
1181
+ } catch (x) {
1182
+ return c(i) && (e.onError(e.errorMessage?.(x) ?? (x instanceof Error ? x.message : "单元格保存失败"), x), i.input.disabled = !1, i.input.setAttribute("aria-invalid", "true"), i.input.focus()), !1;
1183
+ } finally {
1184
+ t.value === i && (o.value = !1);
1185
+ }
1186
+ }
1187
+ async function f() {
1188
+ if (n) return n;
1189
+ const i = t.value;
1190
+ if (!i) return !0;
1191
+ if (!c(i))
1192
+ return a(), !1;
1193
+ o.value = !0, i.input.disabled = !0;
1194
+ const x = b(i);
1195
+ n = x;
1196
+ const $ = await x;
1197
+ return n === x && (n = null), $;
1198
+ }
1199
+ function p(i) {
1200
+ i.stopPropagation(), !i.isComposing && (i.key === "Escape" && (i.preventDefault(), a()), i.key === "Enter" && !i.shiftKey && (i.preventDefault(), f()));
1201
+ }
1202
+ async function h(i) {
1203
+ if (!e.options.value || e.blocked()) return;
1204
+ const x = i.target;
1205
+ if (!(x instanceof Element) || x.closest(".mrp-cell-editor")) return;
1206
+ const $ = x.closest("td[data-mr-row-index]");
1207
+ if (!$ || !await f() || !$.isConnected) return;
1208
+ const w = e.plan.value, I = Cr($);
1209
+ if (!w || !I || !e.options.value || e.blocked()) return;
1210
+ const P = typeof e.options.value == "object" ? e.options.value : {};
1211
+ try {
1212
+ const O = Mt(w, I);
1213
+ if (!O?.editable || P.canEdit?.(O) === !1) return;
1214
+ const C = kr($, e.label(), O.value);
1215
+ t.value = { plan: w, address: I, input: C, controller: new AbortController(), options: P }, C.addEventListener("keydown", p), C.addEventListener("blur", () => {
1216
+ o.value || f();
1217
+ }), C.focus(), C.select();
1218
+ } catch (O) {
1219
+ e.onError(O instanceof Error ? O.message : "无法编辑单元格", O);
1220
+ }
1221
+ }
1222
+ return _(e.options, (i, x) => {
1223
+ (!i || i !== x) && a();
1224
+ }, { flush: "sync" }), _(e.plan, () => {
1225
+ t.value && e.plan.value !== t.value.plan && a();
1226
+ }, { flush: "sync" }), Re(l), {
1227
+ active: t,
1228
+ saving: o,
1229
+ changes: r,
1230
+ cancel: a,
1231
+ reset: l,
1232
+ commit: f,
1233
+ onDoubleClick: h,
1234
+ getChanges: () => structuredClone(r.value)
1235
+ };
1236
+ }
1237
+ const Fr = {
1238
+ key: 2,
1239
+ class: "mrp-edit-hint",
1240
+ role: "status"
1241
+ }, Rr = {
1242
+ key: 4,
1243
+ class: "mrp-export-notice mrp-export-warning",
1244
+ role: "status"
1245
+ }, Tr = { class: "mrp-main" }, Ir = {
1246
+ key: 0,
1247
+ class: "mrp-state"
1248
+ }, Sr = {
1249
+ key: 1,
1250
+ class: "mrp-state mrp-error"
1251
+ }, Dr = {
1252
+ key: 2,
1253
+ class: "mrp-state"
1254
+ }, Or = ["data-page"], Br = ["onClick"], Wr = ["data-thumb"], Ar = { class: "mrp-thumb-no" }, Lr = { class: "mrp-overlay" }, zr = {
1255
+ key: 5,
1256
+ class: "mrp-debug",
1257
+ "aria-hidden": "true"
1258
+ }, We = 96 / 25.4, ot = "mach-report:ui", lt = "mach-report:ui:wide", Hr = /* @__PURE__ */ ct({
1259
+ __name: "ReportPreview",
1260
+ props: {
1261
+ reportId: {
1262
+ type: [String, Array],
1263
+ default: null
1264
+ },
1265
+ params: {
1266
+ type: Object,
1267
+ default: () => ({})
1268
+ },
1269
+ height: { type: String, default: "100vh" },
1270
+ autoLoad: { type: Boolean, default: !0 },
1271
+ /** 以下显隐/间距不传时走配置中心(preset > defaults > 内置缺省) */
1272
+ showExport: { type: Boolean, default: void 0 },
1273
+ showPrint: { type: Boolean, default: void 0 },
1274
+ showPdfWindow: { type: Boolean, default: void 0 },
1275
+ /** 页间距(px);不传走配置中心 */
1276
+ gapPx: { type: Number, default: void 0 },
1277
+ /** 工具栏/状态文案覆写(不传走配置中心 messages) */
1278
+ messages: { type: Object, default: void 0 },
1279
+ /** 启用的 preset 名(不传用配置中心 defaultPreset) */
1280
+ preset: { type: String, default: void 0 },
1281
+ /** 调试面板(也可用 URL ?mrp-debug=1 开启) */
1282
+ debug: { type: Boolean, default: !1 },
1283
+ /** 参数定义(优先级:prop > 模板 params;有定义且未关闭时显示查询面板) */
1284
+ paramDefs: {
1285
+ type: Array,
1286
+ default: void 0
1287
+ },
1288
+ /** 参数面板显隐(不传走配置中心,缺省 true;有参数定义才渲染) */
1289
+ showParams: { type: Boolean, default: void 0 },
1290
+ editable: { type: [Boolean, Object], default: void 0 },
1291
+ excelImport: { type: [Boolean, Object], default: void 0 },
1292
+ fetcher: {
1293
+ type: Function,
1294
+ default: null
1295
+ }
1296
+ },
1297
+ emits: ["loaded", "error", "warning", "cell-edit", "template-import"],
1298
+ setup(e, { expose: t, emit: o }) {
1299
+ nn((s) => ({
1300
+ v587d5a34: H.value + "px"
1301
+ }));
1302
+ const r = e, n = o, a = ye(null), l = A(!1), c = A(""), m = ye(null), b = A(null), f = A(!1), p = ye(Object.freeze({ status: "unchecked", fontUrl: "" })), h = A(null), i = A(1), x = A(null), $ = A(null), w = A(null), I = A(!1), P = A(!1), O = A(null), C = Bn(), D = F(() => !!a.value?.pages.length && a.value.pages.every((s) => s.layout === "wide")), H = F(() => Math.max(0, ee.value));
1303
+ let K = ot;
1304
+ const X = He(hn, null), Q = He(bn, null), Y = F(() => Bt(r.reportId)), se = F(() => r.fetcher ?? X), U = F(() => a.value?.pages.length ?? 0), me = F(() => Object.freeze({
1305
+ loading: l.value,
1306
+ hasPlan: U.value > 0,
1307
+ pageCount: U.value,
1308
+ currentPage: i.value,
1309
+ exporting: b.value,
1310
+ printing: f.value,
1311
+ canExport: !l.value && !P.value && !q.saving.value && U.value > 0 && b.value === null,
1312
+ canPrint: !l.value && !P.value && !q.saving.value && U.value > 0 && !f.value,
1313
+ error: m.value,
1314
+ pdfFont: p.value,
1315
+ editing: q.active.value !== null,
1316
+ saving: q.saving.value,
1317
+ importing: P.value,
1318
+ dirty: q.changes.value.length > 0
1319
+ }));
1320
+ function J(s, v, g) {
1321
+ m.value = Object.freeze({ message: s, code: v, cause: g }), n("error", s, { code: v, cause: g });
1322
+ }
1323
+ const u = wr(), d = F(() => hr(u.value, r.preset)), y = F(() => ({
1324
+ ...d.value.messages,
1325
+ ...r.messages
1326
+ })), T = F(() => r.showExport ?? d.value.showExport), B = F(() => r.showPrint ?? d.value.showPrint), V = F(() => r.showPdfWindow ?? d.value.showPdfWindow), ee = F(() => r.gapPx ?? (D.value ? 0 : d.value.gapPx)), oe = F(() => r.showParams ?? d.value.showParams), mt = F(() => r.editable ?? d.value.editable), Te = F(() => r.excelImport ?? d.value.excelImport);
1327
+ function Lt(s) {
1328
+ return s instanceof Dt ? {
1329
+ number: y.value.editInvalidNumber,
1330
+ boolean: y.value.editInvalidBoolean,
1331
+ conflict: y.value.editConflict
1332
+ }[s.code] ?? s.message : s instanceof Error ? s.message : "单元格保存失败";
1333
+ }
1334
+ const q = Mr({
1335
+ plan: a,
1336
+ options: mt,
1337
+ blocked: () => l.value || P.value || b.value !== null || f.value,
1338
+ label: () => y.value.editCell ?? "编辑单元格",
1339
+ errorMessage: Lt,
1340
+ onChange: (s) => {
1341
+ m.value = null, h.value = null, n("cell-edit", s);
1342
+ },
1343
+ onError: (s, v) => {
1344
+ h.value = { kind: "error", message: s }, J(s, "edit", v);
1345
+ }
1346
+ });
1347
+ let vt = null, Ue = null;
1348
+ function gt() {
1349
+ if (Q) return Q;
1350
+ const s = d.value.pdfFontUrl;
1351
+ return (!Ue || vt !== s) && (vt = s, Ue = Er({ fontUrl: s })), Ue;
1352
+ }
1353
+ let Ie = 0, xe = null, Se = null, ie = !1;
1354
+ function Ve() {
1355
+ Ie++, xe?.abort(), xe = null;
1356
+ }
1357
+ async function De() {
1358
+ if (ie) throw new pe("config", "报表预览已卸载");
1359
+ Ve();
1360
+ const s = Ie, v = new AbortController();
1361
+ xe = v;
1362
+ const g = d.value.pdfFontUrl;
1363
+ p.value = Object.freeze({ status: "checking", fontUrl: g });
1364
+ try {
1365
+ const z = gt(), L = z.checkFont ? await z.checkFont(v.signal) : { status: "unverified", fontUrl: "", message: "自定义 PDF 导出器未提供字体预检查;字体由宿主确认" };
1366
+ return !ie && s === Ie && !v.signal.aborted && (p.value = Object.freeze({ ...L })), L;
1367
+ } catch (z) {
1368
+ if (v.signal.aborted) throw z;
1369
+ const L = {
1370
+ status: "error",
1371
+ fontUrl: g,
1372
+ message: z instanceof Error ? z.message : "PDF 字体检查失败",
1373
+ cause: z
1374
+ };
1375
+ return !ie && s === Ie && (p.value = Object.freeze(L)), L;
1376
+ } finally {
1377
+ xe === v && (xe = null);
1378
+ }
1379
+ }
1380
+ function zt() {
1381
+ De().catch(() => {
1382
+ });
1383
+ }
1384
+ _(
1385
+ [a, () => d.value.pdfFontUrl, T, V],
1386
+ () => {
1387
+ const s = p.value.fontUrl === d.value.pdfFontUrl;
1388
+ s && p.value.status === "available" || (Ve(), (!s || p.value.status === "checking") && (p.value = Object.freeze({ status: "unchecked", fontUrl: d.value.pdfFontUrl })), !ie && U.value > 0 && (T.value || V.value) && De().catch(() => {
1389
+ }));
1390
+ },
1391
+ { immediate: !0 }
1392
+ );
1393
+ const fe = F(
1394
+ () => r.paramDefs ?? se.value?.getParamDefs?.(Y.value) ?? []
1395
+ ), ve = A({}), Ke = A(!1);
1396
+ function Pe(s) {
1397
+ const v = {};
1398
+ for (const g of s)
1399
+ v[g.field] = r.params[g.field] ?? g.defaultValue ?? "";
1400
+ ve.value = v, Ke.value = !1;
1401
+ }
1402
+ Pe(fe.value), _(fe, (s) => Pe(s)), _(Y, () => Pe(fe.value)), _(() => JSON.stringify(r.params), () => Pe(fe.value));
1403
+ const Ht = F(() => {
1404
+ const s = { ...r.params };
1405
+ for (const [v, g] of Object.entries(ve.value))
1406
+ g === "" ? delete s[v] : s[v] = g;
1407
+ return s;
1408
+ });
1409
+ function Nt() {
1410
+ return fe.value.filter(
1411
+ (s) => s.required === !0 && !(ve.value[s.field] ?? "").trim()
1412
+ );
1413
+ }
1414
+ function jt() {
1415
+ Ke.value = !0;
1416
+ const s = Nt();
1417
+ if (s.length > 0) {
1418
+ const v = s[0].label ?? s[0].field, g = y.value.paramRequired.replace("{label}", v);
1419
+ c.value = g, J(g, "param");
1420
+ return;
1421
+ }
1422
+ ge();
1423
+ }
1424
+ function qt() {
1425
+ Pe(fe.value);
1426
+ }
1427
+ const Ut = F(() => ({
1428
+ height: r.height,
1429
+ ...br(d.value.theme)
1430
+ })), { zoom: te, zoomMode: Ee, applyFitZoom: ht, setZoom: $e } = xn(() => ({
1431
+ viewport: $.value,
1432
+ pageWidthPx: Ye.contentSize.value.w || 210 * We
1433
+ })), Ye = yn(a, te, {
1434
+ pxPerMm: We,
1435
+ gapPx: ee,
1436
+ overscan: F(() => d.value.preview.overscanPages)
1437
+ }), { contentSize: Ze, windowRange: Ce, visiblePages: bt, makeScrollHandler: Vt, refreshViewport: Je } = Ye, Kt = Vt(i, U);
1438
+ function Ge(s) {
1439
+ $e(s * 100);
1440
+ }
1441
+ function Oe() {
1442
+ P.value = !1, q.reset(), wt(), a.value = null, i.value = 1, N.reset();
1443
+ }
1444
+ let Z = 0, re = null;
1445
+ async function ge() {
1446
+ if (ie) return;
1447
+ const s = ++Z;
1448
+ P.value = !1, re?.abort(), re = null;
1449
+ const v = se.value;
1450
+ if (l.value = !1, m.value = null, Y.value.length === 0) {
1451
+ c.value = "缺少报表 ID", Oe(), J(c.value, "param");
1452
+ return;
1453
+ }
1454
+ if (!v) {
1455
+ c.value = "未提供渲染数据源 fetcher", Oe(), J(c.value, "config");
1456
+ return;
1457
+ }
1458
+ l.value = !0, c.value = "", h.value = null, Oe();
1459
+ const g = C.start(), z = new AbortController();
1460
+ re = z;
1461
+ const L = /* @__PURE__ */ new Set();
1462
+ function ae(W) {
1463
+ s !== Z || z.signal.aborted || L.has(W) || (L.add(W), d.value.logger.warn("[mach-report] 报表告警:", W), n("warning", W));
1464
+ }
1465
+ try {
1466
+ const W = await v({
1467
+ reportIds: Y.value,
1468
+ params: { ...Ht.value },
1469
+ signal: z.signal,
1470
+ onWarning: ae
1471
+ });
1472
+ if (s !== Z) return;
1473
+ const G = Ft(W);
1474
+ if (!G.ok) {
1475
+ const Be = G.errors.slice(0, 3).map(($t) => `${$t.path}: ${$t.message}`).join("; ");
1476
+ throw new pe(
1477
+ "validate",
1478
+ `渲染计划校验失败(${G.errors.length} 处): ${Be}`
1479
+ );
1480
+ }
1481
+ if (G.warnings.forEach((Be) => ae(`${Be.path}: ${Be.message}`)), s !== Z || z.signal.aborted) return;
1482
+ a.value = W, i.value = 1, C.end(g), $.value && ($.value.scrollTop = 0, $.value.scrollLeft = 0);
1483
+ const ne = D.value ? lt : ot;
1484
+ ne !== K && (K = ne, rt()), Ee.value === "fit" && ht(), n("loaded", W.pages.length);
1485
+ } catch (W) {
1486
+ if (s !== Z) return;
1487
+ const G = W instanceof pe ? W : W instanceof pn ? new pe(W.code, W.message, W.cause) : new pe(
1488
+ "fetch",
1489
+ W instanceof Error ? W.message : "预览加载失败",
1490
+ W
1491
+ );
1492
+ c.value = G.message;
1493
+ const ne = $r(G);
1494
+ J(G.message, ne.code, ne.cause);
1495
+ } finally {
1496
+ s === Z && (l.value = !1), re === z && (re = null);
1497
+ }
1498
+ }
1499
+ function ue(s) {
1500
+ if (ie || U.value <= 0) return;
1501
+ const v = Math.max(1, Math.min(U.value, s));
1502
+ i.value = v;
1503
+ const g = $.value;
1504
+ g && (g.scrollTop = Ye.pageOffsetPx(v - 1) * te.value, Je(g));
1505
+ }
1506
+ const ke = En(a, {
1507
+ getPdfExporter: gt,
1508
+ getXlsxOptions: () => d.value.xlsx,
1509
+ onError: (s, v) => {
1510
+ h.value = { kind: "error", message: s }, J(s, v ?? "print");
1511
+ },
1512
+ onWarning: (s) => {
1513
+ h.value = { kind: "warning", message: s }, n("warning", s);
1514
+ },
1515
+ onBusy: (s) => {
1516
+ b.value = s, s ? h.value = {
1517
+ kind: "progress",
1518
+ message: y.value.exporting.replace("{format}", s)
1519
+ } : h.value?.kind === "progress" && (h.value = null);
1520
+ },
1521
+ onPrinting: (s) => {
1522
+ f.value = s;
1523
+ }
1524
+ }), { releasePrintFrame: wt, dispose: Yt } = ke;
1525
+ async function Xe() {
1526
+ l.value || P.value || q.active.value && !await q.commit() || (m.value = null, await ke.print());
1527
+ }
1528
+ async function Qe(s) {
1529
+ l.value || P.value || q.active.value && !await q.commit() || (m.value = null, await ke.exportAs(s));
1530
+ }
1531
+ function _e() {
1532
+ if (l.value || P.value || q.active.value) {
1533
+ h.value = { kind: "warning", message: y.value.editingHint ?? "请先确认单元格修改" };
1534
+ return;
1535
+ }
1536
+ m.value = null, ke.openPdfWindow();
1537
+ }
1538
+ async function yt(s, v = {}) {
1539
+ ie || (ve.value = { ...ve.value, ...s }, v.reload !== !1 && await ge());
1540
+ }
1541
+ const Zt = {
1542
+ reload: ge,
1543
+ print: Xe,
1544
+ exportAs: Qe,
1545
+ openPdfWindow: _e,
1546
+ gotoPage: ue,
1547
+ setParams: yt,
1548
+ checkPdfFont: De,
1549
+ importExcel: et,
1550
+ getPlan: xt,
1551
+ getChanges: q.getChanges,
1552
+ get state() {
1553
+ return me.value;
1554
+ }
1555
+ };
1556
+ It(wn, Zt);
1557
+ function xt() {
1558
+ return a.value ? structuredClone(a.value) : null;
1559
+ }
1560
+ async function et(s, v) {
1561
+ if (ie) throw new pe("config", "报表预览已卸载");
1562
+ const g = ++Z;
1563
+ re?.abort(), re = null, l.value = !1, q.cancel(), ke.invalidatePending(), P.value = !0, m.value = null, h.value = { kind: "progress", message: y.value.importing ?? "正在导入 Excel…" };
1564
+ try {
1565
+ const { importExcelTemplate: z } = await import("@agile-team/mach-report/xlsx");
1566
+ if (g !== Z) return null;
1567
+ const L = typeof Te.value == "object" ? Te.value : {}, ae = await z(s, { ...L, ...v, limits: { ...L.limits, ...v?.limits } });
1568
+ if (g !== Z) return null;
1569
+ const W = fn(structuredClone(ae.template), {}).plan, G = Ft(W);
1570
+ if (!G.ok) throw new Error(G.errors.map((ne) => ne.message).slice(0, 3).join("; "));
1571
+ for (const ne of ae.warnings) {
1572
+ if (g !== Z) return null;
1573
+ n("warning", ne);
1574
+ }
1575
+ return g !== Z ? null : (q.reset(), wt(), N.reset(), a.value = W, i.value = 1, c.value = "", h.value = ae.warnings.length ? { kind: "warning", message: ae.warnings.join(";") } : null, $.value && ($.value.scrollTop = 0, $.value.scrollLeft = 0), K = D.value ? lt : ot, rt(), n("template-import", ae), g === Z && n("loaded", W.pages.length), ae);
1576
+ } catch (z) {
1577
+ if (g !== Z) return null;
1578
+ const L = new pe("import", z instanceof Error ? z.message : "Excel 模板导入失败", z);
1579
+ throw h.value = { kind: "error", message: L.message }, J(L.message, "import", z), L;
1580
+ } finally {
1581
+ g === Z && (P.value = !1);
1582
+ }
1583
+ }
1584
+ function Jt(s) {
1585
+ const v = s.target, g = v.files?.[0];
1586
+ v.value = "", g && et(g).catch(() => {
1587
+ });
1588
+ }
1589
+ const N = Sn({
1590
+ plan: a,
1591
+ gotoPage: ue,
1592
+ debounceMs: F(() => d.value.preview.searchDebounceMs),
1593
+ highlight: Cn,
1594
+ clearHighlights: $n
1595
+ });
1596
+ function Gt(s) {
1597
+ s.ctrlKey && (s.preventDefault(), Ge(te.value * (s.deltaY < 0 ? 1.1 : 1 / 1.1)));
1598
+ }
1599
+ function Xt(s) {
1600
+ if (!(s.target instanceof Element && s.target.closest("input,textarea,select,[contenteditable='true']"))) {
1601
+ if ((s.ctrlKey || s.metaKey) && s.key.toLowerCase() === "f") {
1602
+ s.preventDefault(), N.visible.value || N.toggle();
1603
+ return;
1604
+ }
1605
+ switch (s.key) {
1606
+ case "PageDown":
1607
+ s.preventDefault(), ue(i.value + 1);
1608
+ break;
1609
+ case "PageUp":
1610
+ s.preventDefault(), ue(i.value - 1);
1611
+ break;
1612
+ case "Home":
1613
+ s.preventDefault(), ue(1);
1614
+ break;
1615
+ case "End":
1616
+ s.preventDefault(), ue(U.value);
1617
+ break;
1618
+ case "+":
1619
+ case "=":
1620
+ s.preventDefault(), Ge(te.value * 1.1);
1621
+ break;
1622
+ case "-":
1623
+ s.preventDefault(), Ge(te.value / 1.1);
1624
+ break;
1625
+ }
1626
+ }
1627
+ }
1628
+ function Qt() {
1629
+ try {
1630
+ localStorage.setItem(
1631
+ K,
1632
+ JSON.stringify({ zoomMode: Ee.value === "fit" ? "fit" : Math.round(te.value * 100) })
1633
+ );
1634
+ } catch {
1635
+ }
1636
+ }
1637
+ _([Ee, te], Qt);
1638
+ let tt = "";
1639
+ const Pt = /* @__PURE__ */ new WeakMap();
1640
+ function Et(s = !1) {
1641
+ const v = N.activeMatch.value;
1642
+ if (!D.value || !v) return;
1643
+ const g = `${N.query.value}:${N.matchIndex.value}:${v.pageIndex}`;
1644
+ if (!s && g === tt) return;
1645
+ const L = x.value?.querySelector(`[data-page="${v.pageIndex + 1}"]`)?.querySelectorAll("mark.mrp-hit")[v.occurrence];
1646
+ L && (L.scrollIntoView?.({ block: "nearest", inline: "nearest" }), tt = g);
1647
+ }
1648
+ kt(() => {
1649
+ const s = a.value;
1650
+ if (!s) return;
1651
+ const v = N.activeMatch.value;
1652
+ N.matchIndex.value, v || (tt = ""), bt.value;
1653
+ const g = x.value;
1654
+ if (!g) return;
1655
+ g.querySelectorAll(".mrp-page-holder").forEach((L) => {
1656
+ const ae = Number(L.dataset.page ?? 0) - 1, W = s.pages[ae];
1657
+ if (!W || L.childElementCount > 0 && Pt.get(L) === W) {
1658
+ if (L.firstElementChild) {
1659
+ const ne = L.firstElementChild;
1660
+ N.clear(ne), N.apply(ne);
1661
+ }
1662
+ return;
1663
+ }
1664
+ L.style.width = `${W.pageWidthMm * We}px`;
1665
+ const G = St(W, 96, {}, document);
1666
+ N.apply(G), L.replaceChildren(G), Pt.set(L, W);
1667
+ }), Et();
1668
+ }, { flush: "post" }), _(() => N.query.value, (s) => {
1669
+ s || x.value?.querySelectorAll(".mrp-page-holder").forEach((v) => {
1670
+ N.clear(v);
1671
+ });
1672
+ });
1673
+ const le = On(a, {
1674
+ thumbsRoot: w,
1675
+ visible: I,
1676
+ renderThumbCanvas: (s) => {
1677
+ try {
1678
+ const v = a.value.pages[s], g = Math.min(0.2, 116 / Math.max(1, v.pageWidthMm * We)), { canvases: z } = mn(a.value, { start: s, end: s, dpr: g });
1679
+ return z[0] ?? null;
1680
+ } catch {
1681
+ return null;
1682
+ }
1683
+ }
1684
+ });
1685
+ kt(() => {
1686
+ le.schedule();
1687
+ }, { flush: "post" });
1688
+ const _t = F(() => r.debug), { debugStats: be } = Dn(_t, {
1689
+ plan: a,
1690
+ pageCount: U,
1691
+ windowRange: Ce,
1692
+ zoom: te,
1693
+ loadMs: C.loadMs
1694
+ });
1695
+ function nt() {
1696
+ Je($.value), le.schedule(), Ee.value === "fit" && ht(), Et(!0);
1697
+ }
1698
+ function rt() {
1699
+ $e(K === lt ? 100 : "fit");
1700
+ try {
1701
+ const s = JSON.parse(localStorage.getItem(K) ?? "{}");
1702
+ s.zoomMode === "fit" ? $e("fit") : typeof s.zoomMode == "number" && $e(s.zoomMode);
1703
+ } catch {
1704
+ }
1705
+ }
1706
+ return rn(() => {
1707
+ window.addEventListener("resize", nt), typeof ResizeObserver < "u" && $.value && (Se = new ResizeObserver(nt), Se.observe($.value)), Je($.value), rt(), r.autoLoad && ge();
1708
+ }), an(() => {
1709
+ ie = !0, q.reset(), P.value = !1, Ve(), Z++, re?.abort(), re = null, window.removeEventListener("resize", nt), Se?.disconnect(), Se = null, le.destroy(), N.reset(), Yt();
1710
+ }), _(
1711
+ () => [JSON.stringify(Y.value), JSON.stringify(r.params), se.value],
1712
+ () => {
1713
+ if (r.autoLoad) {
1714
+ ge();
1715
+ return;
1716
+ }
1717
+ Z++, re?.abort(), re = null, l.value = !1, c.value = "", m.value = null, h.value = null, Oe();
1718
+ }
1719
+ ), t({ reload: ge, print: Xe, exportAs: Qe, openPdfWindow: _e, gotoPage: ue, setParams: yt, checkPdfFont: De, importExcel: et, getPlan: xt, getChanges: q.getChanges, state: me }), (s, v) => (k(), M("div", {
1720
+ class: de(["mach-report-preview", { "mrp-wide-report": D.value }]),
1721
+ style: ce(Ut.value)
1722
+ }, [
1723
+ oe.value && fe.value.length > 0 ? (k(), on(pr, {
1724
+ key: 0,
1725
+ defs: fe.value,
1726
+ modelValue: ve.value,
1727
+ "onUpdate:modelValue": v[0] || (v[0] = (g) => ve.value = g),
1728
+ messages: y.value,
1729
+ attempted: Ke.value,
1730
+ onQuery: jt,
1731
+ onReset: qt
1732
+ }, null, 8, ["defs", "modelValue", "messages", "attempted"])) : j("", !0),
1733
+ ln(tr, {
1734
+ "page-count": U.value,
1735
+ "current-page": i.value,
1736
+ "zoom-mode": E(Ee),
1737
+ zoom: E(te),
1738
+ "show-export": T.value,
1739
+ "show-print": B.value,
1740
+ "show-pdf-window": V.value,
1741
+ messages: y.value,
1742
+ search: { visible: E(N).visible.value, query: E(N).query.value, matchIndex: E(N).matchIndex.value, matchCount: E(N).matchCount.value, searching: E(N).searching.value },
1743
+ "thumbs-visible": I.value,
1744
+ "show-import": !!Te.value,
1745
+ busy: l.value || P.value || E(q).saving.value,
1746
+ onGoto: ue,
1747
+ onZoom: E($e),
1748
+ onExport: v[1] || (v[1] = (g) => Qe(g)),
1749
+ onPrint: Xe,
1750
+ onPdfWindow: _e,
1751
+ onSearchInput: E(N).onInput,
1752
+ onSearchNav: E(N).onNav,
1753
+ onSearchToggle: E(N).toggle,
1754
+ onThumbsToggle: v[2] || (v[2] = (g) => I.value = !I.value),
1755
+ onImportExcel: v[3] || (v[3] = (g) => O.value?.click())
1756
+ }, null, 8, ["page-count", "current-page", "zoom-mode", "zoom", "show-export", "show-print", "show-pdf-window", "messages", "search", "thumbs-visible", "show-import", "busy", "onZoom", "onSearchInput", "onSearchNav", "onSearchToggle"]),
1757
+ Te.value ? (k(), M("input", {
1758
+ key: 1,
1759
+ ref_key: "importInputRef",
1760
+ ref: O,
1761
+ class: "mrp-import-input",
1762
+ type: "file",
1763
+ accept: ".xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
1764
+ hidden: "",
1765
+ onChange: Jt
1766
+ }, null, 544)) : j("", !0),
1767
+ mt.value && U.value > 0 ? (k(), M("div", Fr, R(E(q).saving.value ? y.value.saving : y.value.editingHint), 1)) : j("", !0),
1768
+ h.value ? (k(), M("div", {
1769
+ key: 3,
1770
+ class: de(["mrp-export-notice", `mrp-export-${h.value.kind}`]),
1771
+ role: "alert"
1772
+ }, R(h.value.message), 3)) : j("", !0),
1773
+ p.value.status === "error" && (T.value || V.value) ? (k(), M("div", Rr, [
1774
+ st(R(y.value.pdfFontUnavailable) + " ", 1),
1775
+ S("button", {
1776
+ type: "button",
1777
+ onClick: zt
1778
+ }, R(y.value.retry), 1)
1779
+ ])) : j("", !0),
1780
+ S("div", Tr, [
1781
+ S("div", {
1782
+ ref_key: "viewportRef",
1783
+ ref: $,
1784
+ class: "mrp-body",
1785
+ tabindex: "0",
1786
+ onWheel: Gt,
1787
+ onKeydown: Xt,
1788
+ onDblclick: v[4] || (v[4] = //@ts-ignore
1789
+ (...g) => E(q).onDoubleClick && E(q).onDoubleClick(...g)),
1790
+ onScrollPassive: v[5] || (v[5] = (g) => E(Kt)(g.target))
1791
+ }, [
1792
+ l.value ? (k(), M("div", Ir, R(y.value.loading), 1)) : c.value ? (k(), M("div", Sr, [
1793
+ st(R(c.value) + " ", 1),
1794
+ S("button", {
1795
+ class: "mrp-retry",
1796
+ type: "button",
1797
+ onClick: ge
1798
+ }, R(y.value.retry), 1)
1799
+ ])) : !a.value || U.value === 0 ? (k(), M("div", Dr, R(y.value.empty), 1)) : (k(), M("div", {
1800
+ key: 3,
1801
+ class: "mrp-scale",
1802
+ style: ce({ width: `${E(Ze).w * E(te)}px`, height: `${E(Ze).h * E(te)}px` })
1803
+ }, [
1804
+ S("div", {
1805
+ ref_key: "containerRef",
1806
+ ref: x,
1807
+ class: "mrp-scale-inner",
1808
+ style: ce({ transform: `scale(${E(te)})`, transformOrigin: "top left", width: `${E(Ze).w}px` })
1809
+ }, [
1810
+ E(Ce).padTopPx > 0 ? (k(), M("div", {
1811
+ key: 0,
1812
+ class: "mrp-spacer-top",
1813
+ style: ce({ height: `${E(Ce).padTopPx}px` }),
1814
+ "aria-hidden": "true"
1815
+ }, null, 4)) : j("", !0),
1816
+ (k(!0), M(Fe, null, ze(E(bt), (g) => (k(), M("div", {
1817
+ key: g.index,
1818
+ class: "mrp-page-holder",
1819
+ "data-page": g.index + 1
1820
+ }, null, 8, Or))), 128)),
1821
+ E(Ce).padBottomPx > 0 ? (k(), M("div", {
1822
+ key: 1,
1823
+ class: "mrp-spacer-bottom",
1824
+ style: ce({ height: `${E(Ce).padBottomPx}px` }),
1825
+ "aria-hidden": "true"
1826
+ }, null, 4)) : j("", !0)
1827
+ ], 4)
1828
+ ], 4))
1829
+ ], 544),
1830
+ I.value && U.value > 0 ? (k(), M("aside", {
1831
+ key: 0,
1832
+ ref_key: "thumbsRef",
1833
+ ref: w,
1834
+ class: "mrp-thumbs",
1835
+ onScrollPassive: v[6] || (v[6] = //@ts-ignore
1836
+ (...g) => E(le).onScroll && E(le).onScroll(...g))
1837
+ }, [
1838
+ E(le).windowRange.value.padTopPx > 0 ? (k(), M("div", {
1839
+ key: 0,
1840
+ class: "mrp-thumb-spacer",
1841
+ style: ce({ height: `${E(le).windowRange.value.padTopPx}px` }),
1842
+ "aria-hidden": "true"
1843
+ }, null, 4)) : j("", !0),
1844
+ (k(!0), M(Fe, null, ze(E(le).visibleThumbs.value, (g) => (k(), M("div", {
1845
+ key: g.index,
1846
+ class: de(["mrp-thumb", { "mrp-thumb-active": g.index + 1 === i.value }]),
1847
+ style: ce({ height: `${g.height + 20}px` }),
1848
+ onClick: (z) => ue(g.index + 1)
1849
+ }, [
1850
+ S("div", {
1851
+ class: "mrp-thumb-box",
1852
+ "data-thumb": g.index + 1,
1853
+ style: ce({ height: `${g.height}px` })
1854
+ }, null, 12, Wr),
1855
+ S("span", Ar, R(g.index + 1), 1)
1856
+ ], 14, Br))), 128)),
1857
+ E(le).windowRange.value.padBottomPx > 0 ? (k(), M("div", {
1858
+ key: 1,
1859
+ class: "mrp-thumb-spacer",
1860
+ style: ce({ height: `${E(le).windowRange.value.padBottomPx}px` }),
1861
+ "aria-hidden": "true"
1862
+ }, null, 4)) : j("", !0)
1863
+ ], 544)) : j("", !0)
1864
+ ]),
1865
+ S("div", Lr, [
1866
+ sn(s.$slots, "default", {}, void 0, !0)
1867
+ ]),
1868
+ E(be) ? (k(), M("div", zr, [
1869
+ v[7] || (v[7] = S("div", null, "mach-report debug", -1)),
1870
+ S("div", null, "pages: " + R(E(be).pages) + " | window: [" + R(E(be).window) + "]", 1),
1871
+ S("div", null, "zoom: " + R(E(be).zoom) + " | load: " + R(E(be).loadMs), 1),
1872
+ S("div", null, "plan: " + R(E(be).planKB) + "KB", 1)
1873
+ ])) : j("", !0)
1874
+ ], 6));
1875
+ }
1876
+ }), Nr = /* @__PURE__ */ pt(Hr, [["__scopeId", "data-v-8dab9187"]]), _r = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1877
+ __proto__: null,
1878
+ default: Nr
1879
+ }, Symbol.toStringTag, { value: "Module" }));
1880
+ export {
1881
+ mr as D,
1882
+ pe as M,
1883
+ at as P,
1884
+ pr as R,
1885
+ Xr as S,
1886
+ vr as a,
1887
+ Nr as b,
1888
+ tr as c,
1889
+ Wt as d,
1890
+ Pn as e,
1891
+ Er as f,
1892
+ Zr as g,
1893
+ gr as h,
1894
+ Gr as i,
1895
+ Yr as j,
1896
+ Qr as k,
1897
+ $r as l,
1898
+ yn as m,
1899
+ Bt as n,
1900
+ En as o,
1901
+ Jr as p,
1902
+ xn as q,
1903
+ hr as r,
1904
+ _r as s,
1905
+ br as t,
1906
+ wr as u
1907
+ };