@agile-team/mach-report 1.2.1 → 2.0.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 (45) hide show
  1. package/README.md +86 -255
  2. package/dist/ReportPreview-Cr0IH1Rz.cjs +6 -0
  3. package/dist/ReportPreview-DwknBgsJ.js +1266 -0
  4. package/dist/defaults.d.ts +3 -7
  5. package/dist/format.d.ts +1 -1
  6. package/dist/index.cjs +5 -5
  7. package/dist/index.d.cts +0 -1
  8. package/dist/index.d.ts +0 -1
  9. package/dist/index.js +621 -758
  10. package/dist/layout/textwrap.d.ts +1 -1
  11. package/dist/pdf.cjs +1 -1
  12. package/dist/pdf.js +1 -1
  13. package/dist/plugin-Cj3c2wJc.cjs +1 -0
  14. package/dist/plugin-DJf_6_fl.js +18 -0
  15. package/dist/schema/render-plan.d.ts +1 -9
  16. package/dist/sql/expr.d.ts +3 -3
  17. package/dist/sql.d.cts +1 -1
  18. package/dist/sql.d.ts +1 -1
  19. package/dist/style-CFZ-HE2s.cjs +3 -0
  20. package/dist/{style-6ihHKVCM.js → style-DnmtG7Gl.js} +69 -81
  21. package/dist/style.css +1 -1
  22. package/dist/vue/ReportPreview.d.ts +3 -12
  23. package/dist/vue/adapters.d.ts +6 -12
  24. package/dist/vue/async.d.cts +7 -22
  25. package/dist/vue/async.d.ts +7 -22
  26. package/dist/vue/local-adapter.d.ts +1 -2
  27. package/dist/vue/plugin.d.ts +12 -34
  28. package/dist/vue-async.cjs +1 -1
  29. package/dist/vue-async.js +6 -6
  30. package/dist/vue.cjs +1 -1
  31. package/dist/vue.js +48 -48
  32. package/package.json +2 -12
  33. package/dist/ReportPreview-CJLvkTVn.cjs +0 -6
  34. package/dist/ReportPreview-mZiGtf0L.js +0 -1231
  35. package/dist/compat/jh4j-template.d.ts +0 -12
  36. package/dist/manager/api.d.ts +0 -45
  37. package/dist/manager/index.d.ts +0 -2
  38. package/dist/manager/types.d.ts +0 -50
  39. package/dist/manager.cjs +0 -1
  40. package/dist/manager.d.cts +0 -5
  41. package/dist/manager.d.ts +0 -5
  42. package/dist/manager.js +0 -104
  43. package/dist/plugin-C4qpbdMJ.cjs +0 -1
  44. package/dist/plugin-DcmAPK_K.js +0 -85
  45. package/dist/style-Xq08-IsV.cjs +0 -3
@@ -0,0 +1,1266 @@
1
+ import { computed as k, unref as x, ref as F, shallowRef as Oe, defineComponent as Ee, watch as A, nextTick as lt, openBlock as w, createElementBlock as P, createElementVNode as E, toDisplayString as y, Fragment as ee, createCommentVNode as S, normalizeClass as N, renderList as ie, createTextVNode as Ae, withKeys as De, inject as ue, provide as Ne, useCssVars as it, watchEffect as Le, onMounted as ut, onUnmounted as ct, normalizeStyle as Y, createBlock as dt, createVNode as ft, renderSlot as pt } from "vue";
2
+ import { computePageWindow as mt, renderPlanToImages as gt, renderPage as qe, validateRenderPlan as vt, renderPlanToCanvas as ht } from "@agile-team/mach-report";
3
+ import { a as xe, b as bt, c as wt, M as yt } from "./plugin-DJf_6_fl.js";
4
+ function Ue(e) {
5
+ return e == null ? [] : Array.isArray(e) ? e.map(String).filter((t) => t !== "") : String(e).split(",").map((t) => t.trim()).filter((t) => t !== "");
6
+ }
7
+ function Cn(e) {
8
+ return Ue(e).join(",");
9
+ }
10
+ class Pe extends Error {
11
+ constructor(t) {
12
+ super(t), this.name = "PlanLoadError";
13
+ }
14
+ }
15
+ function Mn(e = {}) {
16
+ const { baseUrl: t = "", headers: a, credentials: r, timeoutMs: o = 3e4 } = e, n = t.replace(/\/+$/, "");
17
+ return async ({ url: l, method: f, params: i }) => {
18
+ const p = i && Object.keys(i).length > 0 ? `?${new URLSearchParams(i)}` : "", c = new AbortController(), g = setTimeout(() => c.abort(), o);
19
+ let $;
20
+ try {
21
+ $ = await fetch(`${n}${l}${p}`, {
22
+ method: f.toUpperCase(),
23
+ headers: { Accept: "application/json", ...a },
24
+ credentials: r,
25
+ signal: c.signal
26
+ });
27
+ } catch (b) {
28
+ throw b instanceof DOMException && b.name === "AbortError" ? new Pe(`请求超时(${o}ms): ${l}`) : new Pe(`请求失败(${l}): ${b instanceof Error ? b.message : String(b)}`);
29
+ } finally {
30
+ clearTimeout(g);
31
+ }
32
+ if (!$.ok)
33
+ throw new Pe(`HTTP ${$.status} ${l}`);
34
+ return $.json();
35
+ };
36
+ }
37
+ function Pt(e, t, a = {}) {
38
+ const r = a.pxPerMm ?? 3.7795275590551185, o = k(() => Math.max(0, x(a.gapPx) ?? 18)), n = F(0), l = F(800), f = k(
39
+ () => (e.value?.pages ?? []).map(($) => $.pageHeightMm * r)
40
+ ), i = k(() => {
41
+ const $ = e.value?.pages ?? [];
42
+ let b = 0, T = 0;
43
+ for (const B of $)
44
+ b += B.pageHeightMm * r + o.value, T = Math.max(T, B.pageWidthMm * r);
45
+ return { w: T, h: b };
46
+ }), p = k(
47
+ () => mt({
48
+ pageHeightsPx: f.value,
49
+ viewportHeightPx: l.value / t.value,
50
+ scrollTopPx: n.value / t.value,
51
+ overscan: 1,
52
+ gapPx: o.value
53
+ })
54
+ ), c = k(() => {
55
+ const $ = e.value;
56
+ if (!$) return [];
57
+ const { start: b, end: T } = p.value;
58
+ return T < b ? [] : $.pages.slice(b, T + 1).map((B, z) => ({ page: B, index: b + z }));
59
+ });
60
+ function g($, b) {
61
+ let T = 0;
62
+ return (B) => {
63
+ T || (T = requestAnimationFrame(() => {
64
+ if (T = 0, n.value = B.scrollTop, l.value = B.clientHeight || 800, b.value <= 0) return;
65
+ const z = B.querySelectorAll(".mrp-page-holder");
66
+ if (!z.length) return;
67
+ const u = B.getBoundingClientRect().top + 56;
68
+ let v = 1;
69
+ z.forEach((d) => {
70
+ d.getBoundingClientRect().top <= u && (v = Number(d.dataset.page ?? 1));
71
+ }), $.value = Math.max(1, Math.min(b.value, v));
72
+ }));
73
+ };
74
+ }
75
+ return {
76
+ contentSize: i,
77
+ windowRange: p,
78
+ visiblePages: c,
79
+ makeScrollHandler: g,
80
+ refreshViewport($) {
81
+ $ && (l.value = $.clientHeight || 800);
82
+ }
83
+ };
84
+ }
85
+ function xt(e) {
86
+ const t = F(1), a = F("fit");
87
+ function r() {
88
+ requestAnimationFrame(() => {
89
+ const n = e();
90
+ !n || !n.viewport || (t.value = Math.min(
91
+ 1,
92
+ Math.max(0.3, (n.viewport.clientWidth - 48) / Math.max(1, n.pageWidthPx))
93
+ ));
94
+ });
95
+ }
96
+ function o(n) {
97
+ n === "fit" ? (a.value = "fit", r()) : (a.value = "raw", t.value = n / 100);
98
+ }
99
+ return { zoom: t, zoomMode: a, applyFitZoom: r, setZoom: o };
100
+ }
101
+ const ce = 8;
102
+ function de() {
103
+ return new Promise((e) => setTimeout(e, 0));
104
+ }
105
+ function se(e) {
106
+ return `p${Math.round(e.pageWidthMm)}x${Math.round(e.pageHeightMm)}`;
107
+ }
108
+ function $e(e) {
109
+ const t = /* @__PURE__ */ new Map();
110
+ return e.pages.forEach((o) => {
111
+ t.has(se(o)) || t.set(se(o), o);
112
+ }), `<!doctype html><html><head><meta charset="utf-8"><style>${`.mr-page{margin:0 auto;page-break-after:always;}
113
+ .mr-page tr{break-inside:avoid;page-break-inside:avoid;}
114
+ .mr-comp{break-inside:avoid;page-break-inside:avoid;}
115
+ ${[...t.values()].map(
116
+ (o) => `@page ${se(o)}{size:${Math.round(o.pageWidthMm)}mm ${Math.round(o.pageHeightMm)}mm;margin:0;}`
117
+ ).join(`
118
+ `)}
119
+ body{margin:0;background:#fff;}`}</style></head><body>`;
120
+ }
121
+ function Ce(e) {
122
+ const t = qe(e, 96, {}, document);
123
+ return t.style.page = se(e), t.outerHTML;
124
+ }
125
+ function Ve(e) {
126
+ return { head: $e(e), pageChunks: e.pages.map(Ce) };
127
+ }
128
+ async function kn(e, t = {}) {
129
+ const a = {
130
+ schemaVersion: "mach-report-batch-print",
131
+ pages: e.flatMap((l) => l.pages)
132
+ };
133
+ if (a.pages.length === 0) return;
134
+ const r = $e(a), o = document.createElement("iframe");
135
+ o.style.cssText = "position:fixed;right:0;bottom:0;width:0;height:0;border:0;visibility:hidden;", document.body.appendChild(o);
136
+ let n = !1;
137
+ try {
138
+ const l = o.contentDocument;
139
+ l.open(), l.write(r);
140
+ for (let f = 0; f < a.pages.length; f++)
141
+ l.write(Ce(a.pages[f])), f % ce === ce - 1 && (t.onProgress?.(f + 1, a.pages.length), await de());
142
+ l.write("</body></html>"), l.close(), await de(), t.onProgress?.(a.pages.length, a.pages.length), n = !0, o.contentWindow?.focus(), o.contentWindow?.print();
143
+ } catch (l) {
144
+ t.onError?.(l instanceof Error ? `批量打印失败: ${l.message}` : "批量打印失败");
145
+ } finally {
146
+ n ? setTimeout(() => o.remove(), 6e4) : o.remove();
147
+ }
148
+ }
149
+ function Et(e) {
150
+ const { head: t, pageChunks: a } = Ve(e);
151
+ return {
152
+ 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>/, "")}`}${a.join("")}</body></html>`,
153
+ filename: "mach-report.doc"
154
+ };
155
+ }
156
+ function $t(e, t) {
157
+ let a = null, r = !1, o = null, n = null, l = null;
158
+ function f() {
159
+ a?.remove(), a = null;
160
+ }
161
+ function i(u, v) {
162
+ const d = URL.createObjectURL(u), m = document.createElement("a");
163
+ m.href = d, m.download = v, m.click(), setTimeout(() => URL.revokeObjectURL(d), 1e4);
164
+ }
165
+ async function p() {
166
+ if (r) return;
167
+ const u = e.value;
168
+ if (!u || u.pages.length === 0) return;
169
+ r = !0, f();
170
+ const v = $e(u);
171
+ a = document.createElement("iframe"), a.style.cssText = "position:fixed;right:0;bottom:0;width:0;height:0;border:0;visibility:hidden;", document.body.appendChild(a);
172
+ const d = a;
173
+ try {
174
+ const m = d.contentDocument;
175
+ m.open(), m.write(v);
176
+ for (let C = 0; C < u.pages.length; C++)
177
+ if (m.write(Ce(u.pages[C])), C % ce === ce - 1 && await de(), d !== a) return;
178
+ m.write("</body></html>"), m.close(), await de(), d.contentWindow?.focus(), d.contentWindow?.print();
179
+ } catch {
180
+ t.onError("调用打印失败,请改用导出 PDF");
181
+ } finally {
182
+ r = !1;
183
+ }
184
+ }
185
+ function c(u) {
186
+ if (o?.plan === u) return o.promise;
187
+ const v = t.getPdfExporter()(u, t.onWarning).finally(() => {
188
+ o?.promise === v && (o = null);
189
+ });
190
+ return o = { plan: u, promise: v }, v;
191
+ }
192
+ async function g() {
193
+ const u = e.value;
194
+ if (!u || u.pages.length === 0) return;
195
+ if (n?.plan === u) return n.promise;
196
+ t.onBusy?.("PDF");
197
+ const v = {}, d = (async () => {
198
+ try {
199
+ const m = await c(u);
200
+ if (e.value !== u) return;
201
+ i(new Blob([m], { type: "application/pdf" }), "mach-report.pdf");
202
+ } catch (m) {
203
+ t.onError(m instanceof Error ? `PDF 导出失败: ${m.message}` : "PDF 导出失败", "pdf");
204
+ } finally {
205
+ t.onBusy?.(null), n?.token === v && (n = null);
206
+ }
207
+ })();
208
+ return n = { plan: u, promise: d, token: v }, d;
209
+ }
210
+ async function $() {
211
+ const u = e.value;
212
+ if (!(!u || u.pages.length === 0)) {
213
+ t.onBusy?.("Excel");
214
+ try {
215
+ const { renderPlanToXlsx: v } = await import("@agile-team/mach-report/xlsx"), { buffer: d, warnings: m } = await v(u);
216
+ if (e.value !== u) return;
217
+ m.length > 0 && t.onWarning?.(`Excel 有 ${m.length} 处内容未导出:${m.slice(0, 2).join(";")}`), i(new Blob([d], {
218
+ type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
219
+ }), "mach-report.xlsx");
220
+ } catch (v) {
221
+ t.onError(v instanceof Error ? `Excel 导出失败: ${v.message}` : "Excel 导出失败", "export");
222
+ } finally {
223
+ t.onBusy?.(null);
224
+ }
225
+ }
226
+ }
227
+ async function b() {
228
+ const u = e.value;
229
+ if (!u || u.pages.length === 0) return;
230
+ if (l?.plan === u) return l.promise;
231
+ t.onBusy?.("图片");
232
+ const v = {}, d = (async () => {
233
+ try {
234
+ const { blobs: m } = await gt(u, {
235
+ dpr: Math.min(2, typeof devicePixelRatio == "number" ? devicePixelRatio : 1)
236
+ });
237
+ if (e.value !== u) return;
238
+ m.forEach((C, W) => {
239
+ i(C, m.length > 1 ? `mach-report-page-${W + 1}.png` : "mach-report.png");
240
+ });
241
+ } catch (m) {
242
+ t.onError(
243
+ m instanceof Error ? `图片导出失败: ${m.message}` : "图片导出失败",
244
+ "export"
245
+ );
246
+ } finally {
247
+ t.onBusy?.(null), l?.token === v && (l = null);
248
+ }
249
+ })();
250
+ return l = { plan: u, promise: d, token: v }, d;
251
+ }
252
+ function T() {
253
+ const u = e.value;
254
+ if (!(!u || u.pages.length === 0))
255
+ try {
256
+ const { html: v, filename: d } = Et(u);
257
+ i(new Blob([v], { type: "application/msword;charset=utf-8" }), d);
258
+ } catch (v) {
259
+ t.onError(
260
+ v instanceof Error ? `Word 导出失败: ${v.message}` : "Word 导出失败",
261
+ "export"
262
+ );
263
+ }
264
+ }
265
+ function B(u) {
266
+ const v = e.value;
267
+ if (!v || v.pages.length === 0) return;
268
+ if (u === "pdf") {
269
+ g();
270
+ return;
271
+ }
272
+ if (u === "xlsx" || u === "excel") {
273
+ $();
274
+ return;
275
+ }
276
+ if (u === "png" || u === "image") {
277
+ b();
278
+ return;
279
+ }
280
+ if (u === "word" || u === "doc") {
281
+ T();
282
+ return;
283
+ }
284
+ if (u !== "html") {
285
+ t.onError(`不支持的导出格式:${u}`, "export");
286
+ return;
287
+ }
288
+ const { head: d, pageChunks: m } = Ve(v), C = `${d}${m.join("")}</body></html>`;
289
+ i(new Blob([C], { type: "text/html;charset=utf-8" }), "mach-report.html");
290
+ }
291
+ function z() {
292
+ const u = e.value;
293
+ if (!u || u.pages.length === 0) return;
294
+ const v = window.open("", "_blank");
295
+ if (!v) {
296
+ t.onError("浏览器拦截了弹窗,请允许弹窗后重试");
297
+ return;
298
+ }
299
+ c(u).then((d) => {
300
+ if (e.value !== u) {
301
+ v.close();
302
+ return;
303
+ }
304
+ const m = URL.createObjectURL(new Blob([d], { type: "application/pdf" })), C = v.document;
305
+ C.title = "PDF 预览", C.documentElement.style.height = "100%", C.body.style.cssText = "margin:0;height:100%;";
306
+ const W = C.createElement("iframe");
307
+ W.title = "PDF 预览", W.style.cssText = "display:block;width:100%;height:100%;border:0;", W.src = m, C.body.replaceChildren(W), setTimeout(() => URL.revokeObjectURL(m), 6e4);
308
+ }).catch((d) => {
309
+ v.close(), t.onError(d instanceof Error ? `PDF 预览失败: ${d.message}` : "PDF 预览失败", "pdf");
310
+ });
311
+ }
312
+ return {
313
+ print: p,
314
+ exportAs: B,
315
+ exportImages: b,
316
+ exportWord: T,
317
+ openPdfWindow: z,
318
+ releasePrintFrame: f
319
+ };
320
+ }
321
+ const je = "mrp-hit";
322
+ function Ct(e) {
323
+ e.querySelectorAll(`mark.${je}`).forEach((a) => {
324
+ const r = a.parentNode;
325
+ if (r) {
326
+ for (; a.firstChild; ) r.insertBefore(a.firstChild, a);
327
+ a.remove(), r.normalize();
328
+ }
329
+ });
330
+ }
331
+ function Mt(e, t) {
332
+ const a = t.trim();
333
+ if (!a) return 0;
334
+ const r = a.toLowerCase(), o = document.createTreeWalker(e, NodeFilter.SHOW_TEXT, {
335
+ acceptNode(f) {
336
+ const i = f.parentElement;
337
+ return !i || i.closest("mark") || /^(SCRIPT|STYLE)$/.test(i.tagName) ? NodeFilter.FILTER_REJECT : (f.nodeValue ?? "").toLowerCase().includes(r) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
338
+ }
339
+ }), n = [];
340
+ for (let f = o.nextNode(); f; f = o.nextNode()) n.push(f);
341
+ let l = 0;
342
+ for (const f of n) {
343
+ const i = f.nodeValue ?? "", p = i.toLowerCase(), c = f.parentElement;
344
+ if (!c) continue;
345
+ const g = document.createDocumentFragment();
346
+ let $ = 0, b = p.indexOf(r);
347
+ for (; b >= 0; ) {
348
+ b > $ && g.appendChild(document.createTextNode(i.slice($, b)));
349
+ const T = document.createElement("mark");
350
+ T.className = je, T.textContent = i.slice(b, b + a.length), g.appendChild(T), l++, $ = b + a.length, b = p.indexOf(r, $);
351
+ }
352
+ $ < i.length && g.appendChild(document.createTextNode(i.slice($))), c.replaceChild(g, f);
353
+ }
354
+ return l;
355
+ }
356
+ function ze(e, t) {
357
+ let a = 0, r = e.toLowerCase().indexOf(t);
358
+ for (; r >= 0; )
359
+ a++, r = e.toLowerCase().indexOf(t, r + t.length);
360
+ return a;
361
+ }
362
+ function kt(e) {
363
+ const { plan: t, gotoPage: a, highlight: r, clearHighlights: o } = e, n = e.debounceMs ?? 200, l = F(!1), f = F(""), i = F(""), p = F(0);
364
+ let c = null;
365
+ const g = k(() => {
366
+ const d = f.value.trim().toLowerCase(), m = t.value;
367
+ if (!d || !m) return [];
368
+ const C = [];
369
+ return m.pages.forEach((W, te) => {
370
+ for (const q of W.components)
371
+ if (q.grid) {
372
+ for (const K of q.grid.cells ?? [])
373
+ for (const J of K ?? [])
374
+ if (typeof J?.text == "string")
375
+ for (let ne = 0; ne < ze(J.text, d); ne++) C.push(te);
376
+ } else if (q.kind === "text" && typeof q.text == "string")
377
+ for (let K = 0; K < ze(q.text, d); K++) C.push(te);
378
+ }), C;
379
+ }), $ = k(() => g.value.length);
380
+ function b(d) {
381
+ if (i.value = d, c && clearTimeout(c), d.trim() === "") {
382
+ c = null, f.value = "", p.value = 0;
383
+ return;
384
+ }
385
+ c = setTimeout(() => {
386
+ c = null, f.value = i.value, p.value = 0;
387
+ const m = g.value[0];
388
+ m != null && a(m + 1);
389
+ }, n);
390
+ }
391
+ function T(d) {
392
+ const m = g.value.length;
393
+ m !== 0 && (p.value = (p.value + d + m) % m, a(g.value[p.value] + 1));
394
+ }
395
+ function B() {
396
+ l.value = !l.value;
397
+ }
398
+ function z(d) {
399
+ const m = f.value.trim();
400
+ m && r(d, m);
401
+ }
402
+ function u(d) {
403
+ o(d);
404
+ }
405
+ function v() {
406
+ i.value = "", f.value = "", p.value = 0, c && clearTimeout(c), c = null;
407
+ }
408
+ return {
409
+ visible: l,
410
+ query: f,
411
+ matchIndex: p,
412
+ matchCount: $,
413
+ toggle: B,
414
+ onInput: b,
415
+ onNav: T,
416
+ apply: z,
417
+ clear: u,
418
+ reset: v
419
+ };
420
+ }
421
+ function Rt(e, t) {
422
+ const a = k(() => {
423
+ if (e.value) return !0;
424
+ if (typeof location > "u") return !1;
425
+ try {
426
+ return new URLSearchParams(location.search).get("mrp-debug") === "1";
427
+ } catch {
428
+ return !1;
429
+ }
430
+ }), r = k(() => !a.value || !t.plan.value ? 0 : Math.round(JSON.stringify(t.plan.value).length / 1024)), o = k(() => !a.value || !t.plan.value ? null : {
431
+ pages: t.pageCount.value,
432
+ window: `${t.windowRange.value.start}-${t.windowRange.value.end}`,
433
+ zoom: `${Math.round(t.zoom.value * 100)}%`,
434
+ loadMs: `${t.loadMs.value}ms`,
435
+ planKB: r.value
436
+ });
437
+ return { enabled: a, debugStats: o };
438
+ }
439
+ function Tt(e, t) {
440
+ const { thumbsRoot: a, visible: r, renderThumbCanvas: o } = t;
441
+ let n = null;
442
+ function l(p, c) {
443
+ if (!e.value || p.childElementCount > 0) return;
444
+ const g = o(c);
445
+ g && (g.style.width = "100%", g.style.height = "100%", g.style.display = "block", p.appendChild(g));
446
+ }
447
+ return { schedule: () => {
448
+ !r.value || !e.value || !a.value || typeof IntersectionObserver > "u" || (n?.disconnect(), n = new IntersectionObserver(
449
+ (p) => {
450
+ for (const c of p) {
451
+ if (!c.isIntersecting) continue;
452
+ const g = c.target;
453
+ l(g, Number(g.dataset.thumb ?? 1) - 1), n?.unobserve(g);
454
+ }
455
+ },
456
+ { root: a.value, rootMargin: "200px" }
457
+ ), a.value.querySelectorAll("[data-thumb]").forEach((p) => {
458
+ n.observe(p);
459
+ }));
460
+ }, destroy: () => {
461
+ n?.disconnect(), n = null;
462
+ } };
463
+ }
464
+ function Ft() {
465
+ const e = Oe(0);
466
+ return {
467
+ loadMs: e,
468
+ start() {
469
+ return typeof performance < "u" ? performance.now() : 0;
470
+ },
471
+ end(t) {
472
+ e.value = t ? Math.round(performance.now() - t) : 0;
473
+ }
474
+ };
475
+ }
476
+ const St = { class: "mrp-toolbar" }, Bt = { class: "mrp-title" }, Wt = ["disabled"], It = { class: "mrp-pageinfo" }, Dt = ["disabled"], Lt = {
477
+ key: 1,
478
+ class: "mrp-search"
479
+ }, zt = ["placeholder", "value"], Ht = {
480
+ key: 0,
481
+ class: "mrp-search-count"
482
+ }, Ot = ["disabled"], At = ["disabled"], Nt = /* @__PURE__ */ Ee({
483
+ __name: "ReportToolbar",
484
+ props: {
485
+ pageCount: {},
486
+ currentPage: {},
487
+ zoomMode: {},
488
+ zoom: {},
489
+ showExport: { type: Boolean },
490
+ showPrint: { type: Boolean },
491
+ showPdfWindow: { type: Boolean },
492
+ messages: {},
493
+ search: {},
494
+ thumbsVisible: { type: Boolean }
495
+ },
496
+ emits: ["goto", "zoom", "export", "print", "pdf-window", "search-input", "search-nav", "search-toggle", "thumbs-toggle"],
497
+ setup(e) {
498
+ const t = e, a = F(null);
499
+ A(
500
+ () => t.search.visible,
501
+ (o) => {
502
+ o && lt(() => a.value?.focus());
503
+ }
504
+ );
505
+ function r(o, n, l) {
506
+ return o.replace("{cur}", String(n)).replace("{total}", String(l));
507
+ }
508
+ return (o, n) => (w(), P("div", St, [
509
+ E("span", Bt, y(e.messages.title), 1),
510
+ e.pageCount > 0 ? (w(), P(ee, { key: 0 }, [
511
+ E("button", {
512
+ class: "mrp-nav",
513
+ type: "button",
514
+ disabled: e.currentPage <= 1,
515
+ onClick: n[0] || (n[0] = (l) => o.$emit("goto", e.currentPage - 1))
516
+ }, y(e.messages.prevPage), 9, Wt),
517
+ E("span", It, y(r(e.messages.pageInfo, e.currentPage, e.pageCount)), 1),
518
+ E("button", {
519
+ class: "mrp-nav",
520
+ type: "button",
521
+ disabled: e.currentPage >= e.pageCount,
522
+ onClick: n[1] || (n[1] = (l) => o.$emit("goto", e.currentPage + 1))
523
+ }, y(e.messages.nextPage), 9, Dt)
524
+ ], 64)) : S("", !0),
525
+ n[17] || (n[17] = E("span", { class: "mrp-spacer" }, null, -1)),
526
+ e.search.visible ? (w(), P("div", Lt, [
527
+ E("input", {
528
+ ref_key: "searchInputRef",
529
+ ref: a,
530
+ class: "mrp-search-input",
531
+ type: "text",
532
+ placeholder: e.messages.searchPlaceholder,
533
+ value: e.search.query,
534
+ onInput: n[2] || (n[2] = (l) => o.$emit("search-input", l.target.value))
535
+ }, null, 40, zt),
536
+ e.search.query ? (w(), P("span", Ht, y(r(e.messages.matchInfo, e.search.matchIndex + 1, e.search.matchCount)), 1)) : S("", !0),
537
+ E("button", {
538
+ class: "mrp-nav",
539
+ type: "button",
540
+ disabled: e.search.matchCount === 0,
541
+ onClick: n[3] || (n[3] = (l) => o.$emit("search-nav", -1))
542
+ }, y(e.messages.prevMatch), 9, Ot),
543
+ E("button", {
544
+ class: "mrp-nav",
545
+ type: "button",
546
+ disabled: e.search.matchCount === 0,
547
+ onClick: n[4] || (n[4] = (l) => o.$emit("search-nav", 1))
548
+ }, y(e.messages.nextMatch), 9, At)
549
+ ])) : S("", !0),
550
+ E("button", {
551
+ class: N(["mrp-nav", { "mrp-active": e.search.visible }]),
552
+ type: "button",
553
+ title: "Ctrl+F",
554
+ onClick: n[5] || (n[5] = (l) => o.$emit("search-toggle"))
555
+ }, " 🔍 ", 2),
556
+ E("button", {
557
+ class: N(["mrp-nav", { "mrp-active": e.thumbsVisible }]),
558
+ type: "button",
559
+ onClick: n[6] || (n[6] = (l) => o.$emit("thumbs-toggle"))
560
+ }, " ▦ " + y(e.messages.thumbnails), 3),
561
+ E("button", {
562
+ class: N(["mrp-nav", { "mrp-active": e.zoomMode === "fit" }]),
563
+ type: "button",
564
+ onClick: n[7] || (n[7] = (l) => o.$emit("zoom", "fit"))
565
+ }, y(e.messages.fitWidth), 3),
566
+ E("button", {
567
+ class: N(["mrp-nav", { "mrp-active": e.zoomMode === "raw" && Math.round(e.zoom * 100) === 100 }]),
568
+ type: "button",
569
+ onClick: n[8] || (n[8] = (l) => o.$emit("zoom", 100))
570
+ }, " 100% ", 2),
571
+ E("button", {
572
+ class: N(["mrp-nav", { "mrp-active": e.zoomMode === "raw" && Math.round(e.zoom * 100) === 150 }]),
573
+ type: "button",
574
+ onClick: n[9] || (n[9] = (l) => o.$emit("zoom", 150))
575
+ }, " 150% ", 2),
576
+ e.showExport ? (w(), P("button", {
577
+ key: 2,
578
+ class: "mrp-nav",
579
+ type: "button",
580
+ onClick: n[10] || (n[10] = (l) => o.$emit("export", "html"))
581
+ }, y(e.messages.exportHtml), 1)) : S("", !0),
582
+ e.showExport ? (w(), P("button", {
583
+ key: 3,
584
+ class: "mrp-nav",
585
+ type: "button",
586
+ onClick: n[11] || (n[11] = (l) => o.$emit("export", "pdf"))
587
+ }, y(e.messages.exportPdf), 1)) : S("", !0),
588
+ e.showExport ? (w(), P("button", {
589
+ key: 4,
590
+ class: "mrp-nav",
591
+ type: "button",
592
+ onClick: n[12] || (n[12] = (l) => o.$emit("export", "xlsx"))
593
+ }, y(e.messages.exportExcel), 1)) : S("", !0),
594
+ e.showExport ? (w(), P("button", {
595
+ key: 5,
596
+ class: "mrp-nav",
597
+ type: "button",
598
+ onClick: n[13] || (n[13] = (l) => o.$emit("export", "png"))
599
+ }, y(e.messages.exportImage), 1)) : S("", !0),
600
+ e.showExport ? (w(), P("button", {
601
+ key: 6,
602
+ class: "mrp-nav",
603
+ type: "button",
604
+ onClick: n[14] || (n[14] = (l) => o.$emit("export", "word"))
605
+ }, y(e.messages.exportWord), 1)) : S("", !0),
606
+ e.showPrint ? (w(), P("button", {
607
+ key: 7,
608
+ class: "mrp-nav",
609
+ type: "button",
610
+ onClick: n[15] || (n[15] = (l) => o.$emit("print"))
611
+ }, y(e.messages.print), 1)) : S("", !0),
612
+ e.showPdfWindow ? (w(), P("button", {
613
+ key: 8,
614
+ class: "mrp-nav",
615
+ type: "button",
616
+ onClick: n[16] || (n[16] = (l) => o.$emit("pdf-window"))
617
+ }, y(e.messages.pdfWindow), 1)) : S("", !0)
618
+ ]));
619
+ }
620
+ }), Me = (e, t) => {
621
+ const a = e.__vccOpts || e;
622
+ for (const [r, o] of t)
623
+ a[r] = o;
624
+ return a;
625
+ }, qt = /* @__PURE__ */ Me(Nt, [["__scopeId", "data-v-48cc0980"]]), Ut = { class: "mrp-params" }, Vt = { class: "mrp-params-title" }, jt = { class: "mrp-params-grid" }, Kt = { class: "mrp-param-label" }, Zt = {
626
+ key: 0,
627
+ class: "mrp-param-star"
628
+ }, Gt = ["value", "onChange"], Yt = {
629
+ value: "",
630
+ disabled: "",
631
+ hidden: ""
632
+ }, Jt = ["value"], Xt = ["type", "placeholder", "value", "onInput"], Qt = { class: "mrp-params-actions" }, _t = /* @__PURE__ */ Ee({
633
+ __name: "ReportParamPanel",
634
+ props: {
635
+ defs: {},
636
+ modelValue: {},
637
+ messages: {},
638
+ attempted: { type: Boolean }
639
+ },
640
+ emits: ["update:modelValue", "query", "reset"],
641
+ setup(e, { emit: t }) {
642
+ const a = e, r = t, o = F({ ...a.modelValue });
643
+ A(
644
+ () => a.modelValue,
645
+ (i) => {
646
+ o.value = { ...i };
647
+ }
648
+ );
649
+ const n = k(
650
+ () => a.defs.map((i) => ({
651
+ def: i,
652
+ label: i.label ?? i.field,
653
+ value: o.value[i.field] ?? ""
654
+ }))
655
+ );
656
+ function l(i, p) {
657
+ o.value = { ...o.value, [i]: p }, r("update:modelValue", { ...o.value });
658
+ }
659
+ function f(i) {
660
+ const p = a.defs.find((c) => c.field === i);
661
+ return a.attempted && p?.required === !0 && !(o.value[i] ?? "").trim();
662
+ }
663
+ return (i, p) => (w(), P("div", Ut, [
664
+ E("span", Vt, y(e.messages.paramsTitle), 1),
665
+ E("div", jt, [
666
+ (w(!0), P(ee, null, ie(n.value, (c) => (w(), P("label", {
667
+ key: c.def.field,
668
+ class: N(["mrp-param", { "mrp-param-missing": f(c.def.field) }])
669
+ }, [
670
+ E("span", Kt, [
671
+ Ae(y(c.label), 1),
672
+ c.def.required ? (w(), P("i", Zt, "*")) : S("", !0)
673
+ ]),
674
+ (c.def.type ?? "text") === "select" ? (w(), P("select", {
675
+ key: 0,
676
+ class: "mrp-param-input",
677
+ value: c.value,
678
+ onChange: (g) => l(c.def.field, g.target.value),
679
+ onKeydown: p[0] || (p[0] = De((g) => i.$emit("query"), ["enter"]))
680
+ }, [
681
+ E("option", Yt, y(c.def.placeholder ?? `请选择${c.label}`), 1),
682
+ (w(!0), P(ee, null, ie(c.def.options ?? [], (g) => (w(), P("option", {
683
+ key: g.value,
684
+ value: g.value
685
+ }, y(g.label), 9, Jt))), 128))
686
+ ], 40, Gt)) : (w(), P("input", {
687
+ key: 1,
688
+ class: "mrp-param-input",
689
+ type: c.def.type === "number" ? "number" : c.def.type === "date" ? "date" : "text",
690
+ placeholder: c.def.placeholder ?? `请输入${c.label}`,
691
+ value: c.value,
692
+ onInput: (g) => l(c.def.field, g.target.value),
693
+ onKeydown: p[1] || (p[1] = De((g) => i.$emit("query"), ["enter"]))
694
+ }, null, 40, Xt))
695
+ ], 2))), 128))
696
+ ]),
697
+ E("div", Qt, [
698
+ E("button", {
699
+ class: "mrp-nav mrp-param-query",
700
+ type: "button",
701
+ onClick: p[2] || (p[2] = (c) => i.$emit("query"))
702
+ }, y(e.messages.query), 1),
703
+ E("button", {
704
+ class: "mrp-nav",
705
+ type: "button",
706
+ onClick: p[3] || (p[3] = (c) => i.$emit("reset"))
707
+ }, y(e.messages.reset), 1)
708
+ ])
709
+ ]));
710
+ }
711
+ }), en = /* @__PURE__ */ Me(_t, [["__scopeId", "data-v-aafce92d"]]), tn = {
712
+ title: "报表预览",
713
+ prevPage: "‹ 上一页",
714
+ nextPage: "下一页 ›",
715
+ pageInfo: "{cur} / {total}",
716
+ fitWidth: "适宽",
717
+ exportHtml: "导出 HTML",
718
+ exportPdf: "导出 PDF",
719
+ exportExcel: "导出 Excel",
720
+ exportImage: "导出图片",
721
+ exportWord: "导出 Word",
722
+ exporting: "正在生成 {format}…",
723
+ print: "打印",
724
+ pdfWindow: "PDF 窗口",
725
+ loading: "报表渲染中…",
726
+ empty: "暂无预览数据",
727
+ errorPrefix: "",
728
+ retry: "重试",
729
+ searchPlaceholder: "搜索报表内容",
730
+ matchInfo: "{cur}/{total}",
731
+ prevMatch: "‹",
732
+ nextMatch: "›",
733
+ thumbnails: "缩略图",
734
+ paramsTitle: "查询条件",
735
+ query: "查 询",
736
+ reset: "重 置",
737
+ paramRequired: "请填写{label}"
738
+ }, nn = {
739
+ shellBg: "#525659",
740
+ shellFg: "#e8e8e8",
741
+ toolbarBg: "#323639",
742
+ toolbarBorder: "#22252a",
743
+ toolbarFg: "#e8e8e8",
744
+ btnFg: "#cfcfcf",
745
+ btnBorder: "#4a4d52",
746
+ btnHoverBg: "#414549",
747
+ btnHoverFg: "#ffffff",
748
+ btnActiveBg: "#2d5fb8"
749
+ };
750
+ function Rn(e) {
751
+ return e;
752
+ }
753
+ function Tn(e) {
754
+ return e;
755
+ }
756
+ const j = {
757
+ showExport: !0,
758
+ showPrint: !0,
759
+ showPdfWindow: !0,
760
+ showParams: !0,
761
+ gapPx: 18,
762
+ pdfFontUrl: "/simhei.ttf",
763
+ logger: console
764
+ }, Fn = { warn: () => {
765
+ }, info: () => {
766
+ } };
767
+ function on(e, t) {
768
+ const a = t ? e?.presets?.[t] : e?.defaultPreset ? e?.presets?.[e.defaultPreset] : void 0, r = { ...e?.defaults, ...a };
769
+ return {
770
+ showExport: r.showExport ?? j.showExport,
771
+ showPrint: r.showPrint ?? j.showPrint,
772
+ showPdfWindow: r.showPdfWindow ?? j.showPdfWindow,
773
+ showParams: r.showParams ?? j.showParams,
774
+ gapPx: r.gapPx ?? j.gapPx,
775
+ pdfFontUrl: r.pdfFontUrl ?? j.pdfFontUrl,
776
+ theme: { ...nn, ...r.theme },
777
+ messages: { ...tn, ...r.messages },
778
+ logger: r.logger ?? j.logger
779
+ };
780
+ }
781
+ function rn(e) {
782
+ const t = {};
783
+ 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;
784
+ }
785
+ function Sn(e) {
786
+ const t = ue(xe, null), a = k(() => {
787
+ const r = t?.value ?? null, o = "defaults" in e && "presets" in e ? e : { defaults: e, presets: {} };
788
+ return r ? {
789
+ defaults: { ...r.defaults, ...o.defaults },
790
+ presets: { ...r.presets, ...o.presets },
791
+ defaultPreset: o.defaultPreset ?? r.defaultPreset
792
+ } : o;
793
+ });
794
+ Ne(xe, a);
795
+ }
796
+ function an() {
797
+ return ue(xe, k(() => null));
798
+ }
799
+ function sn(e = { fontUrl: "/simhei.ttf" }) {
800
+ let t = null;
801
+ return async (a, r) => {
802
+ t || (t = await import("@agile-team/mach-report/pdf"));
803
+ const o = e.fontUrl ? await t.loadFontWithCache(e.fontUrl) : null, { bytes: n, unsupportedTextCount: l, pageErrors: f, fidelityWarnings: i } = await t.renderPlanToPdf(a, o ? { customFontBytes: o } : {});
804
+ if (l > 0)
805
+ throw new Error(`PDF 中有 ${l} 行文字无法编码;请部署支持所用文字的字体并配置 pdfFontUrl`);
806
+ if (f.length > 0)
807
+ throw new Error(`PDF 有 ${f.length} 页渲染失败:${f[0]}`);
808
+ return i.length > 0 && r?.(`PDF 有 ${i.length} 处版式降级:${i.slice(0, 2).join(";")}`), n;
809
+ };
810
+ }
811
+ class le extends Error {
812
+ constructor(t, a, r) {
813
+ super(a), this.name = "MachReportError", this.code = t, this.cause = r;
814
+ }
815
+ }
816
+ function ln(e) {
817
+ return e instanceof le ? { code: e.code, cause: e.cause } : { code: "render", cause: e };
818
+ }
819
+ const un = { class: "mrp-main" }, cn = {
820
+ key: 0,
821
+ class: "mrp-state"
822
+ }, dn = {
823
+ key: 1,
824
+ class: "mrp-state mrp-error"
825
+ }, fn = {
826
+ key: 2,
827
+ class: "mrp-state"
828
+ }, pn = ["data-page"], mn = ["onClick"], gn = ["data-thumb"], vn = { class: "mrp-thumb-no" }, hn = { class: "mrp-overlay" }, bn = {
829
+ key: 2,
830
+ class: "mrp-debug",
831
+ "aria-hidden": "true"
832
+ }, ae = 96 / 25.4, He = "mach-report:ui", wn = /* @__PURE__ */ Ee({
833
+ __name: "ReportPreview",
834
+ props: {
835
+ reportId: {
836
+ type: [String, Array],
837
+ default: null
838
+ },
839
+ params: {
840
+ type: Object,
841
+ default: () => ({})
842
+ },
843
+ height: { type: String, default: "100vh" },
844
+ autoLoad: { type: Boolean, default: !0 },
845
+ /** 以下显隐/间距不传时走配置中心(preset > defaults > 内置缺省) */
846
+ showExport: { type: Boolean, default: void 0 },
847
+ showPrint: { type: Boolean, default: void 0 },
848
+ showPdfWindow: { type: Boolean, default: void 0 },
849
+ /** 页间距(px);不传走配置中心 */
850
+ gapPx: { type: Number, default: void 0 },
851
+ /** 工具栏/状态文案覆写(不传走配置中心 messages) */
852
+ messages: { type: Object, default: void 0 },
853
+ /** 启用的 preset 名(不传用配置中心 defaultPreset) */
854
+ preset: { type: String, default: void 0 },
855
+ /** 调试面板(也可用 URL ?mrp-debug=1 开启) */
856
+ debug: { type: Boolean, default: !1 },
857
+ /** 参数定义(优先级:prop > 模板 params;有定义且未关闭时显示查询面板) */
858
+ paramDefs: {
859
+ type: Array,
860
+ default: void 0
861
+ },
862
+ /** 参数面板显隐(不传走配置中心,缺省 true;有参数定义才渲染) */
863
+ showParams: { type: Boolean, default: void 0 },
864
+ fetcher: {
865
+ type: Function,
866
+ default: null
867
+ }
868
+ },
869
+ emits: ["loaded", "error", "warning"],
870
+ setup(e, { expose: t, emit: a }) {
871
+ it((s) => ({
872
+ v0e7a3c30: B.value + "px"
873
+ }));
874
+ const r = e, o = a, n = Oe(null), l = F(!1), f = F(""), i = F(null), p = F(1), c = F(null), g = F(null), $ = F(null), b = F(!1), T = Ft(), B = k(() => Math.max(0, J.value)), z = ue(bt, null), u = ue(wt, null), v = k(() => Ue(r.reportId)), d = k(() => n.value?.pages.length ?? 0), m = an(), C = k(() => on(m.value, r.preset)), W = k(() => ({
875
+ ...C.value.messages,
876
+ ...r.messages
877
+ })), te = k(() => r.showExport ?? C.value.showExport), q = k(() => r.showPrint ?? C.value.showPrint), K = k(() => r.showPdfWindow ?? C.value.showPdfWindow), J = k(() => r.gapPx ?? C.value.gapPx), ne = k(() => r.showParams ?? C.value.showParams);
878
+ let ke = null, fe = null;
879
+ function Ke() {
880
+ if (u) return u;
881
+ const s = C.value.pdfFontUrl;
882
+ return (!fe || ke !== s) && (ke = s, fe = sn({ fontUrl: s })), fe;
883
+ }
884
+ const U = k(() => r.paramDefs ?? []), V = F({}), pe = F(!1);
885
+ function oe(s) {
886
+ const h = {};
887
+ for (const M of s)
888
+ h[M.field] = r.params[M.field] ?? M.defaultValue ?? "";
889
+ V.value = h, pe.value = !1;
890
+ }
891
+ oe(U.value), A(U, (s) => oe(s)), A(() => JSON.stringify(r.params), () => oe(U.value));
892
+ const Ze = k(() => {
893
+ const s = { ...r.params };
894
+ for (const [h, M] of Object.entries(V.value))
895
+ M === "" ? delete s[h] : s[h] = M;
896
+ return s;
897
+ });
898
+ function Ge() {
899
+ return U.value.filter(
900
+ (s) => s.required === !0 && !(V.value[s.field] ?? "").trim()
901
+ );
902
+ }
903
+ function Ye() {
904
+ pe.value = !0;
905
+ const s = Ge();
906
+ if (s.length > 0) {
907
+ const h = s[0].label ?? s[0].field, M = W.value.paramRequired.replace("{label}", h);
908
+ f.value = M, o("error", M, { code: "param" });
909
+ return;
910
+ }
911
+ O();
912
+ }
913
+ function Je() {
914
+ oe(U.value);
915
+ }
916
+ const Xe = k(() => ({
917
+ height: r.height,
918
+ ...rn(C.value.theme)
919
+ })), { zoom: L, zoomMode: Z, applyFitZoom: Re, setZoom: me } = xt(() => ({
920
+ viewport: g.value,
921
+ pageWidthPx: (n.value?.pages[0]?.pageWidthMm ?? 210) * ae
922
+ })), Qe = Pt(n, L, {
923
+ pxPerMm: ae,
924
+ gapPx: J
925
+ }), { contentSize: ge, windowRange: X, visiblePages: _e, makeScrollHandler: et, refreshViewport: Te } = Qe, tt = et(p, d);
926
+ function ve(s) {
927
+ Z.value = "raw", L.value = Math.min(3, Math.max(0.3, s));
928
+ }
929
+ function he() {
930
+ Fe(), n.value = null, p.value = 1, I.reset();
931
+ }
932
+ let re = 0;
933
+ async function O() {
934
+ const s = ++re, h = r.fetcher ?? z;
935
+ if (v.value.length === 0) {
936
+ f.value = "缺少报表 ID", he(), o("error", f.value, { code: "param" });
937
+ return;
938
+ }
939
+ if (!h) {
940
+ f.value = "未提供渲染数据源 fetcher", he(), o("error", f.value, { code: "config" });
941
+ return;
942
+ }
943
+ l.value = !0, f.value = "", i.value = null, he();
944
+ const M = T.start();
945
+ try {
946
+ const R = await h({
947
+ reportIds: v.value,
948
+ params: { ...Ze.value }
949
+ });
950
+ if (s !== re) return;
951
+ const D = vt(R);
952
+ if (!D.ok) {
953
+ const Q = D.errors.slice(0, 3).map((_) => `${_.path}: ${_.message}`).join("; ");
954
+ throw new le(
955
+ "validate",
956
+ `渲染计划校验失败(${D.errors.length} 处): ${Q}`
957
+ );
958
+ }
959
+ D.warnings.length > 0 && C.value.logger.warn("[mach-report] 渲染计划告警:", D.warnings), n.value = R, p.value = 1, T.end(M), g.value && (g.value.scrollTop = 0), Z.value === "fit" && Re(), o("loaded", R.pages.length);
960
+ } catch (R) {
961
+ if (s !== re) return;
962
+ const D = R instanceof le ? R : new le(
963
+ "fetch",
964
+ R instanceof Error ? R.message : "预览加载失败",
965
+ R
966
+ );
967
+ f.value = D.message, o("error", D.message, ln(D));
968
+ } finally {
969
+ s === re && (l.value = !1);
970
+ }
971
+ }
972
+ function H(s) {
973
+ if (d.value <= 0) return;
974
+ const h = Math.max(1, Math.min(d.value, s));
975
+ p.value = h;
976
+ const M = g.value;
977
+ if (!M) return;
978
+ let R = 0;
979
+ for (let D = 0; D < h - 1; D++)
980
+ R += (n.value?.pages[D]?.pageHeightMm ?? 0) * ae + B.value;
981
+ M.scrollTop = R * L.value;
982
+ }
983
+ const { print: be, exportAs: we, openPdfWindow: ye, releasePrintFrame: Fe } = $t(n, {
984
+ getPdfExporter: Ke,
985
+ onError: (s, h) => {
986
+ i.value = { kind: "error", message: s }, o("error", s, { code: h ?? "print" });
987
+ },
988
+ onWarning: (s) => {
989
+ i.value = { kind: "warning", message: s }, o("warning", s);
990
+ },
991
+ onBusy: (s) => {
992
+ s ? i.value = {
993
+ kind: "progress",
994
+ message: W.value.exporting.replace("{format}", s)
995
+ } : i.value?.kind === "progress" && (i.value = null);
996
+ }
997
+ });
998
+ function Se(s, h = {}) {
999
+ V.value = { ...V.value, ...s }, h.reload !== !1 && O();
1000
+ }
1001
+ Ne(yt, { reload: O, print: be, exportAs: we, openPdfWindow: ye, gotoPage: H, setParams: Se });
1002
+ const I = kt({
1003
+ plan: n,
1004
+ gotoPage: H,
1005
+ highlight: Mt,
1006
+ clearHighlights: Ct
1007
+ });
1008
+ function nt(s) {
1009
+ s.ctrlKey && (s.preventDefault(), ve(L.value * (s.deltaY < 0 ? 1.1 : 1 / 1.1)));
1010
+ }
1011
+ function ot(s) {
1012
+ if ((s.ctrlKey || s.metaKey) && s.key.toLowerCase() === "f") {
1013
+ s.preventDefault(), I.visible.value || I.toggle();
1014
+ return;
1015
+ }
1016
+ switch (s.key) {
1017
+ case "PageDown":
1018
+ s.preventDefault(), H(p.value + 1);
1019
+ break;
1020
+ case "PageUp":
1021
+ s.preventDefault(), H(p.value - 1);
1022
+ break;
1023
+ case "Home":
1024
+ s.preventDefault(), H(1);
1025
+ break;
1026
+ case "End":
1027
+ s.preventDefault(), H(d.value);
1028
+ break;
1029
+ case "+":
1030
+ case "=":
1031
+ s.preventDefault(), ve(L.value * 1.1);
1032
+ break;
1033
+ case "-":
1034
+ s.preventDefault(), ve(L.value / 1.1);
1035
+ break;
1036
+ }
1037
+ }
1038
+ function rt() {
1039
+ try {
1040
+ localStorage.setItem(
1041
+ He,
1042
+ JSON.stringify({ zoomMode: Z.value === "fit" ? "fit" : Math.round(L.value * 100) })
1043
+ );
1044
+ } catch {
1045
+ }
1046
+ }
1047
+ A([Z, L], rt), Le(() => {
1048
+ const s = n.value;
1049
+ if (!s) return;
1050
+ const h = c.value;
1051
+ if (!h) return;
1052
+ h.querySelectorAll(".mrp-page-holder").forEach((R) => {
1053
+ const D = Number(R.dataset.page ?? 0) - 1, Q = s.pages[D];
1054
+ if (!Q || R.childElementCount > 0) {
1055
+ if (R.firstElementChild) {
1056
+ const Ie = R.firstElementChild;
1057
+ I.clear(Ie), I.apply(Ie);
1058
+ }
1059
+ return;
1060
+ }
1061
+ R.style.width = `${Q.pageWidthMm * ae}px`;
1062
+ const _ = qe(Q, 96, {}, document);
1063
+ I.apply(_), R.appendChild(_);
1064
+ });
1065
+ }, { flush: "post" }), A(() => I.query.value, (s) => {
1066
+ s || c.value?.querySelectorAll(".mrp-page-holder").forEach((h) => {
1067
+ I.clear(h);
1068
+ });
1069
+ });
1070
+ const Be = Tt(n, {
1071
+ thumbsRoot: $,
1072
+ visible: b,
1073
+ renderThumbCanvas: (s) => {
1074
+ try {
1075
+ const { canvases: h } = ht(n.value, { start: s, end: s, dpr: 0.2 });
1076
+ return h[0] ?? null;
1077
+ } catch {
1078
+ return null;
1079
+ }
1080
+ }
1081
+ });
1082
+ Le(() => {
1083
+ Be.schedule();
1084
+ }, { flush: "post" });
1085
+ const at = k(() => r.debug), { debugStats: G } = Rt(at, {
1086
+ plan: n,
1087
+ pageCount: d,
1088
+ windowRange: X,
1089
+ zoom: L,
1090
+ loadMs: T.loadMs
1091
+ });
1092
+ function We() {
1093
+ Te(g.value), Z.value === "fit" && Re();
1094
+ }
1095
+ function st() {
1096
+ try {
1097
+ const s = JSON.parse(localStorage.getItem(He) ?? "{}");
1098
+ s.zoomMode === "fit" ? me("fit") : typeof s.zoomMode == "number" && me(s.zoomMode);
1099
+ } catch {
1100
+ }
1101
+ }
1102
+ return ut(() => {
1103
+ window.addEventListener("resize", We), Te(g.value), st(), r.autoLoad && O();
1104
+ }), ct(() => {
1105
+ window.removeEventListener("resize", We), Be.destroy(), I.reset(), Fe();
1106
+ }), A(
1107
+ () => [r.reportId, JSON.stringify(r.params)],
1108
+ () => {
1109
+ r.autoLoad && O();
1110
+ }
1111
+ ), A(
1112
+ () => r.fetcher ?? z,
1113
+ () => {
1114
+ r.autoLoad && O();
1115
+ }
1116
+ ), t({ reload: O, print: be, exportAs: we, openPdfWindow: ye, gotoPage: H, setParams: Se }), (s, h) => (w(), P("div", {
1117
+ class: "mach-report-preview",
1118
+ style: Y(Xe.value)
1119
+ }, [
1120
+ ne.value && U.value.length > 0 ? (w(), dt(en, {
1121
+ key: 0,
1122
+ defs: U.value,
1123
+ modelValue: V.value,
1124
+ "onUpdate:modelValue": h[0] || (h[0] = (M) => V.value = M),
1125
+ messages: W.value,
1126
+ attempted: pe.value,
1127
+ onQuery: Ye,
1128
+ onReset: Je
1129
+ }, null, 8, ["defs", "modelValue", "messages", "attempted"])) : S("", !0),
1130
+ ft(qt, {
1131
+ "page-count": d.value,
1132
+ "current-page": p.value,
1133
+ "zoom-mode": x(Z),
1134
+ zoom: x(L),
1135
+ "show-export": te.value,
1136
+ "show-print": q.value,
1137
+ "show-pdf-window": K.value,
1138
+ messages: W.value,
1139
+ search: { visible: x(I).visible.value, query: x(I).query.value, matchIndex: x(I).matchIndex.value, matchCount: x(I).matchCount.value },
1140
+ "thumbs-visible": b.value,
1141
+ onGoto: H,
1142
+ onZoom: x(me),
1143
+ onExport: h[1] || (h[1] = (M) => x(we)(M)),
1144
+ onPrint: x(be),
1145
+ onPdfWindow: x(ye),
1146
+ onSearchInput: x(I).onInput,
1147
+ onSearchNav: x(I).onNav,
1148
+ onSearchToggle: x(I).toggle,
1149
+ onThumbsToggle: h[2] || (h[2] = (M) => b.value = !b.value)
1150
+ }, null, 8, ["page-count", "current-page", "zoom-mode", "zoom", "show-export", "show-print", "show-pdf-window", "messages", "search", "thumbs-visible", "onZoom", "onPrint", "onPdfWindow", "onSearchInput", "onSearchNav", "onSearchToggle"]),
1151
+ i.value ? (w(), P("div", {
1152
+ key: 1,
1153
+ class: N(["mrp-export-notice", `mrp-export-${i.value.kind}`]),
1154
+ role: "alert"
1155
+ }, y(i.value.message), 3)) : S("", !0),
1156
+ E("div", un, [
1157
+ E("div", {
1158
+ ref_key: "viewportRef",
1159
+ ref: g,
1160
+ class: "mrp-body",
1161
+ tabindex: "0",
1162
+ onWheel: nt,
1163
+ onKeydown: ot,
1164
+ onScrollPassive: h[3] || (h[3] = (M) => x(tt)(M.target))
1165
+ }, [
1166
+ l.value ? (w(), P("div", cn, y(W.value.loading), 1)) : f.value ? (w(), P("div", dn, [
1167
+ Ae(y(f.value) + " ", 1),
1168
+ E("button", {
1169
+ class: "mrp-retry",
1170
+ type: "button",
1171
+ onClick: O
1172
+ }, y(W.value.retry), 1)
1173
+ ])) : !n.value || d.value === 0 ? (w(), P("div", fn, y(W.value.empty), 1)) : (w(), P("div", {
1174
+ key: 3,
1175
+ class: "mrp-scale",
1176
+ style: Y({ width: `${x(ge).w * x(L)}px`, height: `${x(ge).h * x(L)}px` })
1177
+ }, [
1178
+ E("div", {
1179
+ ref_key: "containerRef",
1180
+ ref: c,
1181
+ class: "mrp-scale-inner",
1182
+ style: Y({ transform: `scale(${x(L)})`, transformOrigin: "top left", width: `${x(ge).w}px` })
1183
+ }, [
1184
+ x(X).padTopPx > 0 ? (w(), P("div", {
1185
+ key: 0,
1186
+ class: "mrp-spacer-top",
1187
+ style: Y({ height: `${x(X).padTopPx}px` }),
1188
+ "aria-hidden": "true"
1189
+ }, null, 4)) : S("", !0),
1190
+ (w(!0), P(ee, null, ie(x(_e), (M) => (w(), P("div", {
1191
+ key: M.index,
1192
+ class: "mrp-page-holder",
1193
+ "data-page": M.index + 1
1194
+ }, null, 8, pn))), 128)),
1195
+ x(X).padBottomPx > 0 ? (w(), P("div", {
1196
+ key: 1,
1197
+ class: "mrp-spacer-bottom",
1198
+ style: Y({ height: `${x(X).padBottomPx}px` }),
1199
+ "aria-hidden": "true"
1200
+ }, null, 4)) : S("", !0)
1201
+ ], 4)
1202
+ ], 4))
1203
+ ], 544),
1204
+ b.value && d.value > 0 ? (w(), P("aside", {
1205
+ key: 0,
1206
+ ref_key: "thumbsRef",
1207
+ ref: $,
1208
+ class: "mrp-thumbs"
1209
+ }, [
1210
+ (w(!0), P(ee, null, ie(n.value?.pages ?? [], (M, R) => (w(), P("div", {
1211
+ key: R,
1212
+ class: N(["mrp-thumb", { "mrp-thumb-active": R + 1 === p.value }]),
1213
+ onClick: (D) => H(R + 1)
1214
+ }, [
1215
+ E("div", {
1216
+ class: "mrp-thumb-box",
1217
+ "data-thumb": R + 1,
1218
+ style: Y({ height: `${Math.round(M.pageHeightMm / M.pageWidthMm * 116)}px` })
1219
+ }, null, 12, gn),
1220
+ E("span", vn, y(R + 1), 1)
1221
+ ], 10, mn))), 128))
1222
+ ], 512)) : S("", !0)
1223
+ ]),
1224
+ E("div", hn, [
1225
+ pt(s.$slots, "default", {}, void 0, !0)
1226
+ ]),
1227
+ x(G) ? (w(), P("div", bn, [
1228
+ h[4] || (h[4] = E("div", null, "mach-report debug", -1)),
1229
+ E("div", null, "pages: " + y(x(G).pages) + " | window: [" + y(x(G).window) + "]", 1),
1230
+ E("div", null, "zoom: " + y(x(G).zoom) + " | load: " + y(x(G).loadMs), 1),
1231
+ E("div", null, "plan: " + y(x(G).planKB) + "KB", 1)
1232
+ ])) : S("", !0)
1233
+ ], 4));
1234
+ }
1235
+ }), yn = /* @__PURE__ */ Me(wn, [["__scopeId", "data-v-249dbb78"]]), Bn = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1236
+ __proto__: null,
1237
+ default: yn
1238
+ }, Symbol.toStringTag, { value: "Module" }));
1239
+ export {
1240
+ tn as D,
1241
+ le as M,
1242
+ Pe as P,
1243
+ en as R,
1244
+ Fn as S,
1245
+ nn as a,
1246
+ yn as b,
1247
+ qt as c,
1248
+ Ve as d,
1249
+ Et as e,
1250
+ sn as f,
1251
+ Mn as g,
1252
+ Rn as h,
1253
+ Tn as i,
1254
+ Cn as j,
1255
+ Sn as k,
1256
+ ln as l,
1257
+ Pt as m,
1258
+ Ue as n,
1259
+ $t as o,
1260
+ kn as p,
1261
+ xt as q,
1262
+ on as r,
1263
+ Bn as s,
1264
+ rn as t,
1265
+ an as u
1266
+ };