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