@veltra/sheet 2.3.4 → 2.4.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.
- package/dist/components/report/binding-badge.js +6 -0
- package/dist/components/report/designer/drill-dialog.js +258 -0
- package/dist/components/report/designer/float-panel.js +26 -14
- package/dist/components/report/print.js +39 -0
- package/dist/components/report/report-designer.js +56 -21
- package/dist/components/report/report-viewer.js +173 -44
- package/dist/components/report/style2.css +91 -0
- package/dist/components/report/use-report-designer.js +1 -0
- package/dist/components/report/use-report-viewer.js +88 -3
- package/dist/index.d.ts +4 -2
- package/dist/index.js +3 -1
- package/dist/report/drill.d.ts +48 -0
- package/dist/report/drill.js +78 -0
- package/dist/report/index.d.ts +4 -2
- package/dist/report/print.d.ts +23 -0
- package/dist/report/print.js +197 -0
- package/dist/report/render/aggregate.js +25 -1
- package/dist/report/types.d.ts +19 -1
- package/dist/types/report-designer.d.ts +13 -0
- package/dist/types/report-viewer.d.ts +19 -0
- package/package.json +6 -6
- package/src/components/report/__test__/report-designer.test.ts +98 -3
- package/src/components/report/__test__/report-drill.test.ts +692 -0
- package/src/components/report/__test__/report-viewer.test.ts +43 -0
- package/src/components/report/__test__/use-report-designer.test.ts +108 -1
- package/src/components/report/binding-badge.ts +5 -0
- package/src/components/report/designer/drill-dialog.vue +245 -0
- package/src/components/report/designer/float-panel.vue +12 -0
- package/src/components/report/print.ts +44 -0
- package/src/components/report/report-designer.vue +35 -2
- package/src/components/report/report-viewer.vue +171 -18
- package/src/components/report/style-designer.scss +66 -0
- package/src/components/report/style-viewer.scss +40 -0
- package/src/components/report/use-report-designer.ts +1 -0
- package/src/components/report/use-report-viewer.ts +150 -11
- package/src/report/__test__/drill.test.ts +194 -0
- package/src/report/__test__/print.test.ts +170 -0
- package/src/report/drill.ts +112 -0
- package/src/report/index.ts +4 -1
- package/src/report/print.ts +234 -0
- package/src/report/render/aggregate.ts +28 -0
- package/src/report/types.ts +20 -0
- package/src/types/report-designer.ts +18 -1
- package/src/types/report-viewer.ts +18 -1
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import _sfc_main$1 from "../sheet/sheet.js";
|
|
2
2
|
import { exportFilledReportXlsx } from "../../report/export-xlsx.js";
|
|
3
|
+
import { buildFilledReportPrintHtml } from "../../report/print.js";
|
|
3
4
|
import { applyGridColWidths, applySheetColWidths } from "./designer/col-widths.js";
|
|
4
5
|
import _sfc_main$2 from "./filter-bar.js";
|
|
5
6
|
import { previewGridSize } from "./preview-grid-size.js";
|
|
7
|
+
import { printHtmlDocument } from "./print.js";
|
|
6
8
|
import { useReportViewer } from "./use-report-viewer.js";
|
|
7
|
-
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, nextTick, normalizeClass, openBlock, toDisplayString, unref, useTemplateRef, watch } from "vue";
|
|
9
|
+
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, nextTick, normalizeClass, openBlock, ref, resolveComponent, shallowRef, toDisplayString, unref, useTemplateRef, watch, withCtx } from "vue";
|
|
10
|
+
import { UButton, UDialog } from "@veltra/desktop";
|
|
8
11
|
import { bem } from "@veltra/utils";
|
|
9
12
|
import { saveBlob } from "@cat-kit/fe";
|
|
10
13
|
import { Workbook } from "@veltra/sheet-core";
|
|
11
14
|
//#region src/components/report/report-viewer.vue
|
|
12
15
|
const EXPORT_NOT_READY_MESSAGE = "报表数据尚未就绪,请等待取数完成后再导出";
|
|
13
16
|
const EXPORT_LOADING_MESSAGE = "报表数据加载中,请稍后再导出";
|
|
17
|
+
/** 取数未完成时拒绝打印的可读错误 */
|
|
18
|
+
const PRINT_NOT_READY_MESSAGE = "报表数据尚未就绪,请等待取数完成后再打印";
|
|
19
|
+
const PRINT_LOADING_MESSAGE = "报表数据加载中,请稍后再打印";
|
|
14
20
|
/** 查看器工作簿:宿主可注入(同 USheet `workbook?` 先例),缺省内部自建;模板 / 填充结果都 restore 进活动 sheet 只读展示 */
|
|
15
21
|
const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
16
22
|
name: "UReportViewer",
|
|
@@ -19,26 +25,45 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
19
25
|
connector: {},
|
|
20
26
|
template: {},
|
|
21
27
|
workbook: {},
|
|
22
|
-
colWidths: {}
|
|
28
|
+
colWidths: {},
|
|
29
|
+
resolveTemplate: { type: Function },
|
|
30
|
+
initialValues: {}
|
|
23
31
|
},
|
|
24
32
|
setup(__props, { expose: __expose }) {
|
|
33
|
+
/** 与 `ReportViewerProps` 交叉显式列出下钻 props,避免 SFC 对跨文件 interface 漏抽 runtime 声明 */
|
|
25
34
|
const props = __props;
|
|
26
35
|
const cls = bem("report-viewer");
|
|
27
36
|
/** 取数未完成时拒绝导出的可读错误 */
|
|
28
37
|
const internalWorkbook = new Workbook();
|
|
29
38
|
const workbook = computed(() => props.workbook ?? internalWorkbook);
|
|
30
39
|
const sheetRef = useTemplateRef("sheetRef");
|
|
31
|
-
const { params, values, loading, error, filledSnapshot, filledColWidths, refresh, setValues } = useReportViewer(props);
|
|
40
|
+
const { params, values, loading, error, filledSnapshot, filledColWidths, currentTemplate, canDrillBack, resolveDrillHit, resolveDrillTarget, drillInto, drillBack, refresh, setValues } = useReportViewer(props);
|
|
41
|
+
/** 配了下钻的单元格在查看态展示可点击链接样式(蓝字 + 下划线),便于用户直观感知 */
|
|
42
|
+
const resolveViewerCellStyle = (addr, base) => {
|
|
43
|
+
if (!props.resolveTemplate) return base;
|
|
44
|
+
if (!resolveDrillHit(addr)) return base;
|
|
45
|
+
return {
|
|
46
|
+
...base,
|
|
47
|
+
font: {
|
|
48
|
+
...base?.font,
|
|
49
|
+
color: base?.font?.color ?? "#2f54eb",
|
|
50
|
+
underline: base?.font?.underline ?? true
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
/** 弹框下钻:先挂 UDialog 再打开,避免 modelValue 初始为 true 时 overlay 不进入 */
|
|
55
|
+
const drillDialogVisible = ref(false);
|
|
56
|
+
const drillDialog = shallowRef(null);
|
|
32
57
|
const renderSize = computed(() => {
|
|
33
58
|
const filled = filledSnapshot.value;
|
|
34
59
|
if (filled) return previewGridSize(filled, "filled");
|
|
35
|
-
return previewGridSize(
|
|
60
|
+
return previewGridSize(currentTemplate.value, "template");
|
|
36
61
|
});
|
|
37
|
-
/**
|
|
62
|
+
/** 宿主显式传入优先;否则取数完成后用展开映射列宽;再回落当前层模板设计态列宽 */
|
|
38
63
|
const effectiveColWidths = computed(() => {
|
|
39
64
|
if (props.colWidths?.length) return props.colWidths;
|
|
40
65
|
if (filledColWidths.value?.length) return filledColWidths.value;
|
|
41
|
-
return
|
|
66
|
+
return currentTemplate.value.colWidths;
|
|
42
67
|
});
|
|
43
68
|
/** 将运行时列宽写入模型与 VTable(模型为单一事实源;grid 构造/content-reset 也会回放) */
|
|
44
69
|
function applyRuntimeColWidths() {
|
|
@@ -64,11 +89,65 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
64
89
|
sheet.history.clear();
|
|
65
90
|
nextTick(applyRuntimeColWidths);
|
|
66
91
|
}
|
|
67
|
-
watch(
|
|
92
|
+
watch(currentTemplate, (template) => applySnapshot(template, "template"), { immediate: true });
|
|
68
93
|
watch(filledSnapshot, (filled) => {
|
|
69
94
|
if (filled) applySnapshot(filled, "filled");
|
|
70
95
|
});
|
|
71
96
|
watch(effectiveColWidths, applyRuntimeColWidths);
|
|
97
|
+
/** 悬停命中下钻格时给网格加 cursor 提示 */
|
|
98
|
+
const drillHover = ref(false);
|
|
99
|
+
let pointerStart = null;
|
|
100
|
+
watch(drillDialogVisible, (visible) => {
|
|
101
|
+
if (!visible) drillDialog.value = null;
|
|
102
|
+
});
|
|
103
|
+
async function openDrillDialog(config, record) {
|
|
104
|
+
const next = await resolveDrillTarget(config, record);
|
|
105
|
+
if (!next) return;
|
|
106
|
+
drillDialog.value = next;
|
|
107
|
+
await nextTick();
|
|
108
|
+
drillDialogVisible.value = true;
|
|
109
|
+
}
|
|
110
|
+
/** 事件坐标 → 模型地址(经当前 SheetGrid 命中测试;网格随内容尺寸重建,实例按事件时刻取) */
|
|
111
|
+
function resolveEventAddr(event) {
|
|
112
|
+
const gridEl = event.currentTarget.querySelector(".u-sheet__grid-instance");
|
|
113
|
+
const grid = sheetRef.value?.getGrid();
|
|
114
|
+
if (!gridEl || !grid) return null;
|
|
115
|
+
const rect = gridEl.getBoundingClientRect();
|
|
116
|
+
return grid.hitTestSheetAddr(event.clientX - rect.left, event.clientY - rect.top);
|
|
117
|
+
}
|
|
118
|
+
function handleGridPointerDown(event) {
|
|
119
|
+
pointerStart = {
|
|
120
|
+
x: event.clientX,
|
|
121
|
+
y: event.clientY
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function handleGridClick(event) {
|
|
125
|
+
if (!props.resolveTemplate) return;
|
|
126
|
+
const start = pointerStart;
|
|
127
|
+
pointerStart = null;
|
|
128
|
+
if (start) {
|
|
129
|
+
const dx = event.clientX - start.x;
|
|
130
|
+
const dy = event.clientY - start.y;
|
|
131
|
+
if (dx * dx + dy * dy > 16) return;
|
|
132
|
+
}
|
|
133
|
+
const addr = resolveEventAddr(event);
|
|
134
|
+
if (!addr) return;
|
|
135
|
+
const hit = resolveDrillHit(addr);
|
|
136
|
+
if (!hit) return;
|
|
137
|
+
if (hit.config.openMode === "dialog") {
|
|
138
|
+
openDrillDialog(hit.config, hit.record);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
drillInto(hit.config, hit.record);
|
|
142
|
+
}
|
|
143
|
+
function handleGridPointerMove(event) {
|
|
144
|
+
const addr = props.resolveTemplate ? resolveEventAddr(event) : null;
|
|
145
|
+
const next = !!(addr ? resolveDrillHit(addr) : null);
|
|
146
|
+
if (next !== drillHover.value) drillHover.value = next;
|
|
147
|
+
}
|
|
148
|
+
function handleGridPointerLeave() {
|
|
149
|
+
drillHover.value = false;
|
|
150
|
+
}
|
|
72
151
|
async function exportXlsx() {
|
|
73
152
|
if (loading.value) throw new Error(EXPORT_LOADING_MESSAGE);
|
|
74
153
|
if (!filledSnapshot.value) throw new Error(EXPORT_NOT_READY_MESSAGE);
|
|
@@ -76,47 +155,97 @@ const _sfc_main = /*@__PURE__*/ defineComponent({
|
|
|
76
155
|
const buffer = await exportFilledReportXlsx(sheet);
|
|
77
156
|
saveBlob(new Blob([buffer], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }), `${sheet.name || "报表"}.xlsx`);
|
|
78
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* 打印填充报表(纯前端):填充 sheet 模型 → 打印专用 HTML(buildFilledReportPrintHtml)
|
|
160
|
+
* → 隐藏 iframe 调起浏览器打印。守卫语义与 exportXlsx 一致(取数完成前拒绝)。
|
|
161
|
+
*/
|
|
162
|
+
function print(options) {
|
|
163
|
+
if (loading.value) throw new Error(PRINT_LOADING_MESSAGE);
|
|
164
|
+
if (!filledSnapshot.value) throw new Error(PRINT_NOT_READY_MESSAGE);
|
|
165
|
+
printHtmlDocument(buildFilledReportPrintHtml(workbook.value.activeSheet, options));
|
|
166
|
+
}
|
|
79
167
|
__expose({
|
|
80
168
|
refresh,
|
|
81
|
-
exportXlsx
|
|
169
|
+
exportXlsx,
|
|
170
|
+
print
|
|
82
171
|
});
|
|
83
172
|
return (_ctx, _cache) => {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
"
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
"
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
"
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
173
|
+
const _component_u_report_viewer = resolveComponent("u-report-viewer");
|
|
174
|
+
return openBlock(), createElementBlock("div", { class: normalizeClass(unref(cls).b) }, [
|
|
175
|
+
unref(params).length ? (openBlock(), createBlock(_sfc_main$2, {
|
|
176
|
+
key: 0,
|
|
177
|
+
"query-params": unref(params),
|
|
178
|
+
values: unref(values),
|
|
179
|
+
"onUpdate:values": unref(setValues)
|
|
180
|
+
}, null, 8, [
|
|
181
|
+
"query-params",
|
|
182
|
+
"values",
|
|
183
|
+
"onUpdate:values"
|
|
184
|
+
])) : createCommentVNode("v-if", true),
|
|
185
|
+
unref(canDrillBack) ? (openBlock(), createElementBlock("div", {
|
|
186
|
+
key: 1,
|
|
187
|
+
class: normalizeClass(unref(cls).e("drill-bar"))
|
|
188
|
+
}, [createVNode(unref(UButton), {
|
|
189
|
+
size: "small",
|
|
190
|
+
plain: "",
|
|
191
|
+
onClick: unref(drillBack)
|
|
192
|
+
}, {
|
|
193
|
+
default: withCtx(() => [..._cache[1] || (_cache[1] = [createTextVNode("返回上一层", -1)])]),
|
|
194
|
+
_: 1
|
|
195
|
+
}, 8, ["onClick"])], 2)) : createCommentVNode("v-if", true),
|
|
196
|
+
createElementVNode("div", { class: normalizeClass(unref(cls).e("body")) }, [unref(loading) ? (openBlock(), createElementBlock("div", {
|
|
197
|
+
key: 0,
|
|
198
|
+
class: normalizeClass(unref(cls).e("loading")),
|
|
199
|
+
"aria-live": "polite"
|
|
200
|
+
}, [createElementVNode("div", { class: normalizeClass(unref(cls).e("loading-spinner")) }, null, 2), _cache[2] || (_cache[2] = createElementVNode("span", null, "正在加载报表数据…", -1))], 2)) : unref(error) ? (openBlock(), createElementBlock("div", {
|
|
201
|
+
key: 1,
|
|
202
|
+
class: normalizeClass(unref(cls).e("error")),
|
|
203
|
+
role: "alert"
|
|
204
|
+
}, toDisplayString(unref(error).message), 3)) : createCommentVNode("v-if", true), createVNode(unref(_sfc_main$1), {
|
|
205
|
+
ref_key: "sheetRef",
|
|
206
|
+
ref: sheetRef,
|
|
207
|
+
class: normalizeClass([unref(cls).e("sheet"), drillHover.value ? unref(cls).em("sheet", "drill-hover") : ""]),
|
|
208
|
+
workbook: workbook.value,
|
|
209
|
+
rows: renderSize.value.rows,
|
|
210
|
+
cols: renderSize.value.cols,
|
|
211
|
+
"show-toolbar": false,
|
|
212
|
+
"show-formula-bar": false,
|
|
213
|
+
"show-tabs": false,
|
|
214
|
+
"show-row-header": false,
|
|
215
|
+
"show-col-header": false,
|
|
216
|
+
"resolve-cell-style": resolveViewerCellStyle,
|
|
217
|
+
readonly: "",
|
|
218
|
+
onPointerdown: handleGridPointerDown,
|
|
219
|
+
onPointermove: handleGridPointerMove,
|
|
220
|
+
onPointerleave: handleGridPointerLeave,
|
|
221
|
+
onClick: handleGridClick
|
|
222
|
+
}, null, 8, [
|
|
223
|
+
"class",
|
|
224
|
+
"workbook",
|
|
225
|
+
"rows",
|
|
226
|
+
"cols"
|
|
227
|
+
])], 2),
|
|
228
|
+
drillDialog.value ? (openBlock(), createBlock(unref(UDialog), {
|
|
229
|
+
key: 2,
|
|
230
|
+
modelValue: drillDialogVisible.value,
|
|
231
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => drillDialogVisible.value = $event),
|
|
232
|
+
title: "详情报表",
|
|
233
|
+
class: normalizeClass(unref(cls).e("drill-dialog"))
|
|
234
|
+
}, {
|
|
235
|
+
default: withCtx(() => [createVNode(_component_u_report_viewer, {
|
|
236
|
+
connector: __props.connector,
|
|
237
|
+
template: drillDialog.value.template,
|
|
238
|
+
"initial-values": drillDialog.value.params,
|
|
239
|
+
"resolve-template": __props.resolveTemplate
|
|
240
|
+
}, null, 8, [
|
|
241
|
+
"connector",
|
|
242
|
+
"template",
|
|
243
|
+
"initial-values",
|
|
244
|
+
"resolve-template"
|
|
245
|
+
])]),
|
|
246
|
+
_: 1
|
|
247
|
+
}, 8, ["modelValue", "class"])) : createCommentVNode("v-if", true)
|
|
248
|
+
], 2);
|
|
120
249
|
};
|
|
121
250
|
}
|
|
122
251
|
});
|
|
@@ -37,6 +37,40 @@
|
|
|
37
37
|
flex: 1;
|
|
38
38
|
min-height: 0;
|
|
39
39
|
min-width: 0;
|
|
40
|
+
/* 下钻格可点提示:VTable pointermove 会把容器内联 cursor 重置为 default,需 !important 覆盖 */
|
|
41
|
+
}
|
|
42
|
+
.u-report-viewer__sheet--drill-hover,
|
|
43
|
+
.u-report-viewer__sheet--drill-hover .u-sheet__grid-instance,
|
|
44
|
+
.u-report-viewer__sheet--drill-hover .u-sheet__grid-instance canvas,
|
|
45
|
+
.u-report-viewer__sheet--drill-hover .u-sheet__grid-instance * {
|
|
46
|
+
cursor: pointer !important;
|
|
47
|
+
}
|
|
48
|
+
.u-report-viewer__drill-bar {
|
|
49
|
+
display: flex;
|
|
50
|
+
align-items: center;
|
|
51
|
+
gap: var(--u-gap-small);
|
|
52
|
+
}
|
|
53
|
+
.u-report-viewer {
|
|
54
|
+
/* 下钻弹框挂在 UDialog 根(Teleport 到 body),给内嵌查看器明确高度 */
|
|
55
|
+
}
|
|
56
|
+
.u-report-viewer__drill-dialog {
|
|
57
|
+
width: min(960px, 92vw);
|
|
58
|
+
height: min(80vh, 720px);
|
|
59
|
+
}
|
|
60
|
+
.u-report-viewer__drill-dialog .u-dialog__body {
|
|
61
|
+
flex: 1;
|
|
62
|
+
min-height: 0;
|
|
63
|
+
display: flex;
|
|
64
|
+
flex-direction: column;
|
|
65
|
+
}
|
|
66
|
+
.u-report-viewer__drill-dialog .u-scroll__container,
|
|
67
|
+
.u-report-viewer__drill-dialog .u-scroll__content {
|
|
68
|
+
height: 100%;
|
|
69
|
+
min-height: 0;
|
|
70
|
+
}
|
|
71
|
+
.u-report-viewer__drill-dialog .u-report-viewer {
|
|
72
|
+
height: 100%;
|
|
73
|
+
min-height: 0;
|
|
40
74
|
}
|
|
41
75
|
.u-report-viewer__loading {
|
|
42
76
|
position: absolute;
|
|
@@ -368,6 +402,63 @@
|
|
|
368
402
|
color: var(--u-text-color-second);
|
|
369
403
|
}
|
|
370
404
|
|
|
405
|
+
/* 下钻配置对话框内容 */
|
|
406
|
+
.u-report-drill-dialog {
|
|
407
|
+
display: flex;
|
|
408
|
+
flex-direction: column;
|
|
409
|
+
gap: 12px;
|
|
410
|
+
}
|
|
411
|
+
.u-report-drill-dialog__section {
|
|
412
|
+
display: flex;
|
|
413
|
+
flex-direction: column;
|
|
414
|
+
gap: 6px;
|
|
415
|
+
}
|
|
416
|
+
.u-report-drill-dialog__label {
|
|
417
|
+
font-size: 12px;
|
|
418
|
+
font-weight: 600;
|
|
419
|
+
color: var(--u-text-color-second);
|
|
420
|
+
}
|
|
421
|
+
.u-report-drill-dialog__hint {
|
|
422
|
+
margin: 0;
|
|
423
|
+
font-size: 12px;
|
|
424
|
+
line-height: 1.5;
|
|
425
|
+
color: var(--u-text-color-second);
|
|
426
|
+
}
|
|
427
|
+
.u-report-drill-dialog__error {
|
|
428
|
+
margin: 0;
|
|
429
|
+
font-size: 12px;
|
|
430
|
+
line-height: 1.5;
|
|
431
|
+
color: var(--u-color-danger);
|
|
432
|
+
}
|
|
433
|
+
.u-report-drill-dialog__list {
|
|
434
|
+
margin: 0;
|
|
435
|
+
padding: 0;
|
|
436
|
+
list-style: none;
|
|
437
|
+
display: flex;
|
|
438
|
+
flex-direction: column;
|
|
439
|
+
gap: 8px;
|
|
440
|
+
max-height: 320px;
|
|
441
|
+
overflow: auto;
|
|
442
|
+
}
|
|
443
|
+
.u-report-drill-dialog__mapping {
|
|
444
|
+
display: flex;
|
|
445
|
+
align-items: center;
|
|
446
|
+
gap: 6px;
|
|
447
|
+
}
|
|
448
|
+
.u-report-drill-dialog__field {
|
|
449
|
+
width: 160px;
|
|
450
|
+
flex: none;
|
|
451
|
+
}
|
|
452
|
+
.u-report-drill-dialog__param {
|
|
453
|
+
width: 200px;
|
|
454
|
+
flex: none;
|
|
455
|
+
}
|
|
456
|
+
.u-report-drill-dialog__arrow {
|
|
457
|
+
flex: none;
|
|
458
|
+
font-size: 12px;
|
|
459
|
+
color: var(--u-text-color-second);
|
|
460
|
+
}
|
|
461
|
+
|
|
371
462
|
.u-report-rule-row {
|
|
372
463
|
display: flex;
|
|
373
464
|
align-items: flex-start;
|
|
@@ -152,6 +152,7 @@ function useReportDesigner(options) {
|
|
|
152
152
|
};
|
|
153
153
|
if ("rowParent" in patch && patch.rowParent === void 0) delete next.rowParent;
|
|
154
154
|
if ("colParent" in patch && patch.colParent === void 0) delete next.colParent;
|
|
155
|
+
if ("drill" in patch && patch.drill === void 0) delete next.drill;
|
|
155
156
|
if (("aggregate" in patch || "expand" in patch) && !("preset" in patch) && !presetStillApplies(next)) delete next.preset;
|
|
156
157
|
if (patch.preset === "subtotal") {
|
|
157
158
|
const inferred = inferParentsForPreset(cell, "subtotal", getBindingAt);
|
|
@@ -1,22 +1,34 @@
|
|
|
1
|
+
import { buildDrillHitMap, createDrillStack, currentDrillLayer, popDrillLayer, pushDrillLayer, resolveDrillParams } from "../../report/drill.js";
|
|
1
2
|
import { renderReport, resolveFilledColWidths } from "../../report/render/index.js";
|
|
2
3
|
import { fetchTemplateRecords, resolveParamDefaults, resolveTemplateParams } from "../../report/template.js";
|
|
3
4
|
import { computed, ref, shallowRef, watch } from "vue";
|
|
5
|
+
import { cellKey } from "@veltra/sheet-core";
|
|
4
6
|
//#region src/components/report/use-report-viewer.ts
|
|
5
7
|
/**
|
|
6
8
|
* UReportViewer 的 headless 编排:参数提取 → 取数 → renderReport 展开。
|
|
7
9
|
* 不持有 DOM / 网格引用;填充快照经 `filledSnapshot` 交给组件壳应用。
|
|
10
|
+
* 下钻:openMode 'switch' 栈式切换当前层;'dialog' 由组件壳解析目标后嵌套独立查看器。
|
|
11
|
+
* 导出 / 打印始终作用于当前可见层。
|
|
8
12
|
*/
|
|
9
13
|
function useReportViewer(props) {
|
|
10
14
|
const loading = ref(false);
|
|
11
15
|
const error = shallowRef(null);
|
|
12
16
|
const filledSnapshot = shallowRef(null);
|
|
13
17
|
const filledColWidths = shallowRef(void 0);
|
|
14
|
-
const
|
|
18
|
+
const drillStack = shallowRef(null);
|
|
19
|
+
const drillHits = shallowRef(/* @__PURE__ */ new Map());
|
|
20
|
+
const currentTemplate = computed(() => {
|
|
21
|
+
const stack = drillStack.value;
|
|
22
|
+
return stack ? currentDrillLayer(stack).template : props.template;
|
|
23
|
+
});
|
|
24
|
+
const drillDepth = computed(() => (drillStack.value?.length ?? 1) - 1);
|
|
25
|
+
const canDrillBack = computed(() => drillDepth.value > 0);
|
|
26
|
+
const params = computed(() => resolveTemplateParams(currentTemplate.value));
|
|
15
27
|
const values = shallowRef({});
|
|
16
28
|
let fetchSeq = 0;
|
|
17
29
|
async function refresh() {
|
|
18
30
|
const current = ++fetchSeq;
|
|
19
|
-
const template =
|
|
31
|
+
const template = currentTemplate.value;
|
|
20
32
|
loading.value = true;
|
|
21
33
|
error.value = null;
|
|
22
34
|
const result = await fetchTemplateRecords(props.connector, template, values.value);
|
|
@@ -29,15 +41,81 @@ function useReportViewer(props) {
|
|
|
29
41
|
}
|
|
30
42
|
filledSnapshot.value = renderReport(template, result.data);
|
|
31
43
|
filledColWidths.value = template.colWidths?.length ? resolveFilledColWidths(template, result.data, template.colWidths) : void 0;
|
|
44
|
+
drillHits.value = props.resolveTemplate ? buildDrillHitMap(template, result.data) : /* @__PURE__ */ new Map();
|
|
45
|
+
}
|
|
46
|
+
/** 切层共有收尾:清填充结果与命中索引,写入新层参数并重新取数 */
|
|
47
|
+
function transitionTo(layerParams) {
|
|
48
|
+
filledSnapshot.value = null;
|
|
49
|
+
filledColWidths.value = void 0;
|
|
50
|
+
drillHits.value = /* @__PURE__ */ new Map();
|
|
51
|
+
values.value = layerParams;
|
|
52
|
+
return refresh();
|
|
53
|
+
}
|
|
54
|
+
async function resolveDrillTarget(config, record) {
|
|
55
|
+
const resolve = props.resolveTemplate;
|
|
56
|
+
if (!resolve) return null;
|
|
57
|
+
let target;
|
|
58
|
+
try {
|
|
59
|
+
target = await resolve(config.target);
|
|
60
|
+
} catch (err) {
|
|
61
|
+
error.value = {
|
|
62
|
+
code: "DRILL_RESOLVE_FAILED",
|
|
63
|
+
message: err instanceof Error ? err.message : String(err)
|
|
64
|
+
};
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
if (!target) {
|
|
68
|
+
error.value = {
|
|
69
|
+
code: "DRILL_RESOLVE_FAILED",
|
|
70
|
+
message: `下钻目标模板解析失败:${config.target}`
|
|
71
|
+
};
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
error.value = null;
|
|
75
|
+
return {
|
|
76
|
+
template: target,
|
|
77
|
+
params: {
|
|
78
|
+
...resolveParamDefaults(resolveTemplateParams(target)),
|
|
79
|
+
...resolveDrillParams(config, record)
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
async function drillInto(config, record) {
|
|
84
|
+
const next = await resolveDrillTarget(config, record);
|
|
85
|
+
if (!next) return;
|
|
86
|
+
const base = drillStack.value ?? createDrillStack({
|
|
87
|
+
template: props.template,
|
|
88
|
+
params: values.value
|
|
89
|
+
});
|
|
90
|
+
drillStack.value = pushDrillLayer(base, {
|
|
91
|
+
template: next.template,
|
|
92
|
+
params: next.params
|
|
93
|
+
}, values.value);
|
|
94
|
+
await transitionTo(next.params);
|
|
95
|
+
}
|
|
96
|
+
async function drillBack() {
|
|
97
|
+
const stack = drillStack.value;
|
|
98
|
+
if (!stack || stack.length <= 1) return;
|
|
99
|
+
const next = popDrillLayer(stack);
|
|
100
|
+
drillStack.value = next;
|
|
101
|
+
await transitionTo({ ...currentDrillLayer(next).params });
|
|
102
|
+
}
|
|
103
|
+
function resolveDrillHit(addr) {
|
|
104
|
+
return drillHits.value.get(cellKey(addr)) ?? null;
|
|
32
105
|
}
|
|
33
106
|
function setValues(next) {
|
|
34
107
|
values.value = next;
|
|
35
108
|
refresh();
|
|
36
109
|
}
|
|
37
110
|
watch(() => props.template, () => {
|
|
111
|
+
drillStack.value = null;
|
|
112
|
+
drillHits.value = /* @__PURE__ */ new Map();
|
|
38
113
|
filledSnapshot.value = null;
|
|
39
114
|
filledColWidths.value = void 0;
|
|
40
|
-
values.value =
|
|
115
|
+
values.value = {
|
|
116
|
+
...resolveParamDefaults(params.value),
|
|
117
|
+
...props.initialValues
|
|
118
|
+
};
|
|
41
119
|
refresh();
|
|
42
120
|
}, { immediate: true });
|
|
43
121
|
return {
|
|
@@ -47,6 +125,13 @@ function useReportViewer(props) {
|
|
|
47
125
|
error,
|
|
48
126
|
filledSnapshot,
|
|
49
127
|
filledColWidths,
|
|
128
|
+
currentTemplate,
|
|
129
|
+
drillDepth,
|
|
130
|
+
canDrillBack,
|
|
131
|
+
resolveDrillHit,
|
|
132
|
+
resolveDrillTarget,
|
|
133
|
+
drillInto,
|
|
134
|
+
drillBack,
|
|
50
135
|
refresh,
|
|
51
136
|
setValues
|
|
52
137
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import _sfc_main from "./components/report/report-designer.js";
|
|
|
4
4
|
import { SheetContext, createSheetContext } from "./tools/context.js";
|
|
5
5
|
import { SheetTool, SheetToolGroup, SheetToolPopupType, defaultToolRegistry, registerTool, unregisterTool } from "./tools/registry.js";
|
|
6
6
|
import { SheetEmits, SheetExposed, SheetProps, _SheetExposed } from "./types/sheet.js";
|
|
7
|
-
import { ConditionalOperator, ConditionalRule, DatasetCatalogItem, DatasetField, DatasetRecords, ParamValues, QueryParamDef, QueryParamOption, QueryParamType, ReportAggregate, ReportBinding, ReportExpand, ReportPreset, ReportSort } from "./report/types.js";
|
|
7
|
+
import { ConditionalOperator, ConditionalRule, DatasetCatalogItem, DatasetField, DatasetRecords, ParamValues, QueryParamDef, QueryParamOption, QueryParamType, ReportAggregate, ReportBinding, ReportDrillConfig, ReportExpand, ReportPreset, ReportSort, ReportTemplateListItem } from "./report/types.js";
|
|
8
8
|
import { InferParentOptions, ListParentCandidateOptions, REPORT_META_NAMESPACE, applyReportPreset, createReportBinding, formatBindingPlaceholder, formatBindingPlaceholderParts, formatCellAddress, formatParentCandidateLabel, inferColParentCandidate, inferDropPreset, inferParentsForPreset, inferReportPreset, inferRowParentCandidate, isColGroupBinding, isExpansionBandCol, isExpansionBandRow, isHorizontalExpandBinding, isReductionAggregate, isRowGroupBinding, isVerticalExpandBinding, listColParentCandidates, listRowParentCandidates, parseCellAddress, prefersGroupParent, presetBindingPatch, presetStillApplies, setBindingCatalog } from "./report/binding.js";
|
|
9
9
|
import { ConditionalEvalContext, evaluateCondition, evaluateConditionalStyle, resolveRuleCompareValue, toComparableNumber } from "./report/rules/evaluate.js";
|
|
10
10
|
import { buildParamDefs, extractParamIds, resolveBoundDatasetParams } from "./report/params.js";
|
|
@@ -14,8 +14,10 @@ import { renderReport, resolveFilledColWidths } from "./report/render/index.js";
|
|
|
14
14
|
import { ConnectionType, ConnectorError, CreateHttpConnectorOptions, DEFAULT_CONNECTION_PORTS, DataConnection, DataConnector, QueryResult, Result, createHttpConnector, resolvePortOnTypeChange } from "./report/connector.js";
|
|
15
15
|
import { IncompatibleTemplateVersionError, REPORT_TEMPLATE_VERSION, ReportDatasetDef, ReportTemplate, assertCompatibleTemplateVersion, createReportTemplate, fetchTemplateRecords, getBoundDatasetIds, getTemplateDatasets, resolveParamDefaults, resolveTemplateParams } from "./report/template.js";
|
|
16
16
|
import { parseDateRangeValue, patchParamValues, resolveNumberParamValue } from "./report/filter-bar.js";
|
|
17
|
+
import { DrillHit, DrillStack, DrillStackLayer, ResolveReportTemplate, buildDrillHitMap, createDrillStack, currentDrillLayer, popDrillLayer, pushDrillLayer, resolveDrillParams } from "./report/drill.js";
|
|
18
|
+
import { ReportPrintOptions, buildFilledReportPrintHtml } from "./report/print.js";
|
|
17
19
|
import "./report/index.js";
|
|
18
20
|
import { ReportViewerExposed, ReportViewerProps, _ReportViewerExposed } from "./types/report-viewer.js";
|
|
19
21
|
import { ReportDesignerEmits, ReportDesignerExposed, ReportDesignerProps, _ReportDesignerExposed } from "./types/report-designer.js";
|
|
20
22
|
import "./types/index.js";
|
|
21
|
-
export { type ConditionalEvalContext, ConditionalOperator, ConditionalRule, ConnectionType, ConnectorError, CreateHttpConnectorOptions, DEFAULT_CONNECTION_PORTS, DataConnection, DataConnector, DatasetCatalogItem, DatasetField, DatasetRecords, IncompatibleTemplateVersionError, InferParentOptions, ListParentCandidateOptions, ParamValues, QueryParamDef, QueryParamOption, QueryParamType, QueryResult, REPORT_META_NAMESPACE, REPORT_TEMPLATE_VERSION, ReportAggregate, ReportBinding, ReportColWidthEntry, ReportDatasetDef, type ReportDesignerEmits, type ReportDesignerExposed, type ReportDesignerProps, ReportExpand, ReportPreset, ReportSort, ReportTemplate, type ReportViewerExposed, type ReportViewerProps, Result, type SheetContext, type SheetEmits, type SheetExposed, type SheetProps, type SheetTool, type SheetToolGroup, type SheetToolPopupType, _sfc_main as UReportDesigner, _sfc_main$1 as UReportViewer, _sfc_main$2 as USheet, type _ReportDesignerExposed, type _ReportViewerExposed, type _SheetExposed, applyReportPreset, assertCompatibleTemplateVersion, buildParamDefs, createHttpConnector, createReportBinding, createReportTemplate, createSheetContext, defaultToolRegistry, evaluateCondition, evaluateConditionalStyle, exportFilledReportXlsx, extractParamIds, fetchTemplateRecords, formatBindingPlaceholder, formatBindingPlaceholderParts, formatCellAddress, formatParentCandidateLabel, getBoundDatasetIds, getTemplateDatasets, inferColParentCandidate, inferDropPreset, inferParentsForPreset, inferReportPreset, inferRowParentCandidate, isColGroupBinding, isExpansionBandCol, isExpansionBandRow, isHorizontalExpandBinding, isReductionAggregate, isRowGroupBinding, isVerticalExpandBinding, listColParentCandidates, listRowParentCandidates, mapFilledColWidths, parseCellAddress, parseDateRangeValue, patchParamValues, prefersGroupParent, presetBindingPatch, presetStillApplies, registerTool, renderReport, resolveBoundDatasetParams, resolveFilledColWidths, resolveNumberParamValue, resolveParamDefaults, resolvePortOnTypeChange, resolveRuleCompareValue, resolveTemplateParams, setBindingCatalog, toComparableNumber, unregisterTool };
|
|
23
|
+
export { type ConditionalEvalContext, ConditionalOperator, ConditionalRule, ConnectionType, ConnectorError, CreateHttpConnectorOptions, DEFAULT_CONNECTION_PORTS, DataConnection, DataConnector, DatasetCatalogItem, DatasetField, DatasetRecords, DrillHit, DrillStack, DrillStackLayer, IncompatibleTemplateVersionError, InferParentOptions, ListParentCandidateOptions, ParamValues, QueryParamDef, QueryParamOption, QueryParamType, QueryResult, REPORT_META_NAMESPACE, REPORT_TEMPLATE_VERSION, ReportAggregate, ReportBinding, ReportColWidthEntry, ReportDatasetDef, type ReportDesignerEmits, type ReportDesignerExposed, type ReportDesignerProps, ReportDrillConfig, ReportExpand, ReportPreset, ReportPrintOptions, ReportSort, ReportTemplate, ReportTemplateListItem, type ReportViewerExposed, type ReportViewerProps, ResolveReportTemplate, Result, type SheetContext, type SheetEmits, type SheetExposed, type SheetProps, type SheetTool, type SheetToolGroup, type SheetToolPopupType, _sfc_main as UReportDesigner, _sfc_main$1 as UReportViewer, _sfc_main$2 as USheet, type _ReportDesignerExposed, type _ReportViewerExposed, type _SheetExposed, applyReportPreset, assertCompatibleTemplateVersion, buildDrillHitMap, buildFilledReportPrintHtml, buildParamDefs, createDrillStack, createHttpConnector, createReportBinding, createReportTemplate, createSheetContext, currentDrillLayer, defaultToolRegistry, evaluateCondition, evaluateConditionalStyle, exportFilledReportXlsx, extractParamIds, fetchTemplateRecords, formatBindingPlaceholder, formatBindingPlaceholderParts, formatCellAddress, formatParentCandidateLabel, getBoundDatasetIds, getTemplateDatasets, inferColParentCandidate, inferDropPreset, inferParentsForPreset, inferReportPreset, inferRowParentCandidate, isColGroupBinding, isExpansionBandCol, isExpansionBandRow, isHorizontalExpandBinding, isReductionAggregate, isRowGroupBinding, isVerticalExpandBinding, listColParentCandidates, listRowParentCandidates, mapFilledColWidths, parseCellAddress, parseDateRangeValue, patchParamValues, popDrillLayer, prefersGroupParent, presetBindingPatch, presetStillApplies, pushDrillLayer, registerTool, renderReport, resolveBoundDatasetParams, resolveDrillParams, resolveFilledColWidths, resolveNumberParamValue, resolveParamDefaults, resolvePortOnTypeChange, resolveRuleCompareValue, resolveTemplateParams, setBindingCatalog, toComparableNumber, unregisterTool };
|
package/dist/index.js
CHANGED
|
@@ -3,8 +3,10 @@ import "./tools/builtin.js";
|
|
|
3
3
|
import { createSheetContext } from "./tools/context.js";
|
|
4
4
|
import _sfc_main$2 from "./components/sheet/sheet.js";
|
|
5
5
|
import { exportFilledReportXlsx } from "./report/export-xlsx.js";
|
|
6
|
+
import { buildFilledReportPrintHtml } from "./report/print.js";
|
|
6
7
|
import { parseDateRangeValue, patchParamValues, resolveNumberParamValue } from "./report/filter-bar.js";
|
|
7
8
|
import { REPORT_META_NAMESPACE, applyReportPreset, createReportBinding, formatBindingPlaceholder, formatBindingPlaceholderParts, formatCellAddress, formatParentCandidateLabel, inferColParentCandidate, inferDropPreset, inferParentsForPreset, inferReportPreset, inferRowParentCandidate, isColGroupBinding, isExpansionBandCol, isExpansionBandRow, isHorizontalExpandBinding, isReductionAggregate, isRowGroupBinding, isVerticalExpandBinding, listColParentCandidates, listRowParentCandidates, parseCellAddress, prefersGroupParent, presetBindingPatch, presetStillApplies, setBindingCatalog } from "./report/binding.js";
|
|
9
|
+
import { buildDrillHitMap, createDrillStack, currentDrillLayer, popDrillLayer, pushDrillLayer, resolveDrillParams } from "./report/drill.js";
|
|
8
10
|
import { evaluateCondition, evaluateConditionalStyle, resolveRuleCompareValue, toComparableNumber } from "./report/rules/evaluate.js";
|
|
9
11
|
import { mapFilledColWidths } from "./report/render/builder.js";
|
|
10
12
|
import { renderReport, resolveFilledColWidths } from "./report/render/index.js";
|
|
@@ -13,4 +15,4 @@ import { IncompatibleTemplateVersionError, REPORT_TEMPLATE_VERSION, assertCompat
|
|
|
13
15
|
import _sfc_main$1 from "./components/report/report-viewer.js";
|
|
14
16
|
import { DEFAULT_CONNECTION_PORTS, createHttpConnector, resolvePortOnTypeChange } from "./report/connector.js";
|
|
15
17
|
import _sfc_main from "./components/report/report-designer.js";
|
|
16
|
-
export { DEFAULT_CONNECTION_PORTS, IncompatibleTemplateVersionError, REPORT_META_NAMESPACE, REPORT_TEMPLATE_VERSION, _sfc_main as UReportDesigner, _sfc_main$1 as UReportViewer, _sfc_main$2 as USheet, applyReportPreset, assertCompatibleTemplateVersion, buildParamDefs, createHttpConnector, createReportBinding, createReportTemplate, createSheetContext, defaultToolRegistry, evaluateCondition, evaluateConditionalStyle, exportFilledReportXlsx, extractParamIds, fetchTemplateRecords, formatBindingPlaceholder, formatBindingPlaceholderParts, formatCellAddress, formatParentCandidateLabel, getBoundDatasetIds, getTemplateDatasets, inferColParentCandidate, inferDropPreset, inferParentsForPreset, inferReportPreset, inferRowParentCandidate, isColGroupBinding, isExpansionBandCol, isExpansionBandRow, isHorizontalExpandBinding, isReductionAggregate, isRowGroupBinding, isVerticalExpandBinding, listColParentCandidates, listRowParentCandidates, mapFilledColWidths, parseCellAddress, parseDateRangeValue, patchParamValues, prefersGroupParent, presetBindingPatch, presetStillApplies, registerTool, renderReport, resolveBoundDatasetParams, resolveFilledColWidths, resolveNumberParamValue, resolveParamDefaults, resolvePortOnTypeChange, resolveRuleCompareValue, resolveTemplateParams, setBindingCatalog, toComparableNumber, unregisterTool };
|
|
18
|
+
export { DEFAULT_CONNECTION_PORTS, IncompatibleTemplateVersionError, REPORT_META_NAMESPACE, REPORT_TEMPLATE_VERSION, _sfc_main as UReportDesigner, _sfc_main$1 as UReportViewer, _sfc_main$2 as USheet, applyReportPreset, assertCompatibleTemplateVersion, buildDrillHitMap, buildFilledReportPrintHtml, buildParamDefs, createDrillStack, createHttpConnector, createReportBinding, createReportTemplate, createSheetContext, currentDrillLayer, defaultToolRegistry, evaluateCondition, evaluateConditionalStyle, exportFilledReportXlsx, extractParamIds, fetchTemplateRecords, formatBindingPlaceholder, formatBindingPlaceholderParts, formatCellAddress, formatParentCandidateLabel, getBoundDatasetIds, getTemplateDatasets, inferColParentCandidate, inferDropPreset, inferParentsForPreset, inferReportPreset, inferRowParentCandidate, isColGroupBinding, isExpansionBandCol, isExpansionBandRow, isHorizontalExpandBinding, isReductionAggregate, isRowGroupBinding, isVerticalExpandBinding, listColParentCandidates, listRowParentCandidates, mapFilledColWidths, parseCellAddress, parseDateRangeValue, patchParamValues, popDrillLayer, prefersGroupParent, presetBindingPatch, presetStillApplies, pushDrillLayer, registerTool, renderReport, resolveBoundDatasetParams, resolveDrillParams, resolveFilledColWidths, resolveNumberParamValue, resolveParamDefaults, resolvePortOnTypeChange, resolveRuleCompareValue, resolveTemplateParams, setBindingCatalog, toComparableNumber, unregisterTool };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { DatasetRecords, ParamValues, ReportDrillConfig } from "./types.js";
|
|
2
|
+
import { ReportTemplate } from "./template.js";
|
|
3
|
+
import { SheetSnapshot } from "@veltra/sheet-core";
|
|
4
|
+
//#region src/report/drill.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* 宿主模板解析契约:按下钻 target 引用取回目标模板(允许同步/异步)。
|
|
7
|
+
* 失败抛错——查看器提示可读错误并停留当前报;设计器配置对话框据此解析目标模板查询参数。
|
|
8
|
+
*/
|
|
9
|
+
type ResolveReportTemplate = (ref: string) => ReportTemplate | Promise<ReportTemplate>;
|
|
10
|
+
/**
|
|
11
|
+
* 按下钻映射从该格对应记录取值,生成详情报 Filter Bar 参数值。
|
|
12
|
+
* 记录缺字段(值为 `undefined`)时跳过对应参数,由详情报回退默认值;空映射返回空参数。
|
|
13
|
+
*/
|
|
14
|
+
declare function resolveDrillParams(config: ReportDrillConfig, record: Record<string, unknown>): ParamValues;
|
|
15
|
+
/** 下钻栈层:一张报表模板 + 当时 Filter Bar 参数值(回退时据此恢复并重新取数) */
|
|
16
|
+
interface DrillStackLayer {
|
|
17
|
+
template: ReportTemplate;
|
|
18
|
+
params: ParamValues;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 下钻栈:自根(初始报表)到顶的层序列,至少一层。
|
|
22
|
+
* 只经下方纯函数做不可变更新(返回新栈),便于组件层直接挂响应式。
|
|
23
|
+
*/
|
|
24
|
+
type DrillStack = DrillStackLayer[];
|
|
25
|
+
/** 以初始报表为根层创建下钻栈 */
|
|
26
|
+
declare function createDrillStack(root: DrillStackLayer): DrillStack;
|
|
27
|
+
/**
|
|
28
|
+
* 压入详情报新层并使其成为当前层;`currentParams` 把当前层参数定格为离开时的值
|
|
29
|
+
* (缺省保留原值)。指向自身或成环不做检测,照常压栈,靠 pop 逐级退出。
|
|
30
|
+
*/
|
|
31
|
+
declare function pushDrillLayer(stack: DrillStack, next: DrillStackLayer, currentParams?: ParamValues): DrillStack;
|
|
32
|
+
/** 弹出当前层返回上一层;仅剩根层时原样返回(查看器始终保留一张报表) */
|
|
33
|
+
declare function popDrillLayer(stack: DrillStack): DrillStack;
|
|
34
|
+
/** 当前层(栈顶) */
|
|
35
|
+
declare function currentDrillLayer(stack: DrillStack): DrillStackLayer;
|
|
36
|
+
/** 下钻命中:物理格对应的下钻配置与该格记录 */
|
|
37
|
+
interface DrillHit {
|
|
38
|
+
config: ReportDrillConfig;
|
|
39
|
+
record: Record<string, unknown>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 构建填充报表的物理格 → 下钻命中索引(每次成功取数后重建)。
|
|
43
|
+
* 仅含配了下钻的绑定格落点(含分组/汇总格与展开后的实例格,合并跨度内每格都命中);
|
|
44
|
+
* 记录由 `resolvePlacementContext` 解析:list 明细取源数据行,分组/汇总取分组上下文。
|
|
45
|
+
*/
|
|
46
|
+
declare function buildDrillHitMap(template: SheetSnapshot, data: DatasetRecords): Map<number, DrillHit>;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { DrillHit, DrillStack, DrillStackLayer, ResolveReportTemplate, buildDrillHitMap, createDrillStack, currentDrillLayer, popDrillLayer, pushDrillLayer, resolveDrillParams };
|