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