@agile-team/mach-report 0.9.1 → 0.10.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.
@@ -1,926 +0,0 @@
1
- import { ref as S, computed as x, shallowRef as ke, defineComponent as $e, watch as X, nextTick as Ue, openBlock as M, createElementBlock as C, createElementVNode as y, toDisplayString as P, Fragment as ge, createCommentVNode as L, normalizeClass as V, inject as ae, provide as Re, useCssVars as je, watchEffect as xe, onMounted as qe, onUnmounted as Ke, normalizeStyle as q, createVNode as Ve, unref as m, createTextVNode as Ge, renderList as Ee, renderSlot as Ye } from "vue";
2
- import { computePageWindow as Ze, renderPage as Te, validateRenderPlan as Je, renderPlanToCanvas as Xe } from "@agile-team/mach-report";
3
- import { a as he, b as Qe, c as _e, n as et, M as tt, e as nt } from "./plugin-Bo8QqzCz.js";
4
- function ot(e, o, a = {}) {
5
- const n = a.pxPerMm ?? 3.7795275590551185, r = a.gapPx ?? 18, t = S(0), s = S(800), l = x(
6
- () => (e.value?.pages ?? []).map((u) => u.pageHeightMm * n)
7
- ), d = x(() => {
8
- const u = e.value?.pages ?? [];
9
- let f = 0, p = 0;
10
- for (const b of u)
11
- f += b.pageHeightMm * n + r, p = Math.max(p, b.pageWidthMm * n);
12
- return { w: p, h: f };
13
- }), h = x(
14
- () => Ze({
15
- pageHeightsPx: l.value,
16
- viewportHeightPx: s.value / o.value,
17
- scrollTopPx: t.value / o.value,
18
- overscan: 1,
19
- gapPx: r
20
- })
21
- ), g = x(() => {
22
- const u = e.value;
23
- if (!u) return [];
24
- const { start: f, end: p } = h.value;
25
- return p < f ? [] : u.pages.slice(f, p + 1).map((b, k) => ({ page: b, index: f + k }));
26
- });
27
- function i(u, f) {
28
- let p = 0;
29
- return (b) => {
30
- p || (p = requestAnimationFrame(() => {
31
- if (p = 0, t.value = b.scrollTop, s.value = b.clientHeight || 800, f.value <= 0) return;
32
- const k = b.querySelectorAll(".mrp-page-holder");
33
- if (!k.length) return;
34
- const W = b.getBoundingClientRect().top + 56;
35
- let H = 1;
36
- k.forEach((w) => {
37
- w.getBoundingClientRect().top <= W && (H = Number(w.dataset.page ?? 1));
38
- }), u.value = Math.max(1, Math.min(f.value, H));
39
- }));
40
- };
41
- }
42
- return {
43
- contentSize: d,
44
- windowRange: h,
45
- visiblePages: g,
46
- makeScrollHandler: i,
47
- refreshViewport(u) {
48
- u && (s.value = u.clientHeight || 800);
49
- }
50
- };
51
- }
52
- function rt(e) {
53
- const o = S(1), a = S("fit");
54
- function n() {
55
- requestAnimationFrame(() => {
56
- const t = e();
57
- !t || !t.viewport || (o.value = Math.min(
58
- 1,
59
- Math.max(0.3, (t.viewport.clientWidth - 48) / Math.max(1, t.pageWidthPx))
60
- ));
61
- });
62
- }
63
- function r(t) {
64
- t === "fit" ? (a.value = "fit", n()) : (a.value = "raw", o.value = t / 100);
65
- }
66
- return { zoom: o, zoomMode: a, applyFitZoom: n, setZoom: r };
67
- }
68
- const se = 8;
69
- function le() {
70
- return new Promise((e) => setTimeout(e, 0));
71
- }
72
- function te(e) {
73
- return `p${Math.round(e.pageWidthMm)}x${Math.round(e.pageHeightMm)}`;
74
- }
75
- function oe(e) {
76
- const o = /* @__PURE__ */ new Map();
77
- e.pages.forEach((s) => {
78
- o.has(te(s)) || o.set(te(s), s);
79
- });
80
- const r = `<!doctype html><html><head><meta charset="utf-8"><style>${`.mr-page{margin:0 auto;page-break-after:always;}
81
- .mr-page tr{break-inside:avoid;page-break-inside:avoid;}
82
- .mr-comp{break-inside:avoid;page-break-inside:avoid;}
83
- ${[...o.values()].map(
84
- (s) => `@page ${te(s)}{size:${Math.round(s.pageWidthMm)}mm ${Math.round(s.pageHeightMm)}mm;margin:0;}`
85
- ).join(`
86
- `)}
87
- body{margin:0;background:#fff;}`}</style></head><body>`, t = e.pages.map((s) => {
88
- const l = Te(s, 96, {}, document);
89
- return l.style.page = te(s), l.outerHTML;
90
- });
91
- return { head: r, pageChunks: t };
92
- }
93
- async function Vt(e, o = {}) {
94
- const a = {
95
- pages: e.flatMap((l) => l.pages)
96
- };
97
- if (a.pages.length === 0) return;
98
- const { head: n, pageChunks: r } = oe(a), t = document.createElement("iframe");
99
- t.style.cssText = "position:fixed;right:0;bottom:0;width:0;height:0;border:0;visibility:hidden;", document.body.appendChild(t);
100
- let s = !1;
101
- try {
102
- const l = t.contentDocument;
103
- l.open(), l.write(n);
104
- for (let d = 0; d < r.length; d++)
105
- l.write(r[d]), d % se === se - 1 && (o.onProgress?.(d + 1, r.length), await le());
106
- l.write("</body></html>"), l.close(), await le(), o.onProgress?.(r.length, r.length), s = !0, t.contentWindow?.focus(), t.contentWindow?.print();
107
- } catch (l) {
108
- o.onError?.(l instanceof Error ? `批量打印失败: ${l.message}` : "批量打印失败");
109
- } finally {
110
- s ? setTimeout(() => t.remove(), 6e4) : t.remove();
111
- }
112
- }
113
- function at(e, o) {
114
- let a = null, n = !1, r = null;
115
- function t() {
116
- a?.remove(), a = null;
117
- }
118
- function s(i, u) {
119
- const f = URL.createObjectURL(i), p = document.createElement("a");
120
- p.href = f, p.download = u, p.click(), setTimeout(() => URL.revokeObjectURL(f), 1e4);
121
- }
122
- async function l() {
123
- if (n) return;
124
- const i = e.value;
125
- if (!i || i.pages.length === 0) return;
126
- n = !0, t();
127
- const { head: u, pageChunks: f } = oe(i);
128
- 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);
129
- const p = a;
130
- try {
131
- const b = p.contentDocument;
132
- b.open(), b.write(u);
133
- for (let k = 0; k < f.length; k++)
134
- if (b.write(f[k]), k % se === se - 1 && await le(), p !== a) return;
135
- b.write("</body></html>"), b.close(), await le(), p.contentWindow?.focus(), p.contentWindow?.print();
136
- } catch {
137
- o.onError("调用打印失败,请改用导出 PDF");
138
- } finally {
139
- n = !1;
140
- }
141
- }
142
- async function d() {
143
- if (r) return r;
144
- const i = e.value;
145
- if (!(!i || i.pages.length === 0))
146
- return r = (async () => {
147
- try {
148
- const u = await o.getPdfExporter()(i);
149
- s(
150
- new Blob([u], { type: "application/pdf" }),
151
- "mach-report.pdf"
152
- );
153
- } catch (u) {
154
- o.onError(u instanceof Error ? `PDF 导出失败: ${u.message}` : "PDF 导出失败");
155
- } finally {
156
- r = null;
157
- }
158
- })(), r;
159
- }
160
- function h(i) {
161
- const u = e.value;
162
- if (!u || u.pages.length === 0) return;
163
- if (i === "pdf") {
164
- d();
165
- return;
166
- }
167
- const { head: f, pageChunks: p } = oe(u), b = `${f}${p.join("")}</body></html>`;
168
- s(new Blob([b], { type: "text/html;charset=utf-8" }), `mach-report.${i === "html" ? "html" : i}`);
169
- }
170
- function g() {
171
- const i = e.value;
172
- if (!i || i.pages.length === 0) return;
173
- const { head: u, pageChunks: f } = oe(i), p = `${u}${f.join("")}</body></html>`, b = new Blob([p], { type: "text/html;charset=utf-8" }), k = URL.createObjectURL(b), W = window.open(k, "_blank");
174
- if (!W) {
175
- o.onError("浏览器拦截了弹窗,请允许弹窗后重试"), URL.revokeObjectURL(k);
176
- return;
177
- }
178
- setTimeout(() => W.print(), 400), setTimeout(() => URL.revokeObjectURL(k), 1e4);
179
- }
180
- return {
181
- print: l,
182
- exportAs: h,
183
- openPdfWindow: g,
184
- releasePrintFrame: t
185
- };
186
- }
187
- const Se = "mrp-hit";
188
- function st(e) {
189
- e.querySelectorAll(`mark.${Se}`).forEach((a) => {
190
- const n = a.parentNode;
191
- if (n) {
192
- for (; a.firstChild; ) n.insertBefore(a.firstChild, a);
193
- a.remove(), n.normalize();
194
- }
195
- });
196
- }
197
- function lt(e, o) {
198
- const a = o.trim();
199
- if (!a) return 0;
200
- const n = a.toLowerCase(), r = document.createTreeWalker(e, NodeFilter.SHOW_TEXT, {
201
- acceptNode(l) {
202
- const d = l.parentElement;
203
- return !d || d.closest("mark") || /^(SCRIPT|STYLE)$/.test(d.tagName) ? NodeFilter.FILTER_REJECT : (l.nodeValue ?? "").toLowerCase().includes(n) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
204
- }
205
- }), t = [];
206
- for (let l = r.nextNode(); l; l = r.nextNode()) t.push(l);
207
- let s = 0;
208
- for (const l of t) {
209
- const d = l.nodeValue ?? "", h = d.toLowerCase(), g = l.parentElement;
210
- if (!g) continue;
211
- const i = document.createDocumentFragment();
212
- let u = 0, f = h.indexOf(n);
213
- for (; f >= 0; ) {
214
- f > u && i.appendChild(document.createTextNode(d.slice(u, f)));
215
- const p = document.createElement("mark");
216
- p.className = Se, p.textContent = d.slice(f, f + a.length), i.appendChild(p), s++, u = f + a.length, f = h.indexOf(n, u);
217
- }
218
- u < d.length && i.appendChild(document.createTextNode(d.slice(u))), g.replaceChild(i, l);
219
- }
220
- return s;
221
- }
222
- function Me(e, o) {
223
- let a = 0, n = e.toLowerCase().indexOf(o);
224
- for (; n >= 0; )
225
- a++, n = e.toLowerCase().indexOf(o, n + o.length);
226
- return a;
227
- }
228
- function it(e) {
229
- const { plan: o, gotoPage: a, highlight: n, clearHighlights: r } = e, t = e.debounceMs ?? 200, s = S(!1), l = S(""), d = S(""), h = S(0);
230
- let g = null;
231
- const i = x(() => {
232
- const w = l.value.trim().toLowerCase(), F = o.value;
233
- if (!w || !F) return [];
234
- const B = [];
235
- return F.pages.forEach((N, Q) => {
236
- for (const O of N.components)
237
- if (O.grid) {
238
- for (const D of O.grid.cells ?? [])
239
- for (const G of D ?? [])
240
- if (typeof G?.text == "string")
241
- for (let _ = 0; _ < Me(G.text, w); _++) B.push(Q);
242
- } else if (O.kind === "text" && typeof O.text == "string")
243
- for (let D = 0; D < Me(O.text, w); D++) B.push(Q);
244
- }), B;
245
- }), u = x(() => i.value.length);
246
- function f(w) {
247
- if (d.value = w, g && clearTimeout(g), w.trim() === "") {
248
- g = null, l.value = "", h.value = 0;
249
- return;
250
- }
251
- g = setTimeout(() => {
252
- g = null, l.value = d.value, h.value = 0;
253
- const F = i.value[0];
254
- F != null && a(F + 1);
255
- }, t);
256
- }
257
- function p(w) {
258
- const F = i.value.length;
259
- F !== 0 && (h.value = (h.value + w + F) % F, a(i.value[h.value] + 1));
260
- }
261
- function b() {
262
- s.value = !s.value;
263
- }
264
- function k(w) {
265
- const F = l.value.trim();
266
- F && n(w, F);
267
- }
268
- function W(w) {
269
- r(w);
270
- }
271
- function H() {
272
- d.value = "", l.value = "", h.value = 0, g && clearTimeout(g), g = null;
273
- }
274
- return {
275
- visible: s,
276
- query: l,
277
- matchIndex: h,
278
- matchCount: u,
279
- toggle: b,
280
- onInput: f,
281
- onNav: p,
282
- apply: k,
283
- clear: W,
284
- reset: H
285
- };
286
- }
287
- function ut(e, o) {
288
- const a = x(() => {
289
- if (e.value) return !0;
290
- if (typeof location > "u") return !1;
291
- try {
292
- return new URLSearchParams(location.search).get("mrp-debug") === "1";
293
- } catch {
294
- return !1;
295
- }
296
- }), n = x(() => !a.value || !o.plan.value ? 0 : Math.round(JSON.stringify(o.plan.value).length / 1024)), r = x(() => !a.value || !o.plan.value ? null : {
297
- pages: o.pageCount.value,
298
- window: `${o.windowRange.value.start}-${o.windowRange.value.end}`,
299
- zoom: `${Math.round(o.zoom.value * 100)}%`,
300
- loadMs: `${o.loadMs.value}ms`,
301
- planKB: n.value
302
- });
303
- return { enabled: a, debugStats: r };
304
- }
305
- function ct(e, o) {
306
- const { thumbsRoot: a, visible: n, renderThumbCanvas: r } = o;
307
- let t = null;
308
- function s(h, g) {
309
- if (!e.value || h.childElementCount > 0) return;
310
- const i = r(g);
311
- i && (i.style.width = "100%", i.style.height = "100%", i.style.display = "block", h.appendChild(i));
312
- }
313
- return { schedule: () => {
314
- !n.value || !e.value || !a.value || typeof IntersectionObserver > "u" || (t?.disconnect(), t = new IntersectionObserver(
315
- (h) => {
316
- for (const g of h) {
317
- if (!g.isIntersecting) continue;
318
- const i = g.target;
319
- s(i, Number(i.dataset.thumb ?? 1) - 1), t?.unobserve(i);
320
- }
321
- },
322
- { root: a.value, rootMargin: "200px" }
323
- ), a.value.querySelectorAll("[data-thumb]").forEach((h) => {
324
- t.observe(h);
325
- }));
326
- }, destroy: () => {
327
- t?.disconnect(), t = null;
328
- } };
329
- }
330
- function dt() {
331
- const e = ke(0);
332
- return {
333
- loadMs: e,
334
- start() {
335
- return typeof performance < "u" ? performance.now() : 0;
336
- },
337
- end(o) {
338
- e.value = o ? Math.round(performance.now() - o) : 0;
339
- }
340
- };
341
- }
342
- const ft = { class: "mrp-toolbar" }, pt = { class: "mrp-title" }, mt = ["disabled"], gt = { class: "mrp-pageinfo" }, ht = ["disabled"], vt = {
343
- key: 1,
344
- class: "mrp-search"
345
- }, bt = ["placeholder", "value"], wt = {
346
- key: 0,
347
- class: "mrp-search-count"
348
- }, yt = ["disabled"], Pt = ["disabled"], xt = /* @__PURE__ */ $e({
349
- __name: "ReportToolbar",
350
- props: {
351
- pageCount: {},
352
- currentPage: {},
353
- zoomMode: {},
354
- zoom: {},
355
- showExport: { type: Boolean },
356
- showPrint: { type: Boolean },
357
- showPdfWindow: { type: Boolean },
358
- messages: {},
359
- search: {},
360
- thumbsVisible: { type: Boolean }
361
- },
362
- emits: ["goto", "zoom", "export", "print", "pdf-window", "search-input", "search-nav", "search-toggle", "thumbs-toggle"],
363
- setup(e) {
364
- const o = e, a = S(null);
365
- X(
366
- () => o.search.visible,
367
- (r) => {
368
- r && Ue(() => a.value?.focus());
369
- }
370
- );
371
- function n(r, t, s) {
372
- return r.replace("{cur}", String(t)).replace("{total}", String(s));
373
- }
374
- return (r, t) => (M(), C("div", ft, [
375
- y("span", pt, P(e.messages.title), 1),
376
- e.pageCount > 0 ? (M(), C(ge, { key: 0 }, [
377
- y("button", {
378
- class: "mrp-nav",
379
- type: "button",
380
- disabled: e.currentPage <= 1,
381
- onClick: t[0] || (t[0] = (s) => r.$emit("goto", e.currentPage - 1))
382
- }, P(e.messages.prevPage), 9, mt),
383
- y("span", gt, P(n(e.messages.pageInfo, e.currentPage, e.pageCount)), 1),
384
- y("button", {
385
- class: "mrp-nav",
386
- type: "button",
387
- disabled: e.currentPage >= e.pageCount,
388
- onClick: t[1] || (t[1] = (s) => r.$emit("goto", e.currentPage + 1))
389
- }, P(e.messages.nextPage), 9, ht)
390
- ], 64)) : L("", !0),
391
- t[14] || (t[14] = y("span", { class: "mrp-spacer" }, null, -1)),
392
- e.search.visible ? (M(), C("div", vt, [
393
- y("input", {
394
- ref_key: "searchInputRef",
395
- ref: a,
396
- class: "mrp-search-input",
397
- type: "text",
398
- placeholder: e.messages.searchPlaceholder,
399
- value: e.search.query,
400
- onInput: t[2] || (t[2] = (s) => r.$emit("search-input", s.target.value))
401
- }, null, 40, bt),
402
- e.search.query ? (M(), C("span", wt, P(n(e.messages.matchInfo, e.search.matchIndex + 1, e.search.matchCount)), 1)) : L("", !0),
403
- y("button", {
404
- class: "mrp-nav",
405
- type: "button",
406
- disabled: e.search.matchCount === 0,
407
- onClick: t[3] || (t[3] = (s) => r.$emit("search-nav", -1))
408
- }, P(e.messages.prevMatch), 9, yt),
409
- y("button", {
410
- class: "mrp-nav",
411
- type: "button",
412
- disabled: e.search.matchCount === 0,
413
- onClick: t[4] || (t[4] = (s) => r.$emit("search-nav", 1))
414
- }, P(e.messages.nextMatch), 9, Pt)
415
- ])) : L("", !0),
416
- y("button", {
417
- class: V(["mrp-nav", { "mrp-active": e.search.visible }]),
418
- type: "button",
419
- title: "Ctrl+F",
420
- onClick: t[5] || (t[5] = (s) => r.$emit("search-toggle"))
421
- }, " 🔍 ", 2),
422
- y("button", {
423
- class: V(["mrp-nav", { "mrp-active": e.thumbsVisible }]),
424
- type: "button",
425
- onClick: t[6] || (t[6] = (s) => r.$emit("thumbs-toggle"))
426
- }, " ▦ " + P(e.messages.thumbnails), 3),
427
- y("button", {
428
- class: V(["mrp-nav", { "mrp-active": e.zoomMode === "fit" }]),
429
- type: "button",
430
- onClick: t[7] || (t[7] = (s) => r.$emit("zoom", "fit"))
431
- }, P(e.messages.fitWidth), 3),
432
- y("button", {
433
- class: V(["mrp-nav", { "mrp-active": e.zoomMode === "raw" && Math.round(e.zoom * 100) === 100 }]),
434
- type: "button",
435
- onClick: t[8] || (t[8] = (s) => r.$emit("zoom", 100))
436
- }, " 100% ", 2),
437
- y("button", {
438
- class: V(["mrp-nav", { "mrp-active": e.zoomMode === "raw" && Math.round(e.zoom * 100) === 150 }]),
439
- type: "button",
440
- onClick: t[9] || (t[9] = (s) => r.$emit("zoom", 150))
441
- }, " 150% ", 2),
442
- e.showExport ? (M(), C("button", {
443
- key: 2,
444
- class: "mrp-nav",
445
- type: "button",
446
- onClick: t[10] || (t[10] = (s) => r.$emit("export", "html"))
447
- }, P(e.messages.exportHtml), 1)) : L("", !0),
448
- e.showExport ? (M(), C("button", {
449
- key: 3,
450
- class: "mrp-nav",
451
- type: "button",
452
- onClick: t[11] || (t[11] = (s) => r.$emit("export", "pdf"))
453
- }, P(e.messages.exportPdf), 1)) : L("", !0),
454
- e.showPrint ? (M(), C("button", {
455
- key: 4,
456
- class: "mrp-nav",
457
- type: "button",
458
- onClick: t[12] || (t[12] = (s) => r.$emit("print"))
459
- }, P(e.messages.print), 1)) : L("", !0),
460
- e.showPdfWindow ? (M(), C("button", {
461
- key: 5,
462
- class: "mrp-nav",
463
- type: "button",
464
- onClick: t[13] || (t[13] = (s) => r.$emit("pdf-window"))
465
- }, P(e.messages.pdfWindow), 1)) : L("", !0)
466
- ]));
467
- }
468
- }), Fe = (e, o) => {
469
- const a = e.__vccOpts || e;
470
- for (const [n, r] of o)
471
- a[n] = r;
472
- return a;
473
- }, Et = /* @__PURE__ */ Fe(xt, [["__scopeId", "data-v-f50c26e8"]]), Mt = {
474
- title: "报表预览",
475
- prevPage: "‹ 上一页",
476
- nextPage: "下一页 ›",
477
- pageInfo: "{cur} / {total}",
478
- fitWidth: "适宽",
479
- exportHtml: "导出 HTML",
480
- exportPdf: "导出 PDF",
481
- print: "打印",
482
- pdfWindow: "PDF 窗口",
483
- loading: "报表渲染中…",
484
- empty: "暂无预览数据",
485
- errorPrefix: "",
486
- retry: "重试",
487
- searchPlaceholder: "搜索报表内容",
488
- matchInfo: "{cur}/{total}",
489
- prevMatch: "‹",
490
- nextMatch: "›",
491
- thumbnails: "缩略图"
492
- }, Ct = {
493
- shellBg: "#525659",
494
- shellFg: "#e8e8e8",
495
- toolbarBg: "#323639",
496
- toolbarBorder: "#22252a",
497
- toolbarFg: "#e8e8e8",
498
- btnFg: "#cfcfcf",
499
- btnBorder: "#4a4d52",
500
- btnHoverBg: "#414549",
501
- btnHoverFg: "#ffffff",
502
- btnActiveBg: "#2d5fb8"
503
- };
504
- function Gt(e) {
505
- return e;
506
- }
507
- function Yt(e) {
508
- return e;
509
- }
510
- const K = {
511
- showExport: !0,
512
- showPrint: !0,
513
- showPdfWindow: !0,
514
- gapPx: 18,
515
- pdfFontUrl: "/simhei.ttf",
516
- logger: console
517
- }, Zt = { warn: () => {
518
- }, info: () => {
519
- } };
520
- function kt(e, o) {
521
- const a = o ? e?.presets?.[o] : e?.defaultPreset ? e?.presets?.[e.defaultPreset] : void 0, n = { ...e?.defaults, ...a };
522
- return {
523
- showExport: n.showExport ?? K.showExport,
524
- showPrint: n.showPrint ?? K.showPrint,
525
- showPdfWindow: n.showPdfWindow ?? K.showPdfWindow,
526
- gapPx: n.gapPx ?? K.gapPx,
527
- pdfFontUrl: n.pdfFontUrl ?? K.pdfFontUrl,
528
- theme: { ...Ct, ...n.theme },
529
- messages: { ...Mt, ...n.messages },
530
- logger: n.logger ?? K.logger
531
- };
532
- }
533
- function $t(e) {
534
- const o = {};
535
- return e.shellBg != null && (o["--mrp-shell-bg"] = e.shellBg), e.shellFg != null && (o["--mrp-shell-fg"] = e.shellFg), e.toolbarBg != null && (o["--mrp-toolbar-bg"] = e.toolbarBg), e.toolbarBorder != null && (o["--mrp-toolbar-border"] = e.toolbarBorder), e.toolbarFg != null && (o["--mrp-toolbar-fg"] = e.toolbarFg), e.btnFg != null && (o["--mrp-btn-fg"] = e.btnFg), e.btnBorder != null && (o["--mrp-btn-border"] = e.btnBorder), e.btnHoverBg != null && (o["--mrp-btn-hover-bg"] = e.btnHoverBg), e.btnHoverFg != null && (o["--mrp-btn-hover-fg"] = e.btnHoverFg), e.btnActiveBg != null && (o["--mrp-btn-active-bg"] = e.btnActiveBg), o;
536
- }
537
- function Jt(e) {
538
- const o = ae(he, null), a = x(() => {
539
- const n = o?.value ?? null, r = "defaults" in e && "presets" in e ? e : { defaults: e, presets: {} };
540
- return n ? {
541
- defaults: { ...n.defaults, ...r.defaults },
542
- presets: { ...n.presets, ...r.presets },
543
- defaultPreset: r.defaultPreset ?? n.defaultPreset
544
- } : r;
545
- });
546
- Re(he, a);
547
- }
548
- function Rt() {
549
- return ae(he, x(() => null));
550
- }
551
- class re extends Error {
552
- constructor(o, a, n) {
553
- super(a), this.name = "MachReportError", this.code = o, this.cause = n;
554
- }
555
- }
556
- function Tt(e) {
557
- return e instanceof re ? { code: e.code, cause: e.cause } : { code: "render", cause: e };
558
- }
559
- const St = { class: "mrp-main" }, Ft = {
560
- key: 0,
561
- class: "mrp-state"
562
- }, It = {
563
- key: 1,
564
- class: "mrp-state mrp-error"
565
- }, Bt = {
566
- key: 2,
567
- class: "mrp-state"
568
- }, Lt = ["data-page"], zt = ["onClick"], Wt = ["data-thumb"], Ht = { class: "mrp-thumb-no" }, Ot = { class: "mrp-overlay" }, Nt = {
569
- key: 0,
570
- class: "mrp-debug",
571
- "aria-hidden": "true"
572
- }, ne = 96 / 25.4, Ce = "mach-report:ui", Dt = /* @__PURE__ */ $e({
573
- __name: "ReportPreview",
574
- props: {
575
- tempId: {
576
- type: [String, Array],
577
- default: null
578
- },
579
- furnitureTempId: { type: String, default: "" },
580
- params: {
581
- type: Object,
582
- default: () => ({})
583
- },
584
- height: { type: String, default: "100vh" },
585
- autoLoad: { type: Boolean, default: !0 },
586
- /** 以下显隐/间距不传时走配置中心(preset > defaults > 内置缺省) */
587
- showExport: { type: Boolean, default: void 0 },
588
- showPrint: { type: Boolean, default: void 0 },
589
- showPdfWindow: { type: Boolean, default: void 0 },
590
- /** 页间距(px);不传走配置中心 */
591
- gapPx: { type: Number, default: void 0 },
592
- /** 工具栏/状态文案覆写(不传走配置中心 messages) */
593
- messages: { type: Object, default: void 0 },
594
- /** 启用的 preset 名(不传用配置中心 defaultPreset) */
595
- preset: { type: String, default: void 0 },
596
- /** 调试面板(也可用 URL ?mrp-debug=1 开启) */
597
- debug: { type: Boolean, default: !1 },
598
- fetcher: {
599
- type: Function,
600
- default: null
601
- }
602
- },
603
- emits: ["loaded", "error"],
604
- setup(e, { expose: o, emit: a }) {
605
- je((c) => ({
606
- v3c509574: p.value + "px"
607
- }));
608
- const n = e, r = a, t = ke(null), s = S(!1), l = S(""), d = S(1), h = S(null), g = S(null), i = S(null), u = S(!1), f = dt(), p = x(() => Math.max(0, G.value)), b = ae(Qe, null), W = ae(_e, null) ?? nt({ fontUrl: "/simhei.ttf" }), H = x(() => et(n.tempId)), w = x(() => t.value?.pages.length ?? 0), F = Rt(), B = x(() => kt(F.value, n.preset)), N = x(() => ({
609
- ...B.value.messages,
610
- ...n.messages
611
- })), Q = x(() => n.showExport ?? B.value.showExport), O = x(() => n.showPrint ?? B.value.showPrint), D = x(() => n.showPdfWindow ?? B.value.showPdfWindow), G = x(() => n.gapPx ?? B.value.gapPx), _ = x(() => ({
612
- height: n.height,
613
- ...$t(B.value.theme)
614
- })), { zoom: I, zoomMode: A, applyFitZoom: ve, setZoom: ie } = rt(() => ({
615
- viewport: g.value,
616
- pageWidthPx: (t.value?.pages[0]?.pageWidthMm ?? 210) * ne
617
- })), Ie = ot(t, I, {
618
- pxPerMm: ne,
619
- gapPx: G.value
620
- }), { contentSize: ue, windowRange: Y, visiblePages: Be, makeScrollHandler: Le, refreshViewport: be } = Ie, ze = Le(d, w);
621
- function ce(c) {
622
- A.value = "raw", I.value = Math.min(3, Math.max(0.3, c));
623
- }
624
- function de() {
625
- t.value = null, d.value = 1, $.reset();
626
- }
627
- let ee = 0;
628
- async function U() {
629
- const c = ++ee, E = n.fetcher ?? b;
630
- if (H.value.length === 0) {
631
- l.value = "缺少报表模板 ID", de(), r("error", l.value, { code: "param" });
632
- return;
633
- }
634
- if (!E) {
635
- l.value = "未提供渲染数据源 fetcher", de(), r("error", l.value, { code: "config" });
636
- return;
637
- }
638
- s.value = !0, l.value = "", de();
639
- const R = f.start();
640
- try {
641
- const v = await E({
642
- tempIds: H.value,
643
- furnitureTempId: n.furnitureTempId || void 0,
644
- params: { ...n.params }
645
- });
646
- if (c !== ee) return;
647
- const T = Je(v);
648
- if (!T.ok) {
649
- const Z = T.errors.slice(0, 3).map((J) => `${J.path}: ${J.message}`).join("; ");
650
- throw new re(
651
- "validate",
652
- `渲染计划校验失败(${T.errors.length} 处): ${Z}`
653
- );
654
- }
655
- T.warnings.length > 0 && B.value.logger.warn("[mach-report] 渲染计划告警:", T.warnings), t.value = v, d.value = 1, f.end(R), g.value && (g.value.scrollTop = 0), A.value === "fit" && ve(), r("loaded", v.pages.length);
656
- } catch (v) {
657
- if (c !== ee) return;
658
- const T = v instanceof re ? v : new re(
659
- "fetch",
660
- v instanceof Error ? v.message : "预览加载失败",
661
- v
662
- );
663
- l.value = T.message, r("error", T.message, Tt(T));
664
- } finally {
665
- c === ee && (s.value = !1);
666
- }
667
- }
668
- function z(c) {
669
- if (w.value <= 0) return;
670
- const E = Math.max(1, Math.min(w.value, c));
671
- d.value = E;
672
- const R = g.value;
673
- if (!R) return;
674
- let v = 0;
675
- for (let T = 0; T < E - 1; T++)
676
- v += (t.value?.pages[T]?.pageHeightMm ?? 0) * ne + p.value;
677
- R.scrollTop = v * I.value;
678
- }
679
- const { print: fe, exportAs: pe, openPdfWindow: me, releasePrintFrame: We } = at(t, {
680
- getPdfExporter: () => W,
681
- onError: (c) => r("error", c, { code: "print" })
682
- });
683
- Re(tt, { reload: U, print: fe, exportAs: pe, openPdfWindow: me, gotoPage: z });
684
- const $ = it({
685
- plan: t,
686
- gotoPage: z,
687
- highlight: lt,
688
- clearHighlights: st
689
- });
690
- function He(c) {
691
- c.ctrlKey && (c.preventDefault(), ce(I.value * (c.deltaY < 0 ? 1.1 : 1 / 1.1)));
692
- }
693
- function Oe(c) {
694
- if ((c.ctrlKey || c.metaKey) && c.key.toLowerCase() === "f") {
695
- c.preventDefault(), $.visible.value || $.toggle();
696
- return;
697
- }
698
- switch (c.key) {
699
- case "PageDown":
700
- c.preventDefault(), z(d.value + 1);
701
- break;
702
- case "PageUp":
703
- c.preventDefault(), z(d.value - 1);
704
- break;
705
- case "Home":
706
- c.preventDefault(), z(1);
707
- break;
708
- case "End":
709
- c.preventDefault(), z(w.value);
710
- break;
711
- case "+":
712
- case "=":
713
- c.preventDefault(), ce(I.value * 1.1);
714
- break;
715
- case "-":
716
- c.preventDefault(), ce(I.value / 1.1);
717
- break;
718
- }
719
- }
720
- function Ne() {
721
- try {
722
- localStorage.setItem(
723
- Ce,
724
- JSON.stringify({ zoomMode: A.value === "fit" ? "fit" : Math.round(I.value * 100) })
725
- );
726
- } catch {
727
- }
728
- }
729
- X([A, I], Ne), xe(() => {
730
- const c = t.value;
731
- if (!c) return;
732
- const E = h.value;
733
- if (!E) return;
734
- E.querySelectorAll(".mrp-page-holder").forEach((v) => {
735
- const T = Number(v.dataset.page ?? 0) - 1, Z = c.pages[T];
736
- if (!Z || v.childElementCount > 0) {
737
- if (v.firstElementChild) {
738
- const Pe = v.firstElementChild;
739
- $.clear(Pe), $.apply(Pe);
740
- }
741
- return;
742
- }
743
- v.style.width = `${Z.pageWidthMm * ne}px`;
744
- const J = Te(Z, 96, {}, document);
745
- $.apply(J), v.appendChild(J);
746
- });
747
- }, { flush: "post" }), X(() => $.query.value, (c) => {
748
- c || h.value?.querySelectorAll(".mrp-page-holder").forEach((E) => {
749
- $.clear(E);
750
- });
751
- });
752
- const we = ct(t, {
753
- thumbsRoot: i,
754
- visible: u,
755
- renderThumbCanvas: (c) => {
756
- try {
757
- const { canvases: E } = Xe(t.value, { start: c, end: c, dpr: 0.2 });
758
- return E[0] ?? null;
759
- } catch {
760
- return null;
761
- }
762
- }
763
- });
764
- xe(() => {
765
- we.schedule();
766
- }, { flush: "post" });
767
- const De = x(() => n.debug), { debugStats: j } = ut(De, {
768
- plan: t,
769
- pageCount: w,
770
- windowRange: Y,
771
- zoom: I,
772
- loadMs: f.loadMs
773
- });
774
- function ye() {
775
- be(g.value), A.value === "fit" && ve();
776
- }
777
- function Ae() {
778
- try {
779
- const c = JSON.parse(localStorage.getItem(Ce) ?? "{}");
780
- c.zoomMode === "fit" ? ie("fit") : typeof c.zoomMode == "number" && ie(c.zoomMode);
781
- } catch {
782
- }
783
- }
784
- return qe(() => {
785
- window.addEventListener("resize", ye), be(g.value), Ae(), n.autoLoad && U();
786
- }), Ke(() => {
787
- window.removeEventListener("resize", ye), we.destroy(), $.reset(), We();
788
- }), X(
789
- () => [n.tempId, n.furnitureTempId, JSON.stringify(n.params)],
790
- () => {
791
- n.autoLoad && U();
792
- }
793
- ), X(
794
- () => n.fetcher ?? b,
795
- () => {
796
- n.autoLoad && U();
797
- }
798
- ), o({ reload: U, print: fe, exportAs: pe, openPdfWindow: me, gotoPage: z }), (c, E) => (M(), C("div", {
799
- class: "mach-report-preview",
800
- style: q(_.value)
801
- }, [
802
- Ve(Et, {
803
- "page-count": w.value,
804
- "current-page": d.value,
805
- "zoom-mode": m(A),
806
- zoom: m(I),
807
- "show-export": Q.value,
808
- "show-print": O.value,
809
- "show-pdf-window": D.value,
810
- messages: N.value,
811
- search: { visible: m($).visible.value, query: m($).query.value, matchIndex: m($).matchIndex.value, matchCount: m($).matchCount.value },
812
- "thumbs-visible": u.value,
813
- onGoto: z,
814
- onZoom: m(ie),
815
- onExport: E[0] || (E[0] = (R) => m(pe)(R)),
816
- onPrint: m(fe),
817
- onPdfWindow: m(me),
818
- onSearchInput: m($).onInput,
819
- onSearchNav: m($).onNav,
820
- onSearchToggle: m($).toggle,
821
- onThumbsToggle: E[1] || (E[1] = (R) => u.value = !u.value)
822
- }, 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"]),
823
- y("div", St, [
824
- y("div", {
825
- ref_key: "viewportRef",
826
- ref: g,
827
- class: "mrp-body",
828
- tabindex: "0",
829
- onWheel: He,
830
- onKeydown: Oe,
831
- onScrollPassive: E[2] || (E[2] = (R) => m(ze)(R.target))
832
- }, [
833
- s.value ? (M(), C("div", Ft, P(N.value.loading), 1)) : l.value ? (M(), C("div", It, [
834
- Ge(P(l.value) + " ", 1),
835
- y("button", {
836
- class: "mrp-retry",
837
- type: "button",
838
- onClick: U
839
- }, P(N.value.retry), 1)
840
- ])) : !t.value || w.value === 0 ? (M(), C("div", Bt, P(N.value.empty), 1)) : (M(), C("div", {
841
- key: 3,
842
- class: "mrp-scale",
843
- style: q({ width: `${m(ue).w * m(I)}px`, height: `${m(ue).h * m(I)}px` })
844
- }, [
845
- y("div", {
846
- ref_key: "containerRef",
847
- ref: h,
848
- class: "mrp-scale-inner",
849
- style: q({ transform: `scale(${m(I)})`, transformOrigin: "top left", width: `${m(ue).w}px` })
850
- }, [
851
- m(Y).padTopPx > 0 ? (M(), C("div", {
852
- key: 0,
853
- class: "mrp-spacer-top",
854
- style: q({ height: `${m(Y).padTopPx}px` }),
855
- "aria-hidden": "true"
856
- }, null, 4)) : L("", !0),
857
- (M(!0), C(ge, null, Ee(m(Be), (R) => (M(), C("div", {
858
- key: R.index,
859
- class: "mrp-page-holder",
860
- "data-page": R.index + 1
861
- }, null, 8, Lt))), 128)),
862
- m(Y).padBottomPx > 0 ? (M(), C("div", {
863
- key: 1,
864
- class: "mrp-spacer-bottom",
865
- style: q({ height: `${m(Y).padBottomPx}px` }),
866
- "aria-hidden": "true"
867
- }, null, 4)) : L("", !0)
868
- ], 4)
869
- ], 4))
870
- ], 544),
871
- u.value && w.value > 0 ? (M(), C("aside", {
872
- key: 0,
873
- ref_key: "thumbsRef",
874
- ref: i,
875
- class: "mrp-thumbs"
876
- }, [
877
- (M(!0), C(ge, null, Ee(t.value?.pages ?? [], (R, v) => (M(), C("div", {
878
- key: v,
879
- class: V(["mrp-thumb", { "mrp-thumb-active": v + 1 === d.value }]),
880
- onClick: (T) => z(v + 1)
881
- }, [
882
- y("div", {
883
- class: "mrp-thumb-box",
884
- "data-thumb": v + 1,
885
- style: q({ height: `${Math.round(R.pageHeightMm / R.pageWidthMm * 116)}px` })
886
- }, null, 12, Wt),
887
- y("span", Ht, P(v + 1), 1)
888
- ], 10, zt))), 128))
889
- ], 512)) : L("", !0)
890
- ]),
891
- y("div", Ot, [
892
- Ye(c.$slots, "default", {}, void 0, !0)
893
- ]),
894
- m(j) ? (M(), C("div", Nt, [
895
- E[3] || (E[3] = y("div", null, "mach-report debug", -1)),
896
- y("div", null, "pages: " + P(m(j).pages) + " | window: [" + P(m(j).window) + "]", 1),
897
- y("div", null, "zoom: " + P(m(j).zoom) + " | load: " + P(m(j).loadMs), 1),
898
- y("div", null, "plan: " + P(m(j).planKB) + "KB", 1)
899
- ])) : L("", !0)
900
- ], 4));
901
- }
902
- }), At = /* @__PURE__ */ Fe(Dt, [["__scopeId", "data-v-2e98692a"]]), Xt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
903
- __proto__: null,
904
- default: At
905
- }, Symbol.toStringTag, { value: "Module" }));
906
- export {
907
- Mt as D,
908
- re as M,
909
- At as R,
910
- Zt as S,
911
- Ct as a,
912
- Et as b,
913
- oe as c,
914
- Gt as d,
915
- Yt as e,
916
- Jt as f,
917
- Tt as g,
918
- ot as h,
919
- at as i,
920
- rt as j,
921
- Xt as k,
922
- Vt as p,
923
- kt as r,
924
- $t as t,
925
- Rt as u
926
- };