@agile-team/mach-report 2.10.0 → 2.11.1

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 (111) hide show
  1. package/README.md +6 -2
  2. package/dist/ExcelBindingWizard-LWX6G1A2.js +1465 -0
  3. package/dist/ExcelBindingWizard-a4kslPHF.cjs +1 -0
  4. package/dist/ParamEditor-BLaE5q5W.js +522 -0
  5. package/dist/ParamEditor-MBBC7lUE.cjs +1 -0
  6. package/dist/ReportBatchPanel-B5ClP9tm.js +350 -0
  7. package/dist/ReportBatchPanel-Dc-SDkYA.cjs +1 -0
  8. package/dist/ReportPreview-DWXROHBP.cjs +6 -0
  9. package/dist/ReportPreview-DiNXhQI0.js +4138 -0
  10. package/dist/ReportTemplateLibrary-5fk5CQBO.cjs +1 -0
  11. package/dist/ReportTemplateLibrary-BZB-XWjj.js +311 -0
  12. package/dist/RuleEditor-C2QsOHOs.cjs +1 -0
  13. package/dist/RuleEditor-D9wQHrkf.js +2024 -0
  14. package/dist/TemplateReviewPanel-BKofGrV9.js +222 -0
  15. package/dist/TemplateReviewPanel-DwtOcLue.cjs +1 -0
  16. package/dist/analytics.cjs +1 -1
  17. package/dist/analytics.d.cts +2 -0
  18. package/dist/analytics.d.ts +2 -0
  19. package/dist/analytics.js +29 -29
  20. package/dist/batch-Bt3Fd27Z.cjs +1 -0
  21. package/dist/batch-mRqhhhjt.js +364 -0
  22. package/dist/computed-Bvk0W15F.js +521 -0
  23. package/dist/computed-CGV2a809.cjs +1 -0
  24. package/dist/config-B612mw0x.js +525 -0
  25. package/dist/config-BRoLo2oj.cjs +1 -0
  26. package/dist/designer.cjs +2 -2
  27. package/dist/designer.d.cts +730 -9
  28. package/dist/designer.d.ts +730 -9
  29. package/dist/designer.js +2093 -1785
  30. package/dist/index.cjs +8 -8
  31. package/dist/index.d.cts +161 -3
  32. package/dist/index.d.ts +161 -3
  33. package/dist/index.js +486 -431
  34. package/dist/injection-keys-Db_DyLkm.cjs +1 -0
  35. package/dist/injection-keys-e85udZCp.js +7 -0
  36. package/dist/list-cell-BuYn4tGF.cjs +1 -0
  37. package/dist/{list-cell-Dxyi7DOw.js → list-cell-ClFra1zS.js} +54 -40
  38. package/dist/matrix-DVyWiYsd.cjs +1 -0
  39. package/dist/matrix-yZsGnldA.js +227 -0
  40. package/dist/param-validation-BlHHXs6u.js +153 -0
  41. package/dist/param-validation-DCK039V1.cjs +1 -0
  42. package/dist/pdf.cjs +25 -25
  43. package/dist/pdf.d.cts +3 -0
  44. package/dist/pdf.d.ts +3 -0
  45. package/dist/pdf.js +677 -677
  46. package/dist/plugin-BDTU4D94.cjs +1 -0
  47. package/dist/plugin-Cd5G2QQn.js +22 -0
  48. package/dist/region-binding-workflow-CXDmt9Bs.js +977 -0
  49. package/dist/region-binding-workflow-DhQvu1co.cjs +3 -0
  50. package/dist/{report-params-B_VCihAh.js → report-params-B44imUd4.js} +1 -1
  51. package/dist/{report-params-CjWrjPl6.cjs → report-params-SJfhKgaX.cjs} +1 -1
  52. package/dist/server/node.d.cts +5 -2
  53. package/dist/server/node.d.ts +5 -2
  54. package/dist/server-node.cjs +1 -1
  55. package/dist/server-node.js +87 -87
  56. package/dist/server.cjs +1 -1
  57. package/dist/server.d.cts +201 -2
  58. package/dist/server.d.ts +201 -2
  59. package/dist/server.js +557 -658
  60. package/dist/style.css +1 -1
  61. package/dist/template-registry-WNXdkiET.js +506 -0
  62. package/dist/template-registry-ukBGlm8N.cjs +1 -0
  63. package/dist/template-review-BXp2oyqg.cjs +1 -0
  64. package/dist/template-review-BdcXSYbx.js +1616 -0
  65. package/dist/tree-BX380Rr7.cjs +1 -0
  66. package/dist/tree-CqcQ99NM.js +172 -0
  67. package/dist/{validate-UUy9yP4K.js → validate-7s0yn6ii.js} +44 -44
  68. package/dist/validate-DsRiNw8h.cjs +1 -0
  69. package/dist/vue/async.d.cts +93 -4
  70. package/dist/vue/async.d.ts +93 -4
  71. package/dist/vue/index.d.cts +145 -7
  72. package/dist/vue/index.d.ts +145 -7
  73. package/dist/vue-async.cjs +1 -1
  74. package/dist/vue-async.js +5 -5
  75. package/dist/vue.cjs +1 -1
  76. package/dist/vue.js +116 -113
  77. package/dist/{workbook-session-B-bW5_yR.js → workbook-session-BKOTwcoq.js} +1 -1
  78. package/dist/{workbook-session-D7RtdNo0.cjs → workbook-session-CLYLhZWu.cjs} +1 -1
  79. package/dist/worker.cjs +1 -1
  80. package/dist/worker.d.cts +5 -2
  81. package/dist/worker.d.ts +5 -2
  82. package/dist/worker.js +1 -1
  83. package/dist/xlsx.cjs +3 -3
  84. package/dist/xlsx.d.cts +129 -2
  85. package/dist/xlsx.d.ts +129 -2
  86. package/dist/xlsx.js +336 -242
  87. package/package.json +1 -1
  88. package/dist/ExcelBindingWizard-CF7RplWm.cjs +0 -1
  89. package/dist/ExcelBindingWizard-qhwEderR.js +0 -842
  90. package/dist/ReportPreview-BE1tCHqE.js +0 -4604
  91. package/dist/ReportPreview-QKRKQOe3.cjs +0 -6
  92. package/dist/RuleEditor-BA36yIV6.js +0 -1723
  93. package/dist/RuleEditor-CczJ6mJm.cjs +0 -1
  94. package/dist/TemplateReviewPanel-CHi4Alqa.cjs +0 -1
  95. package/dist/TemplateReviewPanel-Dz0G5o83.js +0 -217
  96. package/dist/binding-preview-BWsdf_z2.cjs +0 -2
  97. package/dist/binding-preview-DILq0-0f.js +0 -649
  98. package/dist/decimal-CI1OAczk.js +0 -87
  99. package/dist/decimal-CQA0xJex.cjs +0 -1
  100. package/dist/list-cell-CyM1ZlRN.cjs +0 -1
  101. package/dist/matrix-BbXarwyk.js +0 -661
  102. package/dist/matrix-Cm65WLLP.cjs +0 -1
  103. package/dist/param-validation-BWNjLcN0.js +0 -116
  104. package/dist/param-validation-CiTxFeZ8.cjs +0 -1
  105. package/dist/plugin-CThk42vJ.cjs +0 -1
  106. package/dist/plugin-tGn7-5oF.js +0 -25
  107. package/dist/template-registry-CGWTLtIA.cjs +0 -1
  108. package/dist/template-registry-DzlQs3OF.js +0 -434
  109. package/dist/template-review-D1RoNCPw.cjs +0 -1
  110. package/dist/template-review-fnteXRng.js +0 -1473
  111. package/dist/validate-Bf6ccFr2.cjs +0 -1
@@ -1,649 +0,0 @@
1
- import { v as j } from "./dataset-H5pFuQGU.js";
2
- import { v as N, d as D, p as H } from "./template-registry-DzlQs3OF.js";
3
- import { r as C } from "./grid-geometry-BNptEcMm.js";
4
- function $(t) {
5
- let e = "";
6
- for (let o = t; o > 0; o = Math.floor((o - 1) / 26)) e = String.fromCharCode(65 + (o - 1) % 26) + e;
7
- return e;
8
- }
9
- function A(t) {
10
- return `${$(t.left)}${t.top}:${$(t.right)}${t.bottom}`;
11
- }
12
- function I(t) {
13
- let e = 0;
14
- for (const o of t.toUpperCase()) e = e * 26 + o.charCodeAt(0) - 64;
15
- return e;
16
- }
17
- function u(t) {
18
- if (typeof t != "string") throw new Error("Excel 范围应为 A1:B20 格式的字符串");
19
- const e = /^\$?([A-Z]{1,3})\$?([1-9]\d{0,6})(?::\$?([A-Z]{1,3})\$?([1-9]\d{0,6}))?$/i.exec(t.trim());
20
- if (!e) throw new Error(`Excel 范围无效:${t}`);
21
- const o = { left: I(e[1]), top: Number(e[2]), right: I(e[3] ?? e[1]), bottom: Number(e[4] ?? e[2]) };
22
- if (o.right < o.left || o.bottom < o.top || o.right > 16384 || o.bottom > 1048576)
23
- throw new Error(`Excel 范围超出边界或顺序无效:${t}`);
24
- return o;
25
- }
26
- function dt(t, e) {
27
- if (e !== void 0) return u(e);
28
- const o = t.model.rows ?? [];
29
- if (!o.length) return { top: 1, left: 1, bottom: 1, right: 1 };
30
- const n = { top: 1 / 0, left: 1 / 0, bottom: 1, right: 1 };
31
- for (const r of o)
32
- n.top = Math.min(n.top, r.number), n.bottom = Math.max(n.bottom, r.number), n.left = Math.min(n.left, r.min || 1), n.right = Math.max(n.right, r.max || 1);
33
- return n;
34
- }
35
- function wt(t, e, o) {
36
- const n = t.bottom - t.top + 1, r = t.right - t.left + 1;
37
- if (n > e.limits.maxRows || r > e.limits.maxColumns || n * r > o)
38
- throw new Error(`Excel 范围 ${A(t)} 超过导入行、列或单元格上限;请用 sheets/range 缩小范围`);
39
- return n * r;
40
- }
41
- function P(t, e) {
42
- return t.top <= e.bottom && t.bottom >= e.top && t.left <= e.right && t.right >= e.left;
43
- }
44
- function yt(t, e) {
45
- const o = [];
46
- for (const n of t.model.merges) {
47
- const r = u(n);
48
- if (P(e, r)) {
49
- if (r.left < e.left || r.right > e.right || r.top < e.top || r.bottom > e.bottom)
50
- throw new Error(`${t.name}: 范围 ${A(e)} 截断合并单元格 ${n},请包含完整合并区域`);
51
- o.push(r);
52
- }
53
- }
54
- return o;
55
- }
56
- function bt(t, e) {
57
- const o = /* @__PURE__ */ new Map();
58
- for (const r of e) o.set(r.top, Math.max(o.get(r.top) ?? r.top, r.bottom));
59
- const n = [];
60
- for (let r = t.top; r <= t.bottom; ) {
61
- let s = o.get(r) ?? r;
62
- for (let i = r; i <= s; i++) s = Math.max(s, o.get(i) ?? i);
63
- n.push({ top: r, bottom: s }), r = s + 1;
64
- }
65
- return n;
66
- }
67
- function Et(t, e, o, n) {
68
- const r = [];
69
- let s, i = 0;
70
- for (const a of t) {
71
- const l = a.bottom - a.top + 1;
72
- if (l > 200) throw new Error("合并单元格跨越超过 200 行,无法安全分段;请先缩小或拆分该合并区域");
73
- let c = 0;
74
- for (let p = a.top; p <= a.bottom; p++) c += n(p);
75
- if (c > o && Number.isFinite(o)) throw new Error("合并区域或单行高度超过标准纸张可用高度;请使用 wide 或调整原模板行高");
76
- const m = s ? a.bottom - s.top + 1 : l;
77
- s && (m > e || i + c > o) && (r.push(s), s = void 0, i = 0), s ? s.bottom = a.bottom : s = { ...a }, i += c;
78
- }
79
- return s && r.push(s), r;
80
- }
81
- function $t(t) {
82
- const e = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Set();
83
- for (const n of t) {
84
- e.set(`${n.top}:${n.left}`, n);
85
- for (let r = n.top; r <= n.bottom; r++)
86
- for (let s = n.left; s <= n.right; s++)
87
- (r !== n.top || s !== n.left) && o.add(`${r}:${s}`);
88
- }
89
- return { masters: e, covered: o };
90
- }
91
- function x(t) {
92
- return JSON.parse(JSON.stringify(t));
93
- }
94
- function _(t, e) {
95
- const o = t.template.pages.slice(e.pageStart, e.pageStart + e.pageCount), n = o[0];
96
- if (!n) throw new Error(`工作表 ${e.name} 没有可绑定页面`);
97
- const r = /* @__PURE__ */ new Map();
98
- let s = [];
99
- for (const i of o)
100
- for (const a of i.components) {
101
- if (a.kind === "list" || !a.grid || a.meta?.xlsxSheet !== e.name) continue;
102
- const l = u(String(a.meta.xlsxRange)), c = a.grid;
103
- s = c.colWidthsMm ?? [], c.cells.forEach((m, p) => r.set(l.top + p, { cells: x(m), height: c.rowHeightsMm?.[p] ?? 6 }));
104
- }
105
- if (!s.length || !r.size) throw new Error(`工作表 ${e.name} 缺少导入几何元数据`);
106
- return { rows: r, widths: [...s], page: n, range: u(e.range) };
107
- }
108
- function k(t, e, o) {
109
- const n = [], r = [];
110
- for (let s = e; s <= o; s++) {
111
- const i = t.rows.get(s);
112
- if (!i) throw new Error(`导入模板缺少第 ${s} 行`);
113
- for (const a of i.cells)
114
- if (a && s + (a.rowSpan ?? 1) - 1 > o) throw new Error(`第 ${s} 行合并区域跨越绑定边界,请调整 header/detail 范围`);
115
- n.push(x(i.cells)), r.push(i.height);
116
- }
117
- return { cells: n, rowHeightsMm: r, colWidthsMm: t.widths, paddingMm: 0.25 };
118
- }
119
- function G(t, e) {
120
- const o = u(t.header), n = t.detail ? u(t.detail) : { ...e.range, top: o.bottom + 1 };
121
- for (const r of [o, n])
122
- if (r.left !== e.range.left || r.right !== e.range.right || r.top < e.range.top || r.bottom > e.range.bottom || r.top > r.bottom) throw new Error("绑定区域必须位于导入选区内并覆盖其完整列宽");
123
- if (n.top !== o.bottom + 1) throw new Error("detail 应紧接 header,避免静态内容被隐式删除");
124
- if (t.columns.length !== e.widths.length) throw new Error("columns 应逐列映射整个选区;不能自动猜测业务字段");
125
- return L(e, [o.top, o.bottom + 1, n.bottom + 1]), { header: o, detail: n };
126
- }
127
- function L(t, e) {
128
- for (const [o, n] of t.rows) for (const r of n.cells) {
129
- const s = o + (r?.rowSpan ?? 1);
130
- if (e.some((i) => o < i && s > i)) throw new Error(`第 ${o} 行合并区域跨越绑定边界,请调整 header/detail 范围`);
131
- }
132
- }
133
- function Y(t, e) {
134
- const o = [];
135
- for (const n of C(t, e.reduce((r, s) => r + s, 0), 100).cells)
136
- for (let r = n.ci; r < Math.min(e.length, n.ci + (n.cell.colSpan ?? 1)); r++) o[r] = n.cell;
137
- return o;
138
- }
139
- function W(t, e, o, n) {
140
- if (e) return e;
141
- const r = t?.numberFormat;
142
- if (!r || r === "General") return;
143
- const s = /^(#,##)?0(?:\.(0+))?(%)?$/.exec(r);
144
- if (s) {
145
- const i = s[2]?.length ?? 0;
146
- if (i <= 100) return s[3] ? { kind: "percent", digits: i } : { kind: "number", digits: i, ...s[1] ? { thousands: !0 } : {} };
147
- }
148
- n.push(`${o}: Excel 数字格式 ${r} 未自动套用到动态数据,请在 columns 中显式声明 format`);
149
- }
150
- function Z(t, e, o, n, r) {
151
- const s = Y(e, n), i = C(o, n.reduce((m, p) => m + p, 0), 20).cells;
152
- if (i.some(({ cell: m }) => (m.colSpan ?? 1) !== 1 || (m.rowSpan ?? 1) !== 1)) throw new Error("动态明细样例行不能包含合并格;合并表头可以保留");
153
- const a = new Map(i.map((m) => [m.ci, m.cell])), l = /* @__PURE__ */ new Set(), c = t.columns.map((m, p) => {
154
- const f = typeof m == "string" ? { field: m } : m;
155
- if (!f || typeof f.field != "string" || !f.field.trim() || l.has(f.field)) throw new Error(`columns[${p}] 需要唯一的非空 field`);
156
- l.add(f.field);
157
- const g = s[p]?.text ?? f.field, h = a.get(p), w = t.inferSampleFormats === !1 ? f.format : W(h, f.format, f.field, r);
158
- return { ...f, ...w ? { format: w } : {}, header: f.header ?? g, widthMm: n[p], style: { ...h?.style, ...f.style }, ...f.semanticRole && !f.align ? { align: "auto" } : {}, ...f.editable === void 0 && h?.editable === !1 ? { editable: !1 } : {} };
159
- });
160
- return z(t, s, c), c;
161
- }
162
- function z(t, e, o) {
163
- const n = /* @__PURE__ */ new Map();
164
- t.columns.forEach((r, s) => {
165
- const i = e[s];
166
- if (!i || typeof r == "string") return;
167
- const a = n.get(i) ?? { style: {} };
168
- if (r.header !== void 0) {
169
- if (a.text !== void 0 && a.text !== r.header) throw new Error("同一合并表头不能配置不同 header");
170
- a.text = r.header;
171
- }
172
- U(a.style, { ...r.headerAlign ? { align: r.headerAlign } : {}, ...r.headerStyle }), n.set(i, a);
173
- });
174
- for (const [r, s] of n)
175
- s.text !== void 0 && Object.assign(r, { text: s.text, rawText: s.text, value: s.text }), r.style = { ...r.style, ...s.style }, e.forEach((i, a) => {
176
- i === r && (s.text !== void 0 && (o[a].header = s.text), s.style.align !== void 0 && (o[a].headerAlign = s.style.align));
177
- });
178
- }
179
- function U(t, e) {
180
- for (const o of Object.keys(e))
181
- if (e[o] !== void 0) {
182
- if (t[o] !== void 0 && t[o] !== e[o]) throw new Error(`同一合并表头不能配置不同 ${o}`);
183
- Object.assign(t, { [o]: e[o] });
184
- }
185
- }
186
- function V(t, e) {
187
- const o = t.page, n = e.rowHeightsMm.reduce((r, s) => r + s, 0);
188
- return { ...o, heightMm: Math.max(o.heightMm, n + (o.marginTopMm ?? 0) + (o.marginBottomMm ?? 0)), components: [{ kind: "rect", leftMm: o.marginLeftMm ?? 0, topMm: o.marginTopMm ?? 0, widthMm: t.widths.reduce((r, s) => r + s, 0), heightMm: n, grid: e }] };
189
- }
190
- function q(t, e, o, n) {
191
- const r = _(t, e), { header: s, detail: i } = G(o, r), a = k(r, r.range.top, s.bottom), l = k(r, i.top, i.top), c = { ...r.page, components: [] }, m = {
192
- kind: "list",
193
- id: `bound:${e.name}`,
194
- dataset: o.dataset ?? "detail",
195
- title: e.name,
196
- leftMm: c.marginLeftMm ?? 0,
197
- topMm: c.marginTopMm ?? 0,
198
- widthMm: r.widths.reduce((p, f) => p + f, 0),
199
- layout: c.layout ?? "page",
200
- headerGrid: a,
201
- columns: Z(o, a, l, r.widths, n),
202
- rowHeightMm: l.rowHeightsMm[0],
203
- headerEveryPage: !0,
204
- align: "auto",
205
- paddingMm: 0.25,
206
- ...o.rowKey ? { rowKey: o.rowKey } : {},
207
- ...o.revisionField ? { revisionField: o.revisionField } : {},
208
- ...o.sourceTokenField ? { sourceTokenField: o.sourceTokenField } : {},
209
- ...o.groupBy ? { groupBy: o.groupBy } : {},
210
- ...o.grandTotal === void 0 ? {} : { grandTotal: o.grandTotal }
211
- };
212
- return c.components.push(m), i.bottom === r.range.bottom ? [c] : (n.push(`${e.name}: 明细区域后的静态内容保留为后续独立页面,不推断动态页脚定位`), [c, V(r, k(r, i.bottom + 1, r.range.bottom))]);
213
- }
214
- function Q(t, e) {
215
- const o = N(t.template);
216
- if (!o.ok) throw new Error(`导入模板无效:${o.errors[0]?.message}`);
217
- if (!e.length) throw new Error("至少需要一个 Excel 业务绑定");
218
- const n = /* @__PURE__ */ new Map();
219
- for (const l of e) {
220
- if (!t.sheets.some((c) => c.name === l.sheet) || n.has(l.sheet)) throw new Error(`绑定工作表不存在或重复:${l.sheet}`);
221
- n.set(l.sheet, l);
222
- }
223
- const r = [...t.warnings], s = t.sheets.flatMap((l) => {
224
- const c = n.get(l.name);
225
- return c ? q(t, l, c, r) : x(t.template.pages.slice(l.pageStart, l.pageStart + l.pageCount));
226
- }), i = { ...x(t.template), pages: s }, a = N(i);
227
- if (!a.ok) throw new Error(`业务模板无效:${a.errors[0]?.path} ${a.errors[0]?.message}`);
228
- return { template: i, warnings: r };
229
- }
230
- function X(t, e) {
231
- return tt(t, e);
232
- }
233
- function tt(t, e) {
234
- const o = t.sheets.find((l) => l.name === e.sheet);
235
- if (!o) return [];
236
- const n = u(e.regions.header), r = u(e.regions.detail), s = [n.top, n.bottom + 1, r.bottom + 1], i = [], a = /* @__PURE__ */ new Set();
237
- for (const l of t.template.pages.slice(
238
- o.pageStart,
239
- o.pageStart + o.pageCount
240
- ))
241
- for (const c of l.components) {
242
- if (c.kind === "list" || !c.grid || c.meta?.xlsxSheet !== e.sheet)
243
- continue;
244
- const m = u(String(c.meta.xlsxRange));
245
- c.grid.cells.forEach((p, f) => {
246
- const g = m.top + f;
247
- for (const h of p) {
248
- const w = s.some(
249
- (E) => g < E && g + (h?.rowSpan ?? 1) > E
250
- ), b = g === r.top && ((h?.rowSpan ?? 1) > 1 || (h?.colSpan ?? 1) > 1);
251
- if (!w && !b) continue;
252
- const y = w ? "$.recipe.regions" : "$.recipe.regions.detail";
253
- a.has(y) || (a.add(y), i.push({
254
- path: y,
255
- code: "region",
256
- message: w ? `第 ${g} 行合并区域跨越绑定边界,请选择完整合并区域` : "动态明细原型行不能包含合并格"
257
- }));
258
- }
259
- });
260
- }
261
- return i;
262
- }
263
- function F(t) {
264
- return JSON.parse(JSON.stringify(t));
265
- }
266
- function S(t) {
267
- return t instanceof Error ? t.message : String(t);
268
- }
269
- function d(t, e, o, n) {
270
- t.push({ path: e, code: o, message: n });
271
- }
272
- function K(t, e) {
273
- return { fields: t.fields, ...e ? { rowKey: e } : {} };
274
- }
275
- function et(t, e) {
276
- const o = /* @__PURE__ */ new Set();
277
- for (const [n, r] of t.entries()) {
278
- const s = `$.datasets[${n}]`;
279
- if (!r || typeof r.id != "string" || !r.id.trim() || o.has(r.id)) {
280
- d(e, s, "schema", "数据集标识应非空且唯一");
281
- continue;
282
- }
283
- o.add(r.id);
284
- try {
285
- j([], K(r, r.rowKey));
286
- for (const [i, a] of r.fields.entries())
287
- a.digits !== void 0 && (!Number.isInteger(a.digits) || a.digits < 0 || a.digits > 100) && d(
288
- e,
289
- `${s}.fields[${i}].digits`,
290
- "schema",
291
- "显示精度应为 0–100 的整数"
292
- );
293
- } catch (i) {
294
- d(e, s, "schema", S(i));
295
- }
296
- }
297
- }
298
- function ot(t, e, o) {
299
- const n = t.sheets.find((a) => a.name === e.sheet);
300
- if (!n) {
301
- d(o, "$.recipe.sheet", "source", "指定的工作表不存在");
302
- return;
303
- }
304
- let r;
305
- try {
306
- r = u(n.range);
307
- } catch (a) {
308
- d(o, "$.source.sheets", "source", S(a));
309
- return;
310
- }
311
- const s = /* @__PURE__ */ new Map();
312
- for (const a of ["title", "header", "detail", "footer"]) {
313
- const l = e.regions?.[a];
314
- if (!(!l && (a === "title" || a === "footer")))
315
- try {
316
- const c = u(l ?? "");
317
- if (c.left !== r.left || c.right !== r.right || c.top < r.top || c.bottom > r.bottom)
318
- throw new Error("区域必须覆盖选区完整列宽,并位于原始工作表内");
319
- s.set(a, c);
320
- } catch (c) {
321
- d(o, `$.recipe.regions.${a}`, "region", S(c));
322
- }
323
- }
324
- const i = [...s.values()];
325
- i.length && (i[0].top !== r.top || i[i.length - 1].bottom !== r.bottom) && d(
326
- o,
327
- "$.recipe.regions",
328
- "region",
329
- "标题、表头、明细、页脚应完整覆盖来源,不能隐式删除静态内容"
330
- );
331
- for (let a = 1; a < i.length; a++)
332
- i[a].top !== i[a - 1].bottom + 1 && d(o, "$.recipe.regions", "region", "各区域应顺序相邻且不重叠");
333
- }
334
- function rt(t, e, o, n) {
335
- if (!Array.isArray(t.fields) || t.fields.length !== o)
336
- return d(
337
- n,
338
- "$.recipe.fields",
339
- "mapping",
340
- "每个物理 Excel 列必须显式绑定一个业务字段"
341
- ), 0;
342
- const r = new Set(e.fields.map((a) => a.field)), s = /* @__PURE__ */ new Set();
343
- let i = 0;
344
- t.fields.forEach((a, l) => {
345
- typeof a != "string" || !r.has(a) ? d(
346
- n,
347
- `$.recipe.fields[${l}]`,
348
- "mapping",
349
- "请选择契约中已声明的字段"
350
- ) : s.has(a) ? d(
351
- n,
352
- `$.recipe.fields[${l}]`,
353
- "mapping",
354
- "同一业务字段不能重复绑定物理列"
355
- ) : (i++, s.add(a));
356
- });
357
- try {
358
- if (!t.rowKey)
359
- throw new Error("请明确选择稳定业务主键,不能使用展示行号");
360
- const a = K(e, t.rowKey), l = j(e.samples ?? [], a, {
361
- path: `$.datasets.${e.id}.samples`,
362
- maxRows: 100,
363
- maxCells: 2e5,
364
- maxIssues: 30
365
- });
366
- for (const c of l.issues)
367
- d(
368
- n,
369
- c.path,
370
- c.code === "row-key" ? "row-key" : "schema",
371
- c.message
372
- );
373
- } catch (a) {
374
- d(n, "$.recipe.rowKey", "row-key", S(a));
375
- }
376
- return i;
377
- }
378
- function nt(t, e) {
379
- const o = [];
380
- return !e || e.version !== "1.0" ? [
381
- {
382
- path: "$.recipe.version",
383
- code: "schema",
384
- message: "不支持的 Excel 绑定配置版本"
385
- }
386
- ] : (ot(t, e, o), o.length || o.push(...X(t, e)), o);
387
- }
388
- function st(t, e, o) {
389
- const n = [];
390
- if (!e || e.version !== "1.0")
391
- return {
392
- ok: !1,
393
- issues: [
394
- {
395
- path: "$.recipe.version",
396
- code: "schema",
397
- message: "不支持的 Excel 绑定配置版本"
398
- }
399
- ],
400
- mapped: 0,
401
- total: 0
402
- };
403
- et(o, n);
404
- const r = t.sheets.find((a) => a.name === e.sheet)?.columnCount ?? 0, s = o.find((a) => a.id === e.dataset);
405
- let i = 0;
406
- return s ? n.some((a) => a.code === "schema") || (i = rt(e, s, r, n)) : d(
407
- n,
408
- "$.recipe.dataset",
409
- "schema",
410
- "请明确选择宿主提供的数据集契约"
411
- ), { ok: n.length === 0, issues: n, mapped: i, total: r };
412
- }
413
- function at(t, e, o) {
414
- const n = st(t, e, o);
415
- if (!e || e.version !== "1.0") return n;
416
- const r = [
417
- ...nt(t, e),
418
- ...n.issues
419
- ];
420
- return { ...n, ok: r.length === 0, issues: r };
421
- }
422
- function it(t) {
423
- const e = t.semanticRole ?? (t.type === "number" || t.type === "decimal" ? "measure" : t.type === "date" ? "date" : "text");
424
- return {
425
- field: t.field,
426
- semanticRole: e,
427
- editable: !1,
428
- ...t.type === "number" && t.digits !== void 0 ? { format: { kind: "number", digits: t.digits } } : {},
429
- ...t.type === "date" ? { format: { kind: "date", pattern: "YYYY-MM-DD" } } : {}
430
- };
431
- }
432
- function xt(t, e, o, n) {
433
- const r = at(t, e, o);
434
- if (!r.ok)
435
- throw new Error(
436
- r.issues.map((m) => `${m.path}: ${m.message}`).join(`
437
- `)
438
- );
439
- const s = t.sheets.find((m) => m.name === e.sheet), i = {
440
- ...t,
441
- sheets: [{ ...s, pageStart: 0 }],
442
- template: {
443
- ...t.template,
444
- pages: t.template.pages.slice(
445
- s.pageStart,
446
- s.pageStart + s.pageCount
447
- )
448
- }
449
- }, a = new Map(
450
- o.find((m) => m.id === e.dataset).fields.map((m) => [m.field, m])
451
- ), l = {
452
- sheet: e.sheet,
453
- dataset: e.dataset,
454
- header: e.regions.header,
455
- detail: e.regions.detail,
456
- rowKey: e.rowKey,
457
- inferSampleFormats: !1,
458
- columns: e.fields.map((m) => it(a.get(m)))
459
- }, c = Q(i, [l]);
460
- return {
461
- document: D({ ...n, template: c.template }),
462
- recipe: F(e),
463
- warnings: c.warnings
464
- };
465
- }
466
- function ct(t) {
467
- return t === null || typeof t == "string" || typeof t == "boolean" || typeof t == "number" && Number.isFinite(t);
468
- }
469
- function J(t, e = 0) {
470
- if (ct(t)) return;
471
- if (!t || typeof t != "object" || e > 16)
472
- throw new Error("绑定会话元数据只允许有限深度的普通 JSON 值");
473
- const o = Object.getPrototypeOf(t);
474
- if (Array.isArray(t) ? o !== Array.prototype : o !== Object.prototype && o !== null)
475
- throw new Error("绑定会话不能包含特殊对象原型");
476
- if (Object.getOwnPropertySymbols(t).length)
477
- throw new Error("绑定会话不能包含 Symbol");
478
- if (Array.isArray(t) && Object.keys(t).length !== t.length)
479
- throw new Error("绑定会话数组不能包含空位或额外属性");
480
- for (const [n, r] of Object.entries(
481
- Object.getOwnPropertyDescriptors(t)
482
- ))
483
- if (!(Array.isArray(t) && n === "length")) {
484
- if (["__proto__", "prototype", "constructor"].includes(n) || r.get || r.set || !r.enumerable)
485
- throw new Error("绑定会话包含不安全元数据");
486
- J(r.value, e + 1);
487
- }
488
- }
489
- function lt(t, e) {
490
- if (t?.version !== "1.0" || !Array.isArray(t.fields) || t.fields.length > 16384 || t.fields.some((o) => typeof o != "string"))
491
- throw new Error("Excel 绑定配置无效");
492
- if (typeof t.dataset != "string" || typeof t.rowKey != "string" || !t.regions || typeof e?.id != "string" || typeof e.name != "string")
493
- throw new Error("Excel 绑定参数或标识无效");
494
- for (const o of Object.values(t.regions))
495
- o !== "" && u(o);
496
- }
497
- function ft(t) {
498
- for (const e of t.sheets)
499
- if (u(e.range), typeof e.name != "string" || ![e.index, e.rowCount, e.columnCount, e.pageCount].every(
500
- (o) => Number.isInteger(o) && o > 0
501
- ) || !Number.isInteger(e.pageStart) || e.pageStart < 0 || e.pageStart + e.pageCount > t.template.pages.length)
502
- throw new Error("Excel 绑定工作表几何元数据无效");
503
- }
504
- function mt(t, e, o) {
505
- if (J({
506
- sheets: t.sheets,
507
- warnings: t.warnings,
508
- recipe: e,
509
- identity: o
510
- }), !Array.isArray(t.sheets) || !t.sheets.length || t.sheets.length > 32 || !Array.isArray(t.warnings) || t.warnings.some((n) => typeof n != "string"))
511
- throw new Error("Excel 绑定来源元数据无效");
512
- if (lt(e, o), !t.sheets.some((n) => n.name === e.sheet))
513
- throw new Error("Excel 绑定工作表不存在");
514
- ft(t);
515
- }
516
- function gt(t, e, o) {
517
- return mt(t, e, o), H({
518
- schemaVersion: "1.0",
519
- id: o.id,
520
- name: o.name,
521
- template: t.template
522
- }), F({ version: "1.0", source: t, recipe: e, identity: o });
523
- }
524
- function St(t) {
525
- if (typeof t == "string" && t.length > 1e7)
526
- throw new Error("Excel 绑定会话超过 1000 万字符上限");
527
- const e = typeof t == "string" ? JSON.parse(t) : t;
528
- if (!e || e.version !== "1.0" || e.recipe?.version !== "1.0" || !Array.isArray(e.source?.sheets))
529
- throw new Error("Excel 绑定会话结构或版本无效");
530
- return gt(
531
- e.source,
532
- e.recipe,
533
- e.identity
534
- );
535
- }
536
- function Mt(t, e, o, n) {
537
- const r = t.sheets.find((l) => l.name === e);
538
- if (!r) throw new Error("工作表不存在");
539
- const s = u(r.range), i = Math.min(o, n), a = Math.max(o, n);
540
- if (!Number.isInteger(i) || !Number.isInteger(a) || i < s.top || a > s.bottom)
541
- throw new Error("选中行超出来源区域");
542
- return A({ ...s, top: i, bottom: a });
543
- }
544
- function T(t, e, o) {
545
- const n = t ?? e;
546
- if (!Number.isInteger(n) || n < 1 || n > o)
547
- throw new Error(`预览窗口大小应为 1–${o} 的整数`);
548
- return n;
549
- }
550
- function B(t, e, o) {
551
- const n = t ?? e;
552
- if (!Number.isInteger(n)) throw new Error("预览起点应为整数");
553
- return Math.max(e, Math.min(o, n));
554
- }
555
- function vt(t, e, o = {}) {
556
- const n = t.sheets.find((f) => f.name === e);
557
- if (!n) throw new Error("指定的工作表不存在");
558
- const r = u(n.range), s = B(o.row, r.top, r.bottom), i = B(o.column, r.left, r.right), a = Math.min(
559
- r.bottom,
560
- s + T(o.rows, 24, 100) - 1
561
- ), l = Math.min(
562
- r.right,
563
- i + T(o.columns, 12, 32) - 1
564
- ), c = Array.from({ length: a - s + 1 }, (f, g) => ({
565
- row: s + g,
566
- cells: []
567
- })), m = /* @__PURE__ */ new Set();
568
- for (const f of t.template.pages.slice(
569
- n.pageStart,
570
- n.pageStart + n.pageCount
571
- ))
572
- for (const g of f.components) {
573
- if (g.kind === "list" || !g.grid || g.meta?.xlsxSheet !== e)
574
- continue;
575
- const h = u(String(g.meta.xlsxRange));
576
- if (h.bottom < s || h.top > a) continue;
577
- const w = C(
578
- g.grid,
579
- g.widthMm,
580
- g.heightMm
581
- );
582
- for (const b of w.cells)
583
- p(b.cell, h.top + b.ri, h.left + b.ci);
584
- }
585
- for (const f of c) {
586
- for (let g = i; g <= l; g++)
587
- m.has(`${f.row}:${g}`) || f.cells.push({
588
- address: `${$(g)}${f.row}`,
589
- row: f.row,
590
- column: g,
591
- text: "",
592
- rowSpan: 1,
593
- colSpan: 1,
594
- continued: !1
595
- });
596
- f.cells.sort((g, h) => g.column - h.column);
597
- }
598
- return {
599
- top: s,
600
- bottom: a,
601
- left: i,
602
- right: l,
603
- source: r,
604
- rows: c,
605
- columns: Array.from({ length: l - i + 1 }, (f, g) => ({
606
- column: i + g,
607
- name: $(i + g)
608
- }))
609
- };
610
- function p(f, g, h) {
611
- const w = g + (f.rowSpan ?? 1) - 1, b = h + (f.colSpan ?? 1) - 1;
612
- if (w < s || g > a || b < i || h > l)
613
- return;
614
- const y = Math.max(s, g), E = Math.max(i, h), R = Math.min(a, w) - y + 1, O = Math.min(l, b) - E + 1;
615
- c[y - s].cells.push({
616
- address: `${$(h)}${g}`,
617
- row: y,
618
- column: E,
619
- text: f.text ?? f.rawText ?? String(f.value ?? ""),
620
- rowSpan: R,
621
- colSpan: O,
622
- continued: y !== g || E !== h,
623
- style: f.style
624
- });
625
- for (let M = y; M < y + R; M++)
626
- for (let v = E; v < E + O; v++)
627
- m.add(`${M}:${v}`);
628
- }
629
- }
630
- export {
631
- gt as a,
632
- Q as b,
633
- xt as c,
634
- at as d,
635
- Mt as e,
636
- nt as f,
637
- vt as g,
638
- u as h,
639
- $ as i,
640
- wt as j,
641
- yt as k,
642
- Et as l,
643
- bt as m,
644
- $t as n,
645
- St as p,
646
- A as r,
647
- dt as s,
648
- st as v
649
- };