zmdms-webui 2.3.3 → 2.3.5
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/es/canvastable/canvasTable.js +30 -25
- package/dist/es/canvastable/components/ColumnDynamic.js +3 -1
- package/dist/es/canvastable/hooks/useAutoHeight.js +67 -0
- package/dist/es/canvastable/hooks/useHeaderHeight.js +2 -2
- package/dist/es/canvastable/hooks/useOverlays.js +7 -7
- package/dist/es/canvastable/hooks/usePopovers.js +10 -2
- package/dist/es/canvastable/hooks/useProcessedColumns.js +7 -5
- package/dist/es/canvastable/hooks/useScroll.js +1 -0
- package/dist/es/canvastable/hooks/useSummaryRow.js +26 -13
- package/dist/es/canvastable/hooks/useTableInteraction.js +3 -2
- package/dist/es/canvastable/hooks/useTableRender.js +133 -42
- package/dist/es/canvastable/hooks/useTableState.js +1 -0
- package/dist/es/canvastable/interface.d.ts +26 -2
- package/dist/es/canvastable/utils/cellHelpers.js +5 -5
- package/dist/es/canvastable/utils/columnHelpers.js +6 -2
- package/dist/es/canvastable/utils/constants.js +3 -3
- package/dist/es/canvastable/utils/formatHelpers.js +4 -25
- package/dist/index.build.d.ts +1 -1
- package/package.json +1 -1
|
@@ -26,8 +26,10 @@ import { useMergeCells } from './hooks/useMergeCells.js';
|
|
|
26
26
|
import { useContainerSize } from './hooks/useContainerSize.js';
|
|
27
27
|
import { useProcessedColumns } from './hooks/useProcessedColumns.js';
|
|
28
28
|
import { useSummaryRow } from './hooks/useSummaryRow.js';
|
|
29
|
+
import { useCanvasTableAutoHeight } from './hooks/useAutoHeight.js';
|
|
29
30
|
import { SCROLLBAR_SIZE } from './utils/constants.js';
|
|
30
31
|
import { calculateColumnRenderInfos, calculateTotalWidth, calculateTotalHeight } from './utils/tableCalculations.js';
|
|
32
|
+
import 'zmdms-utils';
|
|
31
33
|
import 'dayjs';
|
|
32
34
|
import { TABLE_DYNAMIC_KEY } from '../table/constant.js';
|
|
33
35
|
import { useDynamicListByColumns } from '../table/useDynamicListByColumns.js';
|
|
@@ -37,7 +39,7 @@ import { getTableColumns } from '../table/utils.js';
|
|
|
37
39
|
import DynamicSetting from '../dynamicsetting/dynamicSetting.js';
|
|
38
40
|
|
|
39
41
|
function CanvasTable(props) {
|
|
40
|
-
var _a = props.dataSource, dataSource = _a === void 0 ? [] : _a, _b = props.columns, columns = _b === void 0 ? [] : _b, _c = props.rowKey, rowKey = _c === void 0 ? "id" : _c, _d = props.height, height = _d === void 0 ? 600 : _d, width = props.width, _e = props.rowHeight, rowHeight = _e === void 0 ? 36 : _e, _f = props.headerHeight, headerHeight = _f === void 0 ? 36 : _f, rowSelection = props.rowSelection, onSortChange = props.onSortChange, onFilterChange = props.onFilterChange, onScroll = props.onScroll, onRowClick = props.onRowClick, onColumnResize = props.onColumnResize, _g = props.bordered, bordered = _g === void 0 ? true : _g, _h = props.striped, striped = _h === void 0 ? false : _h, _j = props.emptyText, emptyText = _j === void 0 ? "暂无数据" : _j, style = props.style, className = props.className, _k = props.loading, loading = _k === void 0 ? false : _k, _l = props.isContextMenu, isContextMenu = _l === void 0 ? true : _l, isFullscreenHandle = props.isFullscreenHandle,
|
|
42
|
+
var _a = props.dataSource, dataSource = _a === void 0 ? [] : _a, _b = props.columns, columns = _b === void 0 ? [] : _b, _c = props.rowKey, rowKey = _c === void 0 ? "id" : _c, _d = props.height, height = _d === void 0 ? 600 : _d, width = props.width, _e = props.rowHeight, rowHeight = _e === void 0 ? 36 : _e, _f = props.headerHeight, headerHeight = _f === void 0 ? 36 : _f, rowSelection = props.rowSelection, onSortChange = props.onSortChange, onFilterChange = props.onFilterChange, onScroll = props.onScroll, onRowClick = props.onRowClick, onColumnResize = props.onColumnResize, _g = props.bordered, bordered = _g === void 0 ? true : _g, _h = props.striped, striped = _h === void 0 ? false : _h, _j = props.emptyText, emptyText = _j === void 0 ? "暂无数据" : _j, style = props.style, className = props.className, _k = props.loading, loading = _k === void 0 ? false : _k, _l = props.isContextMenu, isContextMenu = _l === void 0 ? true : _l, isFullscreenHandle = props.isFullscreenHandle, _m = props.mode, mode = _m === void 0 ? "index" : _m, dynamicKey = props.dynamicKey, dynamicVersion = props.dynamicVersion, customDynamicListHandle = props.customDynamicListHandle, isDimensionDynamic = props.isDimensionDynamic, dimensionCustomSumKeys = props.dimensionCustomSumKeys, isAutoMerge = props.isAutoMerge, _o = props.isIndexMerge, isIndexMerge = _o === void 0 ? true : _o, _p = props.isSelectionMerge, isSelectionMerge = _p === void 0 ? false : _p, _q = props.renderMode, renderMode = _q === void 0 ? "object" : _q, fixedRowsCount = props.fixedRowsCount, fixedRowsConfig = props.fixedRowsConfig, _r = props.summaryFixed, summaryFixed = _r === void 0 ? false : _r, _s = props.isAutoScrollY, isAutoScrollY = _s === void 0 ? false : _s, _t = props.autoScrollYMarginBottom, autoScrollYMarginBottom = _t === void 0 ? 65 : _t, canvasTableId = props.canvasTableId, headerWrap = props.headerWrap;
|
|
41
43
|
var canvasRef = useRef(null);
|
|
42
44
|
var containerRef = useRef(null);
|
|
43
45
|
var filterPopoverRef = useRef(null);
|
|
@@ -59,11 +61,11 @@ function CanvasTable(props) {
|
|
|
59
61
|
return String((_a = record[rowKey]) !== null && _a !== void 0 ? _a : index);
|
|
60
62
|
}, [rowKey]);
|
|
61
63
|
// 动态列配置
|
|
62
|
-
var
|
|
64
|
+
var _u = useDynamicListByColumns(columns, {
|
|
63
65
|
dynamicKey: dynamicKey,
|
|
64
66
|
dynamicVersion: dynamicVersion,
|
|
65
67
|
customDynamicListHandle: customDynamicListHandle,
|
|
66
|
-
}), defaultDynamicList =
|
|
68
|
+
}), defaultDynamicList = _u.defaultDynamicList, currentDynamicList = _u.currentDynamicList, onCurrentListChange = _u.onCurrentListChange, dynamicSettingRef = _u.dynamicSettingRef;
|
|
67
69
|
// 根据动态列配置处理columns
|
|
68
70
|
var dynamicColumns = useMemo(function () { return getTableColumns(columns, currentDynamicList); }, [columns, currentDynamicList]).columns;
|
|
69
71
|
// 计算表头动态高度(支持wrap换行)
|
|
@@ -72,7 +74,7 @@ function CanvasTable(props) {
|
|
|
72
74
|
headerHeight: headerHeight,
|
|
73
75
|
});
|
|
74
76
|
// 内部列宽状态(未开启动态配置时使用)
|
|
75
|
-
var
|
|
77
|
+
var _v = useState({}), internalColumnWidths = _v[0], setInternalColumnWidths = _v[1];
|
|
76
78
|
// 处理选中框列、序号列等
|
|
77
79
|
var processedColumnsOld = useProcessedColumns({
|
|
78
80
|
columns: columns,
|
|
@@ -83,30 +85,31 @@ function CanvasTable(props) {
|
|
|
83
85
|
dynamicKey: dynamicKey,
|
|
84
86
|
renderMode: renderMode,
|
|
85
87
|
dynamicSettingRef: dynamicSettingRef,
|
|
88
|
+
headerWrap: headerWrap,
|
|
86
89
|
});
|
|
87
90
|
// 表格状态管理
|
|
88
|
-
var
|
|
91
|
+
var _w = useTableState({
|
|
89
92
|
dataSource: dataSource,
|
|
90
93
|
columns: processedColumnsOld,
|
|
91
94
|
rowSelection: rowSelection,
|
|
92
95
|
onFilterChange: onFilterChange,
|
|
93
|
-
}), state =
|
|
96
|
+
}), state = _w.state, setState = _w.setState, processedDataSource = _w.processedDataSource, handleFilterChange = _w.handleFilterChange, closeFilterPopover = _w.closeFilterPopover, autoGeneratedFilters = _w.autoGeneratedFilters;
|
|
94
97
|
var order = useMemo(function () {
|
|
95
98
|
return state.sortOrder && state.sortField
|
|
96
99
|
? { field: state.sortField, order: state.sortOrder }
|
|
97
100
|
: undefined;
|
|
98
101
|
}, [state.sortOrder, state.sortField]);
|
|
99
|
-
var
|
|
102
|
+
var _x = useAutoMerge(processedDataSource, processedColumnsOld, {
|
|
100
103
|
isAutoMerge: isAutoMerge,
|
|
101
104
|
isDimensionDynamic: isDimensionDynamic,
|
|
102
105
|
order: order,
|
|
103
106
|
dimensionCustomSumKeys: dimensionCustomSumKeys,
|
|
104
|
-
}), newDataSource =
|
|
107
|
+
}), newDataSource = _x[0], processedColumns = _x[1];
|
|
105
108
|
// 生成合计行和最终数据源
|
|
106
|
-
var
|
|
109
|
+
var _y = useSummaryRow({
|
|
107
110
|
columns: processedColumns,
|
|
108
111
|
dataSource: newDataSource,
|
|
109
|
-
}), finalDataSource =
|
|
112
|
+
}), finalDataSource = _y.finalDataSource, hasSummaryRow = _y.hasSummaryRow;
|
|
110
113
|
// 计算列的渲染信息
|
|
111
114
|
var columnRenderInfos = useMemo(function () { return calculateColumnRenderInfos(processedColumns); }, [processedColumns]);
|
|
112
115
|
// 计算合并单元格信息
|
|
@@ -121,16 +124,18 @@ function CanvasTable(props) {
|
|
|
121
124
|
var totalHeight = useMemo(function () {
|
|
122
125
|
return calculateTotalHeight(calculatedHeaderHeight, finalDataSource.length, rowHeight);
|
|
123
126
|
}, [calculatedHeaderHeight, finalDataSource.length, rowHeight]);
|
|
127
|
+
// 自动高度计算
|
|
128
|
+
var autoHeight = useCanvasTableAutoHeight(isAutoScrollY, autoScrollYMarginBottom, canvasTableId);
|
|
124
129
|
// 监听容器尺寸变化
|
|
125
130
|
var containerSize = useContainerSize({
|
|
126
131
|
containerRef: containerRef,
|
|
127
132
|
width: width,
|
|
128
|
-
height: height,
|
|
133
|
+
height: isAutoScrollY ? autoHeight || height : height,
|
|
129
134
|
});
|
|
130
135
|
var containerWidth = containerSize.width;
|
|
131
136
|
var containerHeight = containerSize.height;
|
|
132
137
|
// 计算滚动条指标
|
|
133
|
-
var
|
|
138
|
+
var _z = useScrollbarMetrics({
|
|
134
139
|
containerWidth: containerWidth,
|
|
135
140
|
containerHeight: containerHeight,
|
|
136
141
|
totalWidth: totalWidth,
|
|
@@ -138,15 +143,15 @@ function CanvasTable(props) {
|
|
|
138
143
|
headerHeight: calculatedHeaderHeight,
|
|
139
144
|
scrollTop: 0,
|
|
140
145
|
scrollLeft: 0,
|
|
141
|
-
}), maxScrollTop =
|
|
146
|
+
}), maxScrollTop = _z.maxScrollTop, maxScrollLeft = _z.maxScrollLeft;
|
|
142
147
|
// 滚动管理(使用预先计算的maxScrollTop和maxScrollLeft)
|
|
143
|
-
var
|
|
148
|
+
var _0 = useTableScroll({
|
|
144
149
|
canvasRef: canvasRef,
|
|
145
150
|
containerRef: containerRef,
|
|
146
151
|
maxScrollTop: maxScrollTop,
|
|
147
152
|
maxScrollLeft: maxScrollLeft,
|
|
148
153
|
onScroll: onScroll,
|
|
149
|
-
}), scrollState =
|
|
154
|
+
}), scrollState = _0.scrollState, setScrollState = _0.setScrollState;
|
|
150
155
|
// 数据变化时重置滚动位置(筛选、排序、数据源更新等操作后)
|
|
151
156
|
useScrollReset({
|
|
152
157
|
dataSourceLength: dataSource.length,
|
|
@@ -167,12 +172,12 @@ function CanvasTable(props) {
|
|
|
167
172
|
scrollLeft: scrollState.scrollLeft,
|
|
168
173
|
}).actualMetrics;
|
|
169
174
|
// 单元格框选
|
|
170
|
-
var
|
|
175
|
+
var _1 = useTableSelection({
|
|
171
176
|
state: state,
|
|
172
177
|
setState: setState,
|
|
173
178
|
}),
|
|
174
179
|
// selectionStartRef,
|
|
175
|
-
startSelection =
|
|
180
|
+
startSelection = _1.startSelection, updateSelection = _1.updateSelection, extendSelection = _1.extendSelection;
|
|
176
181
|
// 处理列宽调整
|
|
177
182
|
var handleColumnResize = useCallback(function (columnKey, newWidth) {
|
|
178
183
|
var _a;
|
|
@@ -221,13 +226,13 @@ function CanvasTable(props) {
|
|
|
221
226
|
onCurrentListChange,
|
|
222
227
|
]);
|
|
223
228
|
// 列宽调整
|
|
224
|
-
var
|
|
229
|
+
var _2 = useColumnResize({
|
|
225
230
|
columnRenderInfos: columnRenderInfos,
|
|
226
231
|
containerWidth: containerWidth,
|
|
227
232
|
headerHeight: calculatedHeaderHeight,
|
|
228
233
|
scrollLeft: scrollState.scrollLeft,
|
|
229
234
|
onColumnResize: handleColumnResize,
|
|
230
|
-
}), resizeState =
|
|
235
|
+
}), resizeState = _2.resizeState, checkResizeHandle = _2.checkResizeHandle, startResize = _2.startResize, updateResize = _2.updateResize, endResize = _2.endResize, setHoverResizeColumn = _2.setHoverResizeColumn, getColumnWidth = _2.getColumnWidth, RESIZE_HANDLE_WIDTH = _2.RESIZE_HANDLE_WIDTH;
|
|
231
236
|
// 复制到剪贴板
|
|
232
237
|
var getSelectedCellsText = useCopyToClipboard({
|
|
233
238
|
cellSelection: state.cellSelection,
|
|
@@ -250,7 +255,7 @@ function CanvasTable(props) {
|
|
|
250
255
|
isAutoMerge: isAutoMerge,
|
|
251
256
|
});
|
|
252
257
|
// 交互事件处理(使用baseScrollbarMetrics的maxScrollTop/maxScrollLeft以保持稳定)
|
|
253
|
-
var
|
|
258
|
+
var _3 = useTableInteraction({
|
|
254
259
|
state: state,
|
|
255
260
|
setState: setState,
|
|
256
261
|
scrollState: scrollState,
|
|
@@ -295,11 +300,11 @@ function CanvasTable(props) {
|
|
|
295
300
|
menuShow: isContextMenu ? menuShow : undefined,
|
|
296
301
|
fixedRowsCount: fixedRowsCount,
|
|
297
302
|
fixedRowsConfig: fixedRowsConfig,
|
|
298
|
-
|
|
299
|
-
}), handleCanvasMouseDown =
|
|
303
|
+
summaryFixed: summaryFixed,
|
|
304
|
+
}), handleCanvasMouseDown = _3.handleCanvasMouseDown, handleCanvasMouseMove = _3.handleCanvasMouseMove, handleCanvasMouseUp = _3.handleCanvasMouseUp, handleCanvasMouseLeave = _3.handleCanvasMouseLeave, handleCanvasContextMenu = _3.handleCanvasContextMenu;
|
|
300
305
|
// 渲染表格
|
|
301
306
|
useTableRender(__assign(__assign({ canvasRef: canvasRef, processedDataSource: finalDataSource, columnRenderInfos: columnRenderInfos, columns: processedColumns, // 传递原始columns用于渲染多级表头
|
|
302
|
-
state: state, scrollState: scrollState, rowSelection: rowSelection, containerWidth: containerWidth, containerHeight: containerHeight, headerHeight: calculatedHeaderHeight, rowHeight: rowHeight, bordered: bordered, striped: striped }, scrollbarMetrics), { getRowKey: getRowKey, resizeState: resizeState, getColumnWidth: getColumnWidth, RESIZE_HANDLE_WIDTH: RESIZE_HANDLE_WIDTH, mergeCellMap: mergeCellMap, hasSummaryRow: hasSummaryRow, fixedRowsCount: fixedRowsCount, fixedRowsConfig: fixedRowsConfig,
|
|
307
|
+
state: state, scrollState: scrollState, rowSelection: rowSelection, containerWidth: containerWidth, containerHeight: containerHeight, headerHeight: calculatedHeaderHeight, rowHeight: rowHeight, bordered: bordered, striped: striped }, scrollbarMetrics), { getRowKey: getRowKey, resizeState: resizeState, getColumnWidth: getColumnWidth, RESIZE_HANDLE_WIDTH: RESIZE_HANDLE_WIDTH, mergeCellMap: mergeCellMap, hasSummaryRow: hasSummaryRow, fixedRowsCount: fixedRowsCount, fixedRowsConfig: fixedRowsConfig, summaryFixed: summaryFixed }));
|
|
303
308
|
// 单元格覆盖层
|
|
304
309
|
var cellOverlays = useTableCellOverlay({
|
|
305
310
|
canvasRef: canvasRef,
|
|
@@ -316,7 +321,7 @@ function CanvasTable(props) {
|
|
|
316
321
|
fixedRowsCount: fixedRowsCount,
|
|
317
322
|
fixedRowsConfig: fixedRowsConfig,
|
|
318
323
|
hasSummaryRow: hasSummaryRow,
|
|
319
|
-
|
|
324
|
+
summaryFixed: summaryFixed,
|
|
320
325
|
}).cellOverlays;
|
|
321
326
|
// 表头覆盖层
|
|
322
327
|
var headerOverlays = useHeaderOverlay({
|
|
@@ -357,7 +362,7 @@ function CanvasTable(props) {
|
|
|
357
362
|
isVisible: state.badgePopover.visible,
|
|
358
363
|
onClose: handleCloseBadgePopover,
|
|
359
364
|
});
|
|
360
|
-
return (jsx(Spin, __assign({ spinning: loading }, { children: jsxs("div", __assign({ ref: containerRef, className: "canvas-table-container ".concat(className || ""), tabIndex: 0, style: __assign(__assign({}, style), { position: "relative", width: width || "100%", height: containerHeight, overflow: "hidden", touchAction: "none", outline: "none" }) }, { children: [jsx("canvas", { ref: canvasRef, onMouseDown: handleCanvasMouseDown, onMouseMove: handleCanvasMouseMove, onMouseUp: handleCanvasMouseUp, onMouseLeave: handleCanvasMouseLeave, onContextMenu: handleCanvasContextMenu, style: {
|
|
365
|
+
return (jsx(Spin, __assign({ spinning: loading }, { children: jsxs("div", __assign({ ref: containerRef, id: canvasTableId, className: "canvas-table-container ".concat(className || ""), tabIndex: 0, style: __assign(__assign({}, style), { position: "relative", width: width || "100%", height: containerHeight, overflow: "hidden", touchAction: "none", outline: "none" }) }, { children: [jsx("canvas", { ref: canvasRef, onMouseDown: handleCanvasMouseDown, onMouseMove: handleCanvasMouseMove, onMouseUp: handleCanvasMouseUp, onMouseLeave: handleCanvasMouseLeave, onContextMenu: handleCanvasContextMenu, style: {
|
|
361
366
|
display: "block",
|
|
362
367
|
// cursor 由 useTableInteraction 动态管理
|
|
363
368
|
touchAction: "none",
|
|
@@ -9,4 +9,6 @@ var ColumnDynamic = function (_a) {
|
|
|
9
9
|
(_a = dynamicSettingRef === null || dynamicSettingRef === void 0 ? void 0 : dynamicSettingRef.current) === null || _a === void 0 ? void 0 : _a.setVisible(true);
|
|
10
10
|
} }));
|
|
11
11
|
};
|
|
12
|
-
memo(ColumnDynamic);
|
|
12
|
+
var ColumnDynamic$1 = memo(ColumnDynamic);
|
|
13
|
+
|
|
14
|
+
export { ColumnDynamic$1 as default };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CanvasTable 自动高度计算 Hook
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* 计算CanvasTable高度
|
|
8
|
+
* @param isAutoScrollY 是否自动计算高度
|
|
9
|
+
* @param marginBottom canvas table下面留出的距离
|
|
10
|
+
* @param canvasTableId 表格id
|
|
11
|
+
* @returns 计算出的表格高度
|
|
12
|
+
*/
|
|
13
|
+
function useCanvasTableAutoHeight(isAutoScrollY, marginBottom, canvasTableId) {
|
|
14
|
+
if (marginBottom === void 0) { marginBottom = 65; }
|
|
15
|
+
var _a = useState(undefined), tableHeight = _a[0], setTableHeight = _a[1];
|
|
16
|
+
useEffect(function () {
|
|
17
|
+
if (!isAutoScrollY)
|
|
18
|
+
return;
|
|
19
|
+
var calculateHeight = function () {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
// 查找容器元素
|
|
22
|
+
var containerRect = (_a = document
|
|
23
|
+
.querySelector(".ztxk-container")) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
|
24
|
+
// 查找CanvasTable元素
|
|
25
|
+
var tableSelector = canvasTableId
|
|
26
|
+
? "#".concat(CSS.escape(canvasTableId), " .canvas-table-container")
|
|
27
|
+
: ".canvas-table-container";
|
|
28
|
+
var tableRect = (_b = document
|
|
29
|
+
.querySelector(tableSelector)) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect();
|
|
30
|
+
if (containerRect && tableRect) {
|
|
31
|
+
var calculatedHeight = containerRect.height +
|
|
32
|
+
containerRect.top -
|
|
33
|
+
tableRect.top -
|
|
34
|
+
marginBottom;
|
|
35
|
+
// 确保高度不小于最小值
|
|
36
|
+
var minHeight = 200;
|
|
37
|
+
setTableHeight(Math.max(calculatedHeight, minHeight));
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
// 初始计算
|
|
41
|
+
calculateHeight();
|
|
42
|
+
// 监听窗口大小变化
|
|
43
|
+
var handleResize = function () {
|
|
44
|
+
calculateHeight();
|
|
45
|
+
};
|
|
46
|
+
window.addEventListener("resize", handleResize);
|
|
47
|
+
// 使用 MutationObserver 监听DOM变化
|
|
48
|
+
var observer = new MutationObserver(function () {
|
|
49
|
+
calculateHeight();
|
|
50
|
+
});
|
|
51
|
+
var container = document.querySelector(".ztxk-container");
|
|
52
|
+
if (container) {
|
|
53
|
+
observer.observe(container, {
|
|
54
|
+
childList: true,
|
|
55
|
+
subtree: true,
|
|
56
|
+
attributes: true,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return function () {
|
|
60
|
+
window.removeEventListener("resize", handleResize);
|
|
61
|
+
observer.disconnect();
|
|
62
|
+
};
|
|
63
|
+
}, [isAutoScrollY, marginBottom, canvasTableId]);
|
|
64
|
+
return tableHeight;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export { useCanvasTableAutoHeight };
|
|
@@ -2,8 +2,8 @@ import { __spreadArray } from '../../_virtual/_tslib.js';
|
|
|
2
2
|
import { useState, useEffect } from 'react';
|
|
3
3
|
import { getMaxDepth } from '../utils/multiHeaderHelpers.js';
|
|
4
4
|
|
|
5
|
-
var FONT_SIZE =
|
|
6
|
-
var FONT_FAMILY = "
|
|
5
|
+
var FONT_SIZE = 13;
|
|
6
|
+
var FONT_FAMILY = '"Microsoft YaHei", 微软雅黑, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
7
7
|
var LINE_HEIGHT = 20;
|
|
8
8
|
var FILTER_ICON_WIDTH = 15;
|
|
9
9
|
var SORT_ICON_WIDTH = 15;
|
|
@@ -29,7 +29,7 @@ import 'dayjs';
|
|
|
29
29
|
* - 只渲染React元素类型的内容(字符串和数字在Canvas中直接绘制)
|
|
30
30
|
*/
|
|
31
31
|
var useTableCellOverlay = function (params) {
|
|
32
|
-
var processedDataSource = params.processedDataSource, columnRenderInfos = params.columnRenderInfos, scrollState = params.scrollState, containerWidth = params.containerWidth, containerHeight = params.containerHeight, headerHeight = params.headerHeight, rowHeight = params.rowHeight, needHorizontalScrollbar = params.needHorizontalScrollbar, needVerticalScrollbar = params.needVerticalScrollbar, scrollbarSize = params.scrollbarSize, fixedRowsCount = params.fixedRowsCount, fixedRowsConfig = params.fixedRowsConfig, _a = params.hasSummaryRow, hasSummaryRow = _a === void 0 ? false : _a, _b = params.
|
|
32
|
+
var processedDataSource = params.processedDataSource, columnRenderInfos = params.columnRenderInfos, scrollState = params.scrollState, containerWidth = params.containerWidth, containerHeight = params.containerHeight, headerHeight = params.headerHeight, rowHeight = params.rowHeight, needHorizontalScrollbar = params.needHorizontalScrollbar, needVerticalScrollbar = params.needVerticalScrollbar, scrollbarSize = params.scrollbarSize, fixedRowsCount = params.fixedRowsCount, fixedRowsConfig = params.fixedRowsConfig, _a = params.hasSummaryRow, hasSummaryRow = _a === void 0 ? false : _a, _b = params.summaryFixed, summaryFixed = _b === void 0 ? false : _b;
|
|
33
33
|
// 计算可见的单元格覆盖层信息
|
|
34
34
|
var cellOverlays = useMemo(function () {
|
|
35
35
|
var overlays = [];
|
|
@@ -49,7 +49,7 @@ var useTableCellOverlay = function (params) {
|
|
|
49
49
|
? containerWidth - scrollbarSize
|
|
50
50
|
: containerWidth;
|
|
51
51
|
// 计算可用高度,需要为固定合计行预留空间
|
|
52
|
-
var fixedSummaryHeight =
|
|
52
|
+
var fixedSummaryHeight = summaryFixed && hasSummaryRow ? rowHeight : 0;
|
|
53
53
|
var effectiveHeight = (needHorizontalScrollbar
|
|
54
54
|
? containerHeight - scrollbarSize
|
|
55
55
|
: containerHeight) - fixedSummaryHeight;
|
|
@@ -158,7 +158,7 @@ var useTableCellOverlay = function (params) {
|
|
|
158
158
|
else {
|
|
159
159
|
// 非固定行需要严格避开所有固定行区域
|
|
160
160
|
var currentFixedBottomHeight = fixedBottomRowsCount * rowHeight;
|
|
161
|
-
var currentFixedSummaryHeight =
|
|
161
|
+
var currentFixedSummaryHeight = summaryFixed && hasSummaryRow ? rowHeight : 0;
|
|
162
162
|
// 计算可滚动区域的严格边界
|
|
163
163
|
var scrollableAreaBottom = containerHeight -
|
|
164
164
|
(needHorizontalScrollbar ? scrollbarSize : 0) -
|
|
@@ -248,7 +248,7 @@ var useTableCellOverlay = function (params) {
|
|
|
248
248
|
if (fixedBottomRowsCount > 0) {
|
|
249
249
|
var bottomRowsStartIndex = processedDataSource.length -
|
|
250
250
|
fixedBottomRowsCount -
|
|
251
|
-
(
|
|
251
|
+
(summaryFixed && hasSummaryRow ? 1 : 0);
|
|
252
252
|
for (var i = 0; i < fixedBottomRowsCount; i++) {
|
|
253
253
|
var rowIndex = bottomRowsStartIndex + i;
|
|
254
254
|
var y = containerHeight -
|
|
@@ -260,7 +260,7 @@ var useTableCellOverlay = function (params) {
|
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
// 4. 处理固定合计行
|
|
263
|
-
if (
|
|
263
|
+
if (summaryFixed && hasSummaryRow) {
|
|
264
264
|
var summaryRowIndex = processedDataSource.length - 1;
|
|
265
265
|
var summaryY = containerHeight -
|
|
266
266
|
(needHorizontalScrollbar ? scrollbarSize : 0) -
|
|
@@ -272,7 +272,7 @@ var useTableCellOverlay = function (params) {
|
|
|
272
272
|
// 计算优先级(数值越大优先级越高)
|
|
273
273
|
var getPriority = function (overlay) {
|
|
274
274
|
// 检查是否是固定合计行(最后一行且固定合计行开启)
|
|
275
|
-
var isSummaryRow =
|
|
275
|
+
var isSummaryRow = summaryFixed &&
|
|
276
276
|
hasSummaryRow &&
|
|
277
277
|
overlay.rowIndex === processedDataSource.length - 1;
|
|
278
278
|
if (isSummaryRow && overlay.isFixed)
|
|
@@ -304,7 +304,7 @@ var useTableCellOverlay = function (params) {
|
|
|
304
304
|
fixedRowsCount,
|
|
305
305
|
fixedRowsConfig,
|
|
306
306
|
hasSummaryRow,
|
|
307
|
-
|
|
307
|
+
summaryFixed,
|
|
308
308
|
]);
|
|
309
309
|
return {
|
|
310
310
|
cellOverlays: cellOverlays,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { __assign } from '../../_virtual/_tslib.js';
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { useCallback, useEffect, useMemo } from 'react';
|
|
3
|
+
import { useRef, useCallback, useEffect, useMemo } from 'react';
|
|
4
|
+
import 'zmdms-utils';
|
|
4
5
|
import 'dayjs';
|
|
5
6
|
import { findColumnByKey } from '../utils/columnHelpers.js';
|
|
6
7
|
import FilterPopover from '../components/FilterPopover.js';
|
|
@@ -19,6 +20,8 @@ import '../components/ColumnDynamic.js';
|
|
|
19
20
|
*/
|
|
20
21
|
var useBadgePopover = function (params) {
|
|
21
22
|
var badgePopover = params.badgePopover, tooltip = params.tooltip, scrollTop = params.scrollTop, scrollLeft = params.scrollLeft, setState = params.setState;
|
|
23
|
+
// 使用 ref 记录上一次的滚动位置
|
|
24
|
+
var prevScrollRef = useRef({ scrollTop: scrollTop, scrollLeft: scrollLeft });
|
|
22
25
|
// 关闭badge弹窗
|
|
23
26
|
var handleCloseBadgePopover = useCallback(function () {
|
|
24
27
|
setState(function (prev) { return (__assign(__assign({}, prev), { badgePopover: {
|
|
@@ -29,7 +32,10 @@ var useBadgePopover = function (params) {
|
|
|
29
32
|
}, [setState]);
|
|
30
33
|
// 滚动时关闭badge弹窗和tooltip
|
|
31
34
|
useEffect(function () {
|
|
32
|
-
|
|
35
|
+
// 只有在滚动位置真正变化时才关闭弹窗
|
|
36
|
+
var scrollChanged = prevScrollRef.current.scrollTop !== scrollTop ||
|
|
37
|
+
prevScrollRef.current.scrollLeft !== scrollLeft;
|
|
38
|
+
if (scrollChanged && (badgePopover.visible || tooltip.visible)) {
|
|
33
39
|
setState(function (prev) { return (__assign(__assign({}, prev), { badgePopover: {
|
|
34
40
|
visible: false,
|
|
35
41
|
content: "",
|
|
@@ -41,6 +47,8 @@ var useBadgePopover = function (params) {
|
|
|
41
47
|
cellInfo: null,
|
|
42
48
|
} })); });
|
|
43
49
|
}
|
|
50
|
+
// 更新上一次的滚动位置
|
|
51
|
+
prevScrollRef.current = { scrollTop: scrollTop, scrollLeft: scrollLeft };
|
|
44
52
|
}, [scrollTop, scrollLeft, setState, badgePopover.visible, tooltip.visible]);
|
|
45
53
|
return {
|
|
46
54
|
handleCloseBadgePopover: handleCloseBadgePopover,
|
|
@@ -2,25 +2,27 @@ import { __spreadArray } from '../../_virtual/_tslib.js';
|
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { useMemo } from 'react';
|
|
4
4
|
import { DEFAULT_SELECTION_COLUMN_WIDTH } from '../utils/constants.js';
|
|
5
|
+
import 'zmdms-utils';
|
|
5
6
|
import 'dayjs';
|
|
6
7
|
import { processColumnRender } from '../utils/columnHelpers.js';
|
|
7
8
|
import { MERGE_INDEX } from '../../table/constant.js';
|
|
8
9
|
import 'lodash/isEqual';
|
|
9
10
|
import 'ahooks';
|
|
10
11
|
import '../../node_modules/immutability-helper/index.js';
|
|
11
|
-
import 'zmdms-utils';
|
|
12
12
|
import '../../node_modules/exceljs/dist/exceljs.min.js';
|
|
13
|
+
import '../components/FilterPopover.js';
|
|
14
|
+
import '../../node_modules/react-contexify/dist/index.js';
|
|
15
|
+
import '../../node_modules/screenfull/index.js';
|
|
16
|
+
import ColumnDynamic from '../components/ColumnDynamic.js';
|
|
13
17
|
|
|
14
18
|
var useProcessedColumns = function (params) {
|
|
15
|
-
var columns = params.columns, dynamicColumns = params.dynamicColumns, mode = params.mode, rowSelection = params.rowSelection, internalColumnWidths = params.internalColumnWidths, dynamicKey = params.dynamicKey, _a = params.renderMode, renderMode = _a === void 0 ? "object" : _a, dynamicSettingRef = params.dynamicSettingRef;
|
|
19
|
+
var columns = params.columns, dynamicColumns = params.dynamicColumns, mode = params.mode, rowSelection = params.rowSelection, internalColumnWidths = params.internalColumnWidths, dynamicKey = params.dynamicKey, _a = params.renderMode, renderMode = _a === void 0 ? "object" : _a, dynamicSettingRef = params.dynamicSettingRef, headerWrap = params.headerWrap;
|
|
16
20
|
return useMemo(function () {
|
|
17
21
|
var cols = __spreadArray([], (dynamicColumns || columns), true);
|
|
18
22
|
// 添加序号列
|
|
19
23
|
if (mode === "index") {
|
|
20
24
|
var title = "序号";
|
|
21
25
|
if (dynamicKey && dynamicSettingRef) {
|
|
22
|
-
// 动态引入ColumnDynamic组件,避免循环依赖
|
|
23
|
-
var ColumnDynamic = require("../components/ColumnDynamic").default;
|
|
24
26
|
title = jsx(ColumnDynamic, { dynamicSettingRef: dynamicSettingRef });
|
|
25
27
|
}
|
|
26
28
|
cols.unshift({
|
|
@@ -77,7 +79,7 @@ var useProcessedColumns = function (params) {
|
|
|
77
79
|
}
|
|
78
80
|
// 处理render函数
|
|
79
81
|
return cols.map(function (col) {
|
|
80
|
-
return processColumnRender(col, renderMode);
|
|
82
|
+
return processColumnRender(col, renderMode, headerWrap);
|
|
81
83
|
});
|
|
82
84
|
}, [
|
|
83
85
|
dynamicColumns,
|
|
@@ -2,6 +2,7 @@ import { __assign } from '../../_virtual/_tslib.js';
|
|
|
2
2
|
import { useMemo, useState, useRef, useEffect } from 'react';
|
|
3
3
|
import { SCROLLBAR_SIZE, MIN_SCROLLBAR_SIZE } from '../utils/constants.js';
|
|
4
4
|
import { calculateScrollbarMetrics } from '../utils/tableCalculations.js';
|
|
5
|
+
import 'zmdms-utils';
|
|
5
6
|
import 'dayjs';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -5,9 +5,10 @@ import 'lodash/isEqual';
|
|
|
5
5
|
import 'ahooks';
|
|
6
6
|
import '../../node_modules/immutability-helper/index.js';
|
|
7
7
|
import 'react/jsx-runtime';
|
|
8
|
-
import { plus } from 'zmdms-utils';
|
|
8
|
+
import { plus, exactRound, addThousedSeparator } from 'zmdms-utils';
|
|
9
9
|
import '../../node_modules/exceljs/dist/exceljs.min.js';
|
|
10
10
|
import 'dayjs';
|
|
11
|
+
import { getAllLeafColumns } from '../utils/columnHelpers.js';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* 合计行计算 Hook
|
|
@@ -15,23 +16,26 @@ import 'dayjs';
|
|
|
15
16
|
var useSummaryRow = function (params) {
|
|
16
17
|
var columns = params.columns, dataSource = params.dataSource;
|
|
17
18
|
var summaryRow = useMemo(function () {
|
|
18
|
-
|
|
19
|
+
// 先扁平化多级表头,获取所有叶子列
|
|
20
|
+
var leafColumns = getAllLeafColumns(columns);
|
|
21
|
+
var hasSummary = leafColumns.some(function (col) { return col.isSummary; });
|
|
19
22
|
if (!hasSummary)
|
|
20
23
|
return null;
|
|
21
24
|
var summaryRecord = {};
|
|
22
25
|
// 找到第一个数据列(非序号列、非选择框列)
|
|
23
26
|
var firstDataColIndex = -1;
|
|
24
|
-
for (var i = 0; i <
|
|
25
|
-
var col =
|
|
27
|
+
for (var i = 0; i < leafColumns.length; i++) {
|
|
28
|
+
var col = leafColumns[i];
|
|
26
29
|
if (col.key !== "__index__" && col.key !== "__selection__") {
|
|
27
30
|
firstDataColIndex = i;
|
|
28
31
|
break;
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
|
-
|
|
34
|
+
leafColumns.forEach(function (column, colIndex) {
|
|
32
35
|
var dataIndex = column.dataIndex || column.key;
|
|
33
36
|
if (column.isSummary) {
|
|
34
|
-
|
|
37
|
+
var calculatedSum = void 0;
|
|
38
|
+
// 默认计算逻辑:数值求和
|
|
35
39
|
var sum_1 = 0;
|
|
36
40
|
dataSource.forEach(function (record) {
|
|
37
41
|
var value = record[dataIndex];
|
|
@@ -43,13 +47,16 @@ var useSummaryRow = function (params) {
|
|
|
43
47
|
sum_1 = plus(sum_1, num);
|
|
44
48
|
}
|
|
45
49
|
});
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
calculatedSum = sum_1;
|
|
51
|
+
// 应用格式化(仅在没有自定义回调或回调返回数值时)
|
|
52
|
+
var formattedSum = calculatedSum;
|
|
53
|
+
if (typeof calculatedSum === "number") {
|
|
54
|
+
if (column.precision !== undefined) {
|
|
55
|
+
formattedSum = exactRound(calculatedSum, column.precision);
|
|
56
|
+
}
|
|
57
|
+
if (column.thousand) {
|
|
58
|
+
formattedSum = addThousedSeparator(formattedSum);
|
|
59
|
+
}
|
|
53
60
|
}
|
|
54
61
|
summaryRecord[dataIndex] = formattedSum;
|
|
55
62
|
}
|
|
@@ -61,6 +68,12 @@ var useSummaryRow = function (params) {
|
|
|
61
68
|
summaryRecord[dataIndex] = "";
|
|
62
69
|
}
|
|
63
70
|
});
|
|
71
|
+
leafColumns.forEach(function (column) {
|
|
72
|
+
if (column.totalCalcCallback) {
|
|
73
|
+
var dataIndex = column.dataIndex || column.key;
|
|
74
|
+
summaryRecord[dataIndex] = column.totalCalcCallback(summaryRecord[dataIndex], summaryRecord);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
64
77
|
summaryRecord[IS_SUMMARY] = true;
|
|
65
78
|
return summaryRecord;
|
|
66
79
|
}, [columns, dataSource]);
|
|
@@ -5,6 +5,7 @@ import { FONT_SIZE, FONT_FAMILY } from '../utils/constants.js';
|
|
|
5
5
|
import { isTextTruncated } from '../utils/canvasDrawHelpers.js';
|
|
6
6
|
import { getMaxDepth, flattenHeaders, getLeafColumns } from '../utils/multiHeaderHelpers.js';
|
|
7
7
|
import { getCellFromMousePosition, extractCellText } from '../utils/cellHelpers.js';
|
|
8
|
+
import 'zmdms-utils';
|
|
8
9
|
import 'dayjs';
|
|
9
10
|
import { calculateSelectionState, toggleSelectAll, handleSortClick, calculateIconArea, isClickInIconArea, calculateScrollPosition, calculatePopoverPosition, isPointInTriangle } from '../utils/interactionHelpers.js';
|
|
10
11
|
|
|
@@ -12,7 +13,7 @@ import { calculateSelectionState, toggleSelectAll, handleSortClick, calculateIco
|
|
|
12
13
|
* 表格交互事件处理 Hook
|
|
13
14
|
*/
|
|
14
15
|
var useTableInteraction = function (params) {
|
|
15
|
-
var state = params.state, setState = params.setState, scrollState = params.scrollState, setScrollState = params.setScrollState, processedDataSource = params.processedDataSource, columnRenderInfos = params.columnRenderInfos, _a = params.columns, columns = _a === void 0 ? [] : _a, rowSelection = params.rowSelection, rowHeight = params.rowHeight, headerHeight = params.headerHeight, containerWidth = params.containerWidth, containerHeight = params.containerHeight, scrollbarSize = params.scrollbarSize, canvasRef = params.canvasRef, needVerticalScrollbar = params.needVerticalScrollbar, needHorizontalScrollbar = params.needHorizontalScrollbar, verticalScrollbarTop = params.verticalScrollbarTop, verticalScrollbarHeight = params.verticalScrollbarHeight, horizontalScrollbarLeft = params.horizontalScrollbarLeft, horizontalScrollbarWidth = params.horizontalScrollbarWidth, maxScrollTop = params.maxScrollTop, maxScrollLeft = params.maxScrollLeft, totalHeight = params.totalHeight, totalWidth = params.totalWidth, dataAreaHeight = params.dataAreaHeight, onSortChange = params.onSortChange, onRowClick = params.onRowClick, getRowKey = params.getRowKey, startSelection = params.startSelection, updateSelection = params.updateSelection, extendSelection = params.extendSelection, checkResizeHandle = params.checkResizeHandle, startResize = params.startResize, updateResize = params.updateResize, endResize = params.endResize, setHoverResizeColumn = params.setHoverResizeColumn, resizeState = params.resizeState, _b = params.hasSummaryRow, hasSummaryRow = _b === void 0 ? false : _b, mergeCellMap = params.mergeCellMap, menuShow = params.menuShow, fixedRowsCount = params.fixedRowsCount, fixedRowsConfig = params.fixedRowsConfig,
|
|
16
|
+
var state = params.state, setState = params.setState, scrollState = params.scrollState, setScrollState = params.setScrollState, processedDataSource = params.processedDataSource, columnRenderInfos = params.columnRenderInfos, _a = params.columns, columns = _a === void 0 ? [] : _a, rowSelection = params.rowSelection, rowHeight = params.rowHeight, headerHeight = params.headerHeight, containerWidth = params.containerWidth, containerHeight = params.containerHeight, scrollbarSize = params.scrollbarSize, canvasRef = params.canvasRef, needVerticalScrollbar = params.needVerticalScrollbar, needHorizontalScrollbar = params.needHorizontalScrollbar, verticalScrollbarTop = params.verticalScrollbarTop, verticalScrollbarHeight = params.verticalScrollbarHeight, horizontalScrollbarLeft = params.horizontalScrollbarLeft, horizontalScrollbarWidth = params.horizontalScrollbarWidth, maxScrollTop = params.maxScrollTop, maxScrollLeft = params.maxScrollLeft, totalHeight = params.totalHeight, totalWidth = params.totalWidth, dataAreaHeight = params.dataAreaHeight, onSortChange = params.onSortChange, onRowClick = params.onRowClick, getRowKey = params.getRowKey, startSelection = params.startSelection, updateSelection = params.updateSelection, extendSelection = params.extendSelection, checkResizeHandle = params.checkResizeHandle, startResize = params.startResize, updateResize = params.updateResize, endResize = params.endResize, setHoverResizeColumn = params.setHoverResizeColumn, resizeState = params.resizeState, _b = params.hasSummaryRow, hasSummaryRow = _b === void 0 ? false : _b, mergeCellMap = params.mergeCellMap, menuShow = params.menuShow, fixedRowsCount = params.fixedRowsCount, fixedRowsConfig = params.fixedRowsConfig, summaryFixed = params.summaryFixed;
|
|
16
17
|
// 获取鼠标位置对应的单元格
|
|
17
18
|
var getCellFromPosition = useMemoizedFn(function (x, y) {
|
|
18
19
|
var fixedTopRowsCount = (fixedRowsConfig === null || fixedRowsConfig === void 0 ? void 0 : fixedRowsConfig.topCount) || fixedRowsCount || 0;
|
|
@@ -29,7 +30,7 @@ var useTableInteraction = function (params) {
|
|
|
29
30
|
fixedTopRowsCount: fixedTopRowsCount,
|
|
30
31
|
fixedBottomRowsCount: fixedBottomRowsCount,
|
|
31
32
|
hasSummaryRow: hasSummaryRow,
|
|
32
|
-
|
|
33
|
+
summaryFixed: summaryFixed,
|
|
33
34
|
displayHeight: containerHeight,
|
|
34
35
|
needHorizontalScrollbar: needHorizontalScrollbar,
|
|
35
36
|
scrollbarSize: scrollbarSize,
|
|
@@ -19,7 +19,7 @@ import { calculateSelectionState, calculateIconArea } from '../utils/interaction
|
|
|
19
19
|
* 表格渲染 Hook
|
|
20
20
|
*/
|
|
21
21
|
var useTableRender = function (params) {
|
|
22
|
-
var canvasRef = params.canvasRef, processedDataSource = params.processedDataSource, columnRenderInfos = params.columnRenderInfos, columns = params.columns, state = params.state, scrollState = params.scrollState, rowSelection = params.rowSelection, containerWidth = params.containerWidth, containerHeight = params.containerHeight, headerHeight = params.headerHeight, rowHeight = params.rowHeight, bordered = params.bordered, striped = params.striped, needVerticalScrollbar = params.needVerticalScrollbar, needHorizontalScrollbar = params.needHorizontalScrollbar, verticalScrollbarTop = params.verticalScrollbarTop, verticalScrollbarHeight = params.verticalScrollbarHeight, horizontalScrollbarLeft = params.horizontalScrollbarLeft, horizontalScrollbarWidth = params.horizontalScrollbarWidth, getRowKey = params.getRowKey, resizeState = params.resizeState, getColumnWidth = params.getColumnWidth, _a = params.RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_WIDTH = _a === void 0 ? 8 : _a, mergeCellMap = params.mergeCellMap, _b = params.hasSummaryRow, hasSummaryRow = _b === void 0 ? false : _b, fixedRowsCount = params.fixedRowsCount, fixedRowsConfig = params.fixedRowsConfig, _c = params.
|
|
22
|
+
var canvasRef = params.canvasRef, processedDataSource = params.processedDataSource, columnRenderInfos = params.columnRenderInfos, columns = params.columns, state = params.state, scrollState = params.scrollState, rowSelection = params.rowSelection, containerWidth = params.containerWidth, containerHeight = params.containerHeight, headerHeight = params.headerHeight, rowHeight = params.rowHeight, bordered = params.bordered, striped = params.striped, needVerticalScrollbar = params.needVerticalScrollbar, needHorizontalScrollbar = params.needHorizontalScrollbar, verticalScrollbarTop = params.verticalScrollbarTop, verticalScrollbarHeight = params.verticalScrollbarHeight, horizontalScrollbarLeft = params.horizontalScrollbarLeft, horizontalScrollbarWidth = params.horizontalScrollbarWidth, getRowKey = params.getRowKey, resizeState = params.resizeState, getColumnWidth = params.getColumnWidth, _a = params.RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_WIDTH = _a === void 0 ? 8 : _a, mergeCellMap = params.mergeCellMap, _b = params.hasSummaryRow, hasSummaryRow = _b === void 0 ? false : _b, fixedRowsCount = params.fixedRowsCount, fixedRowsConfig = params.fixedRowsConfig, _c = params.summaryFixed, summaryFixed = _c === void 0 ? false : _c;
|
|
23
23
|
// 判断是否是多级表头
|
|
24
24
|
var maxDepth = useMemo(function () { return getMaxDepth(columns); }, [columns]);
|
|
25
25
|
var isMultiHeader = maxDepth > 1;
|
|
@@ -281,16 +281,42 @@ var useTableRender = function (params) {
|
|
|
281
281
|
// 如果是最末级且有图标,文本左对齐;否则居中
|
|
282
282
|
if (isLastLevel && iconArea.iconsWidth > 0) {
|
|
283
283
|
ctx.textAlign = "left";
|
|
284
|
-
var
|
|
284
|
+
var textX_1 = drawX + 16;
|
|
285
285
|
var textMaxWidth = width - 16 - iconArea.iconsWidth;
|
|
286
|
-
|
|
287
|
-
|
|
286
|
+
// 根据 wrap 属性处理文本
|
|
287
|
+
if (column.wrap) {
|
|
288
|
+
// 换行显示(支持\n和自动换行)
|
|
289
|
+
var lines = wrapText(ctx, titleText, textMaxWidth);
|
|
290
|
+
var lineHeight_2 = 20;
|
|
291
|
+
var startY_2 = textY - ((lines.length - 1) * lineHeight_2) / 2;
|
|
292
|
+
lines.forEach(function (line, index) {
|
|
293
|
+
var lineY = startY_2 + index * lineHeight_2;
|
|
294
|
+
ctx.fillText(line, textX_1, lineY);
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
var truncated = truncateText(ctx, titleText, textMaxWidth);
|
|
299
|
+
ctx.fillText(truncated, textX_1, textY);
|
|
300
|
+
}
|
|
288
301
|
}
|
|
289
302
|
else {
|
|
290
303
|
ctx.textAlign = "center";
|
|
291
|
-
var
|
|
292
|
-
|
|
293
|
-
|
|
304
|
+
var textX_2 = drawX + width / 2;
|
|
305
|
+
// 根据 wrap 属性处理文本
|
|
306
|
+
if (column.wrap) {
|
|
307
|
+
// 换行显示(支持\n和自动换行)
|
|
308
|
+
var lines = wrapText(ctx, titleText, width - 16);
|
|
309
|
+
var lineHeight_3 = 20;
|
|
310
|
+
var startY_3 = textY - ((lines.length - 1) * lineHeight_3) / 2;
|
|
311
|
+
lines.forEach(function (line, index) {
|
|
312
|
+
var lineY = startY_3 + index * lineHeight_3;
|
|
313
|
+
ctx.fillText(line, textX_2, lineY);
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
var truncated = truncateText(ctx, titleText, width - 16);
|
|
318
|
+
ctx.fillText(truncated, textX_2, textY);
|
|
319
|
+
}
|
|
294
320
|
}
|
|
295
321
|
// 绘制筛选图标(仅在最末级表头显示)
|
|
296
322
|
if (iconArea.hasFilter) {
|
|
@@ -365,13 +391,30 @@ var useTableRender = function (params) {
|
|
|
365
391
|
// 计算实际可用的渲染区域高度(考虑固定底部行和合计行)
|
|
366
392
|
var fixedBottomRowsCount = (fixedRowsConfig === null || fixedRowsConfig === void 0 ? void 0 : fixedRowsConfig.bottomCount) || 0;
|
|
367
393
|
var fixedBottomHeight = fixedBottomRowsCount * rowHeight;
|
|
368
|
-
var fixedSummaryHeight =
|
|
394
|
+
var fixedSummaryHeight = summaryFixed && hasSummaryRow ? rowHeight : 0;
|
|
369
395
|
var effectiveHeight = displayHeight -
|
|
370
396
|
(needHorizontalScrollbar ? SCROLLBAR_SIZE : 0) -
|
|
371
397
|
fixedBottomHeight -
|
|
372
398
|
fixedSummaryHeight;
|
|
373
|
-
//
|
|
374
|
-
|
|
399
|
+
// 提前检查这一行是否有合并单元格,找出最大的rowSpan
|
|
400
|
+
var maxRowSpanInRow = 1;
|
|
401
|
+
if (mergeCellMap) {
|
|
402
|
+
columnRenderInfos.forEach(function (_, colIndex) {
|
|
403
|
+
var mergeCellKey = "".concat(rowIndex, "-").concat(colIndex);
|
|
404
|
+
var mergeInfo = mergeCellMap.get(mergeCellKey);
|
|
405
|
+
// 只考虑主单元格(不是被合并的单元格)
|
|
406
|
+
if (mergeInfo &&
|
|
407
|
+
!mergeInfo.skip &&
|
|
408
|
+
mergeInfo.rowSpan > maxRowSpanInRow) {
|
|
409
|
+
maxRowSpanInRow = mergeInfo.rowSpan;
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
// 计算这一行的实际高度(考虑合并单元格)
|
|
414
|
+
var actualRowHeight = rowHeight * maxRowSpanInRow;
|
|
415
|
+
// 跳过不在可视区域的行
|
|
416
|
+
// 关键:使用合并后的实际高度判断,确保合并单元格的最后一行还在可视区域内时继续渲染
|
|
417
|
+
if (y + actualRowHeight < headerHeight || y >= effectiveHeight) {
|
|
375
418
|
return;
|
|
376
419
|
}
|
|
377
420
|
var recordKey = getRowKey(record, rowIndex);
|
|
@@ -430,7 +473,10 @@ var useTableRender = function (params) {
|
|
|
430
473
|
ctx.beginPath();
|
|
431
474
|
// 裁剪区域:确保不覆盖表头,从 headerHeight 开始
|
|
432
475
|
var clipY = Math.max(y, headerHeight);
|
|
433
|
-
|
|
476
|
+
// 计算单元格实际底部位置,并限制在可视区域内
|
|
477
|
+
var cellBottom = Math.min(y + cellHeight, effectiveHeight);
|
|
478
|
+
// 裁剪高度 = 单元格可见底部 - 裁剪起始位置
|
|
479
|
+
var clipHeight = Math.max(0, cellBottom - clipY);
|
|
434
480
|
// 对于非fixed列,还需要裁剪掉被fixed列遮挡的部分
|
|
435
481
|
var clipX = drawX;
|
|
436
482
|
var clipWidth = width;
|
|
@@ -476,9 +522,12 @@ var useTableRender = function (params) {
|
|
|
476
522
|
else {
|
|
477
523
|
var dataIndex = column.dataIndex || column.key;
|
|
478
524
|
var cellValue = record[dataIndex];
|
|
525
|
+
// 检查是否是合计行
|
|
526
|
+
var isSummaryRow = record[IS_SUMMARY];
|
|
479
527
|
// 检查是否有 render 函数且返回自定义 ReactNode
|
|
480
528
|
var shouldRenderInCanvas = true;
|
|
481
|
-
|
|
529
|
+
// 对于合计行,不应用render函数,直接显示原始数据
|
|
530
|
+
if (column.render && !isSummaryRow) {
|
|
482
531
|
var rendered = column.render(cellValue, record, rowIndex);
|
|
483
532
|
// 如果返回的不是字符串或数字,说明是自定义组件,应该在覆盖层渲染,不在 Canvas 渲染
|
|
484
533
|
if (typeof rendered !== "string" &&
|
|
@@ -491,29 +540,39 @@ var useTableRender = function (params) {
|
|
|
491
540
|
// 只有在需要在 Canvas 中渲染时才绘制文本
|
|
492
541
|
if (shouldRenderInCanvas) {
|
|
493
542
|
// 应用格式化(日期、精度、千分符)
|
|
494
|
-
var cellText =
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
rowIndex: rowIndex,
|
|
498
|
-
renderFn: column.render,
|
|
499
|
-
});
|
|
500
|
-
// 如果没有自定义render,应用格式化
|
|
501
|
-
if (!column.render) {
|
|
543
|
+
var cellText = void 0;
|
|
544
|
+
// 对于合计行,直接使用格式化函数,不应用render
|
|
545
|
+
if (isSummaryRow) {
|
|
502
546
|
cellText = formatCellValue(cellValue, column);
|
|
503
547
|
}
|
|
548
|
+
else {
|
|
549
|
+
cellText = extractCellText({
|
|
550
|
+
cellValue: cellValue,
|
|
551
|
+
record: record,
|
|
552
|
+
rowIndex: rowIndex,
|
|
553
|
+
renderFn: column.render,
|
|
554
|
+
});
|
|
555
|
+
// 如果没有自定义render,应用格式化
|
|
556
|
+
if (!column.render) {
|
|
557
|
+
cellText = formatCellValue(cellValue, column);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
504
560
|
// 绘制文本
|
|
505
561
|
ctx.fillStyle = COLORS.text;
|
|
506
|
-
|
|
562
|
+
// 合计行字体加粗
|
|
563
|
+
ctx.font = record[IS_SUMMARY]
|
|
564
|
+
? "bold ".concat(FONT_SIZE, "px ").concat(FONT_FAMILY)
|
|
565
|
+
: "".concat(FONT_SIZE, "px ").concat(FONT_FAMILY);
|
|
507
566
|
ctx.textBaseline = "middle";
|
|
508
567
|
var align = column.align || "left";
|
|
509
|
-
var
|
|
568
|
+
var textX_3 = drawX + 16;
|
|
510
569
|
if (align === "center") {
|
|
511
570
|
ctx.textAlign = "center";
|
|
512
|
-
|
|
571
|
+
textX_3 = drawX + width / 2;
|
|
513
572
|
}
|
|
514
573
|
else if (align === "right") {
|
|
515
574
|
ctx.textAlign = "right";
|
|
516
|
-
|
|
575
|
+
textX_3 = drawX + width - 16;
|
|
517
576
|
}
|
|
518
577
|
else {
|
|
519
578
|
ctx.textAlign = "left";
|
|
@@ -525,15 +584,15 @@ var useTableRender = function (params) {
|
|
|
525
584
|
if (wrap) {
|
|
526
585
|
// 换行显示
|
|
527
586
|
var lines = wrapText(ctx, cellText, maxWidth);
|
|
528
|
-
var
|
|
529
|
-
var totalHeight = lines.length *
|
|
587
|
+
var lineHeight_4 = FONT_SIZE + 4; // 行高
|
|
588
|
+
var totalHeight = lines.length * lineHeight_4;
|
|
530
589
|
// 使用合并后的单元格高度计算垂直居中位置
|
|
531
|
-
var
|
|
590
|
+
var startY_4 = y + (cellHeight - totalHeight) / 2 + lineHeight_4 / 2;
|
|
532
591
|
lines.forEach(function (line, lineIndex) {
|
|
533
|
-
var lineY =
|
|
592
|
+
var lineY = startY_4 + lineIndex * lineHeight_4;
|
|
534
593
|
// 只绘制在单元格可见区域内的文本
|
|
535
594
|
if (lineY >= y && lineY <= y + cellHeight) {
|
|
536
|
-
ctx.fillText(line,
|
|
595
|
+
ctx.fillText(line, textX_3, lineY);
|
|
537
596
|
}
|
|
538
597
|
});
|
|
539
598
|
}
|
|
@@ -541,15 +600,13 @@ var useTableRender = function (params) {
|
|
|
541
600
|
// 省略显示 - 使用合并后的单元格高度
|
|
542
601
|
var textY = y + cellHeight / 2;
|
|
543
602
|
var truncatedText = truncateText(ctx, cellText, maxWidth);
|
|
544
|
-
ctx.fillText(truncatedText,
|
|
603
|
+
ctx.fillText(truncatedText, textX_3, textY);
|
|
545
604
|
}
|
|
546
605
|
else {
|
|
547
606
|
// 不处理,直接显示 - 使用合并后的单元格高度
|
|
548
607
|
var textY = y + cellHeight / 2;
|
|
549
|
-
ctx.fillText(cellText,
|
|
608
|
+
ctx.fillText(cellText, textX_3, textY);
|
|
550
609
|
}
|
|
551
|
-
// 绘制角标(跳过合计行)
|
|
552
|
-
var isSummaryRow = hasSummaryRow && rowIndex === processedDataSource.length - 1;
|
|
553
610
|
if (column.badge && !isSummaryRow) {
|
|
554
611
|
var badgeProps = typeof column.badge === "function"
|
|
555
612
|
? column.badge(record)
|
|
@@ -787,7 +844,9 @@ var useTableRender = function (params) {
|
|
|
787
844
|
var cellText = formatCellValue(cellValue, column);
|
|
788
845
|
// 检查是否有render函数且返回自定义ReactNode
|
|
789
846
|
var shouldRenderInCanvas = true;
|
|
790
|
-
|
|
847
|
+
// 对于合计行,不应用render函数,直接显示原始数据
|
|
848
|
+
var isSummaryRowFixed = rowType === "summary";
|
|
849
|
+
if (column.render && !isSummaryRowFixed) {
|
|
791
850
|
var rendered = column.render(cellValue, record, rowIndex);
|
|
792
851
|
// 如果返回的不是字符串或数字,说明是自定义组件,应该在覆盖层渲染,不在 Canvas 渲染
|
|
793
852
|
if (typeof rendered !== "string" &&
|
|
@@ -887,7 +946,7 @@ var useTableRender = function (params) {
|
|
|
887
946
|
var drawFixedBottomRow = useMemoizedFn(function (ctx, rowIndex, relativeIndex, displayWidth, displayHeight, onlyFixed) {
|
|
888
947
|
if (onlyFixed === void 0) { onlyFixed = false; }
|
|
889
948
|
drawFixedRow(ctx, rowIndex, function () {
|
|
890
|
-
var fixedSummaryHeight =
|
|
949
|
+
var fixedSummaryHeight = summaryFixed && hasSummaryRow ? rowHeight : 0;
|
|
891
950
|
return (displayHeight -
|
|
892
951
|
(needHorizontalScrollbar ? SCROLLBAR_SIZE : 0) -
|
|
893
952
|
fixedSummaryHeight -
|
|
@@ -899,7 +958,7 @@ var useTableRender = function (params) {
|
|
|
899
958
|
var drawFixedBottomRowsBorder = useMemoizedFn(function (ctx, rowCount, displayWidth, displayHeight, onlyFixed) {
|
|
900
959
|
if (onlyFixed === void 0) { onlyFixed = false; }
|
|
901
960
|
drawFixedRowsBorder(ctx, rowCount, function () {
|
|
902
|
-
var fixedSummaryHeight =
|
|
961
|
+
var fixedSummaryHeight = summaryFixed && hasSummaryRow ? rowHeight : 0;
|
|
903
962
|
return (displayHeight -
|
|
904
963
|
(needHorizontalScrollbar ? SCROLLBAR_SIZE : 0) -
|
|
905
964
|
fixedSummaryHeight -
|
|
@@ -948,7 +1007,7 @@ var useTableRender = function (params) {
|
|
|
948
1007
|
var fixedBottomRowsCount = (fixedRowsConfig === null || fixedRowsConfig === void 0 ? void 0 : fixedRowsConfig.bottomCount) || 0;
|
|
949
1008
|
var bottomRowsStartIndex = processedDataSource.length -
|
|
950
1009
|
fixedBottomRowsCount -
|
|
951
|
-
(
|
|
1010
|
+
(summaryFixed && hasSummaryRow ? 1 : 0);
|
|
952
1011
|
var summaryRowIndex = hasSummaryRow
|
|
953
1012
|
? processedDataSource.length - 1
|
|
954
1013
|
: -1;
|
|
@@ -974,7 +1033,7 @@ var useTableRender = function (params) {
|
|
|
974
1033
|
row < bottomRowsStartIndex + fixedBottomRowsCount) {
|
|
975
1034
|
// 固定底部行
|
|
976
1035
|
var relativeIndex = row - bottomRowsStartIndex;
|
|
977
|
-
var fixedSummaryHeight =
|
|
1036
|
+
var fixedSummaryHeight = summaryFixed && hasSummaryRow ? rowHeight : 0;
|
|
978
1037
|
y =
|
|
979
1038
|
displayHeight -
|
|
980
1039
|
(needHorizontalScrollbar ? SCROLLBAR_SIZE : 0) -
|
|
@@ -984,7 +1043,7 @@ var useTableRender = function (params) {
|
|
|
984
1043
|
cellHeight = rowHeight;
|
|
985
1044
|
isFixedRow = true;
|
|
986
1045
|
}
|
|
987
|
-
else if (
|
|
1046
|
+
else if (summaryFixed && row === summaryRowIndex) {
|
|
988
1047
|
// 固定合计行
|
|
989
1048
|
var summaryRowY = displayHeight -
|
|
990
1049
|
(needHorizontalScrollbar ? SCROLLBAR_SIZE : 0) -
|
|
@@ -1157,6 +1216,9 @@ var useTableRender = function (params) {
|
|
|
1157
1216
|
canvas.style.width = "".concat(displayWidth, "px");
|
|
1158
1217
|
canvas.style.height = "".concat(displayHeight, "px");
|
|
1159
1218
|
ctx.scale(dpr, dpr);
|
|
1219
|
+
// 优化文字渲染质量,防止模糊
|
|
1220
|
+
ctx.imageSmoothingEnabled = true;
|
|
1221
|
+
ctx.imageSmoothingQuality = "high";
|
|
1160
1222
|
// 清空画布
|
|
1161
1223
|
ctx.clearRect(0, 0, displayWidth, displayHeight);
|
|
1162
1224
|
// 绘制背景
|
|
@@ -1168,7 +1230,7 @@ var useTableRender = function (params) {
|
|
|
1168
1230
|
// 计算固定行占用的高度
|
|
1169
1231
|
var fixedTopRowsHeight = fixedTopRowsCount * rowHeight;
|
|
1170
1232
|
var fixedBottomRowsHeight = fixedBottomRowsCount * rowHeight;
|
|
1171
|
-
var fixedSummaryRowHeight =
|
|
1233
|
+
var fixedSummaryRowHeight = summaryFixed && hasSummaryRow ? rowHeight : 0;
|
|
1172
1234
|
// 计算可视区域的数据区域高度(不包括表头、固定行和固定合计行)
|
|
1173
1235
|
var dataAreaHeight = displayHeight -
|
|
1174
1236
|
headerHeight -
|
|
@@ -1182,6 +1244,35 @@ var useTableRender = function (params) {
|
|
|
1182
1244
|
Math.ceil((scrollState.scrollTop + dataAreaHeight) / rowHeight), processedDataSource.length - fixedBottomRowsCount
|
|
1183
1245
|
// 注意:不再减去合计行数量,因为合计行的空间已在 dataAreaHeight 中考虑
|
|
1184
1246
|
);
|
|
1247
|
+
// 关键修复:向前扩展渲染范围,检查是否有合并单元格延伸到可视区域
|
|
1248
|
+
// 策略:对每一列独立检查,找到该列最靠前的需要渲染的主合并单元格
|
|
1249
|
+
if (mergeCellMap && scrollStartRow > fixedTopRowsCount) {
|
|
1250
|
+
var originalStartRow = scrollStartRow;
|
|
1251
|
+
var minStartRow = scrollStartRow;
|
|
1252
|
+
// 对每一列独立检查
|
|
1253
|
+
for (var colIndex = 0; colIndex < columnRenderInfos.length; colIndex++) {
|
|
1254
|
+
// 向前查找这一列的主合并单元格,最多向前查找20行
|
|
1255
|
+
for (var checkRow = originalStartRow - 1; checkRow >= fixedTopRowsCount && checkRow >= originalStartRow - 20; checkRow--) {
|
|
1256
|
+
var mergeCellKey = "".concat(checkRow, "-").concat(colIndex);
|
|
1257
|
+
var mergeInfo = mergeCellMap.get(mergeCellKey);
|
|
1258
|
+
// 如果找到主单元格(不是被合并的单元格)
|
|
1259
|
+
if (mergeInfo && !mergeInfo.skip && mergeInfo.rowSpan > 1) {
|
|
1260
|
+
// 计算合并单元格的底部行索引
|
|
1261
|
+
var mergeEndRow = checkRow + mergeInfo.rowSpan - 1;
|
|
1262
|
+
// 如果这个合并单元格延伸到可视区域
|
|
1263
|
+
if (mergeEndRow >= originalStartRow) {
|
|
1264
|
+
// 更新最小起始行
|
|
1265
|
+
minStartRow = Math.min(minStartRow, checkRow);
|
|
1266
|
+
}
|
|
1267
|
+
// 找到这一列的主单元格后,停止向前查找该列
|
|
1268
|
+
break;
|
|
1269
|
+
}
|
|
1270
|
+
// 如果是skip的单元格或没有合并信息,继续向前查找
|
|
1271
|
+
// 因为主单元格可能在更前面
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
scrollStartRow = minStartRow;
|
|
1275
|
+
}
|
|
1185
1276
|
// 1. 绘制可滚动区域的数据行(包括边框)
|
|
1186
1277
|
renderWithFixedLayer(ctx,
|
|
1187
1278
|
// 渲染行内容
|
|
@@ -1215,7 +1306,7 @@ var useTableRender = function (params) {
|
|
|
1215
1306
|
ctx.save();
|
|
1216
1307
|
var bottomRowsStartIndex_1 = processedDataSource.length -
|
|
1217
1308
|
fixedBottomRowsCount -
|
|
1218
|
-
(
|
|
1309
|
+
(summaryFixed && hasSummaryRow ? 1 : 0);
|
|
1219
1310
|
renderWithFixedLayer(ctx,
|
|
1220
1311
|
// 渲染行内容
|
|
1221
1312
|
function (onlyFixed) {
|
|
@@ -1233,7 +1324,7 @@ var useTableRender = function (params) {
|
|
|
1233
1324
|
// 7. 绘制固定列阴影
|
|
1234
1325
|
drawFixedColumns(ctx, scrollStartRow, scrollEndRow, displayWidth, displayHeight);
|
|
1235
1326
|
// 4. 绘制固定合计行(如果启用)
|
|
1236
|
-
if (
|
|
1327
|
+
if (summaryFixed && hasSummaryRow) {
|
|
1237
1328
|
var summaryRowIndex_1 = processedDataSource.length - 1;
|
|
1238
1329
|
var summaryRowY_1 = displayHeight -
|
|
1239
1330
|
(needHorizontalScrollbar ? SCROLLBAR_SIZE : 0) -
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { __assign, __spreadArray } from '../../_virtual/_tslib.js';
|
|
2
2
|
import { useState, useEffect, useMemo } from 'react';
|
|
3
3
|
import { useMemoizedFn } from 'ahooks';
|
|
4
|
+
import 'zmdms-utils';
|
|
4
5
|
import 'dayjs';
|
|
5
6
|
import { getAllLeafColumns, findColumnByKey } from '../utils/columnHelpers.js';
|
|
6
7
|
|
|
@@ -129,6 +129,13 @@ interface ICanvasColumnType<RecordType = any> {
|
|
|
129
129
|
* 开启合计
|
|
130
130
|
*/
|
|
131
131
|
isSummary?: boolean;
|
|
132
|
+
/**
|
|
133
|
+
* 合计自定义计算回调函数
|
|
134
|
+
* @param value 当前值
|
|
135
|
+
* @param values 所有值的数组
|
|
136
|
+
* @returns 计算后的合计值
|
|
137
|
+
*/
|
|
138
|
+
totalCalcCallback?: (value: any, values: any) => any;
|
|
132
139
|
/**
|
|
133
140
|
* 开启合并的字段,按其他字段维度合并
|
|
134
141
|
*/
|
|
@@ -172,6 +179,7 @@ interface ICanvasColumnType<RecordType = any> {
|
|
|
172
179
|
[key: string]: any;
|
|
173
180
|
};
|
|
174
181
|
}
|
|
182
|
+
type ICanvasColumnsType<RecordType = any> = ICanvasColumnType<RecordType>[];
|
|
175
183
|
interface IBadgeProps {
|
|
176
184
|
/**
|
|
177
185
|
* 角标颜色
|
|
@@ -237,6 +245,10 @@ interface ICanvasTableProps<RecordType = any> {
|
|
|
237
245
|
* 表头高度
|
|
238
246
|
*/
|
|
239
247
|
headerHeight?: number;
|
|
248
|
+
/**
|
|
249
|
+
* 表头换行
|
|
250
|
+
*/
|
|
251
|
+
headerWrap?: boolean;
|
|
240
252
|
/**
|
|
241
253
|
* 勾选配置
|
|
242
254
|
*/
|
|
@@ -369,7 +381,19 @@ interface ICanvasTableProps<RecordType = any> {
|
|
|
369
381
|
* 合计行是否固定在底部(默认为false)
|
|
370
382
|
* 当为true时,合计行固定在表格底部不参与滚动
|
|
371
383
|
*/
|
|
372
|
-
|
|
384
|
+
summaryFixed?: boolean;
|
|
385
|
+
/**
|
|
386
|
+
* 是否开启自动计算Y轴高度
|
|
387
|
+
*/
|
|
388
|
+
isAutoScrollY?: boolean;
|
|
389
|
+
/**
|
|
390
|
+
* 自动计算Y轴高度时,canvas table下面留出的距离
|
|
391
|
+
*/
|
|
392
|
+
autoScrollYMarginBottom?: number;
|
|
393
|
+
/**
|
|
394
|
+
* 表格id(用于自动高度计算时定位元素)
|
|
395
|
+
*/
|
|
396
|
+
canvasTableId?: string;
|
|
373
397
|
}
|
|
374
398
|
|
|
375
|
-
export { ColumnDataType, FilterConfig, IBadgeProps, ICanvasColumnType, ICanvasRowSelection, ICanvasTableProps, SortOrder };
|
|
399
|
+
export { ColumnDataType, FilterConfig, IBadgeProps, ICanvasColumnType, ICanvasColumnsType, ICanvasRowSelection, ICanvasTableProps, SortOrder };
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* 获取鼠标位置对应的单元格
|
|
6
6
|
*/
|
|
7
7
|
var getCellFromMousePosition = function (params) {
|
|
8
|
-
var x = params.x, y = params.y, headerHeight = params.headerHeight, rowHeight = params.rowHeight, scrollTop = params.scrollTop, scrollLeft = params.scrollLeft, columnRenderInfos = params.columnRenderInfos, dataLength = params.dataLength, _a = params.fixedTopRowsCount, fixedTopRowsCount = _a === void 0 ? 0 : _a, _b = params.fixedBottomRowsCount, fixedBottomRowsCount = _b === void 0 ? 0 : _b, _c = params.hasSummaryRow, hasSummaryRow = _c === void 0 ? false : _c, _d = params.
|
|
8
|
+
var x = params.x, y = params.y, headerHeight = params.headerHeight, rowHeight = params.rowHeight, scrollTop = params.scrollTop, scrollLeft = params.scrollLeft, columnRenderInfos = params.columnRenderInfos, dataLength = params.dataLength, _a = params.fixedTopRowsCount, fixedTopRowsCount = _a === void 0 ? 0 : _a, _b = params.fixedBottomRowsCount, fixedBottomRowsCount = _b === void 0 ? 0 : _b, _c = params.hasSummaryRow, hasSummaryRow = _c === void 0 ? false : _c, _d = params.summaryFixed, summaryFixed = _d === void 0 ? false : _d, _e = params.displayHeight, displayHeight = _e === void 0 ? 0 : _e, _f = params.needHorizontalScrollbar, needHorizontalScrollbar = _f === void 0 ? false : _f, _g = params.scrollbarSize, scrollbarSize = _g === void 0 ? 12 : _g;
|
|
9
9
|
// 判断是否在表头区域(row=-1表示表头)
|
|
10
10
|
var rowIndex;
|
|
11
11
|
if (y < headerHeight) {
|
|
@@ -23,7 +23,7 @@ var getCellFromMousePosition = function (params) {
|
|
|
23
23
|
return findColumn(x, scrollLeft, columnRenderInfos, rowIndex);
|
|
24
24
|
}
|
|
25
25
|
// 检查是否在固定合计行区域
|
|
26
|
-
if (
|
|
26
|
+
if (summaryFixed && hasSummaryRow && displayHeight > 0) {
|
|
27
27
|
var summaryRowY = displayHeight -
|
|
28
28
|
(needHorizontalScrollbar ? scrollbarSize : 0) -
|
|
29
29
|
rowHeight;
|
|
@@ -35,7 +35,7 @@ var getCellFromMousePosition = function (params) {
|
|
|
35
35
|
}
|
|
36
36
|
// 检查是否在固定底部行区域
|
|
37
37
|
if (fixedBottomRowsCount > 0 && displayHeight > 0) {
|
|
38
|
-
var fixedSummaryHeight =
|
|
38
|
+
var fixedSummaryHeight = summaryFixed && hasSummaryRow ? rowHeight : 0;
|
|
39
39
|
var fixedBottomAreaStart = displayHeight -
|
|
40
40
|
(needHorizontalScrollbar ? scrollbarSize : 0) -
|
|
41
41
|
fixedSummaryHeight -
|
|
@@ -50,7 +50,7 @@ var getCellFromMousePosition = function (params) {
|
|
|
50
50
|
var relativeIndex = Math.floor(relativeY / rowHeight);
|
|
51
51
|
var bottomRowsStartIndex = dataLength -
|
|
52
52
|
fixedBottomRowsCount -
|
|
53
|
-
(
|
|
53
|
+
(summaryFixed && hasSummaryRow ? 1 : 0);
|
|
54
54
|
rowIndex = bottomRowsStartIndex + relativeIndex;
|
|
55
55
|
if (rowIndex < 0 || rowIndex >= dataLength)
|
|
56
56
|
return null;
|
|
@@ -65,7 +65,7 @@ var getCellFromMousePosition = function (params) {
|
|
|
65
65
|
// 如果有固定底部行或合计行,需要排除它们
|
|
66
66
|
var maxScrollableRow = dataLength -
|
|
67
67
|
fixedBottomRowsCount -
|
|
68
|
-
(
|
|
68
|
+
(summaryFixed && hasSummaryRow ? 1 : 0);
|
|
69
69
|
if (rowIndex >= maxScrollableRow) {
|
|
70
70
|
// 超出可滚动区域,可能在滚动条或空白区域
|
|
71
71
|
return null;
|
|
@@ -24,9 +24,13 @@ var findColumnByKey = function (columns, key) {
|
|
|
24
24
|
/**
|
|
25
25
|
* 递归处理列的render函数(转换为统一的调用格式)
|
|
26
26
|
*/
|
|
27
|
-
var processColumnRender = function (column, renderMode) {
|
|
27
|
+
var processColumnRender = function (column, renderMode, headerWrap) {
|
|
28
28
|
if (renderMode === void 0) { renderMode = "object"; }
|
|
29
29
|
var processedColumn = __assign({}, column);
|
|
30
|
+
if (headerWrap) {
|
|
31
|
+
processedColumn.wrap =
|
|
32
|
+
processedColumn.wrap === undefined ? headerWrap : processedColumn.wrap;
|
|
33
|
+
}
|
|
30
34
|
// 处理当前列的render函数
|
|
31
35
|
if (column.render) {
|
|
32
36
|
var render_1 = column.render;
|
|
@@ -40,7 +44,7 @@ var processColumnRender = function (column, renderMode) {
|
|
|
40
44
|
// 递归处理children
|
|
41
45
|
if (column.children && Array.isArray(column.children)) {
|
|
42
46
|
processedColumn.children = column.children.map(function (child) {
|
|
43
|
-
return processColumnRender(child, renderMode);
|
|
47
|
+
return processColumnRender(child, renderMode, headerWrap);
|
|
44
48
|
});
|
|
45
49
|
}
|
|
46
50
|
return processedColumn;
|
|
@@ -18,7 +18,7 @@ var COLORS = {
|
|
|
18
18
|
hoverBg: "rgb(239, 245, 254)",
|
|
19
19
|
selectionBg: "rgba(24, 144, 255, 0.1)",
|
|
20
20
|
// 文本色
|
|
21
|
-
text: "
|
|
21
|
+
text: "#333333",
|
|
22
22
|
emptyText: "rgba(0, 0, 0, 0.25)",
|
|
23
23
|
// 边框色
|
|
24
24
|
border: "rgb(222, 233, 246)",
|
|
@@ -33,8 +33,8 @@ var COLORS = {
|
|
|
33
33
|
checkboxDisabled: "#d9d9d9",
|
|
34
34
|
};
|
|
35
35
|
// 字体配置
|
|
36
|
-
var FONT_FAMILY = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto';
|
|
37
|
-
var FONT_SIZE =
|
|
36
|
+
var FONT_FAMILY = '"Microsoft YaHei", 微软雅黑, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
37
|
+
var FONT_SIZE = 13; // 增大1px,提升清晰度
|
|
38
38
|
// 图标尺寸
|
|
39
39
|
var CHECKBOX_SIZE = 16;
|
|
40
40
|
var SORT_ICON_SIZE = 6;
|
|
@@ -1,30 +1,9 @@
|
|
|
1
|
+
import { exactRound, addThousedSeparator } from 'zmdms-utils';
|
|
1
2
|
import dayjs from 'dayjs';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* 数据格式化工具函数
|
|
5
6
|
*/
|
|
6
|
-
/**
|
|
7
|
-
* 格式化数值(千分符)
|
|
8
|
-
*/
|
|
9
|
-
var formatThousand = function (value) {
|
|
10
|
-
if (value === null || value === undefined || value === "")
|
|
11
|
-
return "";
|
|
12
|
-
var num = typeof value === "string" ? parseFloat(value) : value;
|
|
13
|
-
if (isNaN(num))
|
|
14
|
-
return String(value);
|
|
15
|
-
return num.toLocaleString("en-US");
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* 格式化精度
|
|
19
|
-
*/
|
|
20
|
-
var formatPrecision = function (value, precision) {
|
|
21
|
-
if (value === null || value === undefined || value === "")
|
|
22
|
-
return "";
|
|
23
|
-
var num = typeof value === "string" ? parseFloat(value) : value;
|
|
24
|
-
if (isNaN(num))
|
|
25
|
-
return String(value);
|
|
26
|
-
return num.toFixed(precision);
|
|
27
|
-
};
|
|
28
7
|
/**
|
|
29
8
|
* 格式化日期
|
|
30
9
|
*/
|
|
@@ -48,13 +27,13 @@ var formatCellValue = function (value, column) {
|
|
|
48
27
|
}
|
|
49
28
|
// 数值精度
|
|
50
29
|
if (column.precision !== undefined && typeof formattedValue === "number") {
|
|
51
|
-
formattedValue =
|
|
30
|
+
formattedValue = exactRound(formattedValue, column.precision);
|
|
52
31
|
}
|
|
53
32
|
// 千分符
|
|
54
33
|
if (column.thousand && !isNaN(Number(formattedValue))) {
|
|
55
|
-
formattedValue =
|
|
34
|
+
formattedValue = addThousedSeparator(formattedValue);
|
|
56
35
|
}
|
|
57
36
|
return String(formattedValue);
|
|
58
37
|
};
|
|
59
38
|
|
|
60
|
-
export { formatCellValue, formatDate
|
|
39
|
+
export { formatCellValue, formatDate };
|
package/dist/index.build.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ export { default as Sortable } from './es/sortable/sortable.js';
|
|
|
49
49
|
export { default as ElectronSignatures } from './es/electronsignatures/index.js';
|
|
50
50
|
export { default as message } from './es/message/index.js';
|
|
51
51
|
export { default as CanvasTable } from './es/canvastable/canvasTable.js';
|
|
52
|
-
export { ICanvasColumnType, ICanvasTableProps } from './es/canvastable/interface.js';
|
|
52
|
+
export { ICanvasColumnType, ICanvasColumnsType, ICanvasTableProps } from './es/canvastable/interface.js';
|
|
53
53
|
export { Affix, Anchor, AutoComplete, Avatar, BackTop, Badge, Breadcrumb, Card, Carousel, Cascader, Checkbox, Col, Comment, ConfigProvider, Divider, Drawer, Dropdown, Empty, Grid, Image, Layout, List, Mentions, Menu, PageHeader, Popconfirm, Popover, Progress, Radio, Rate, Result, Row, Segmented, Skeleton, Slider, Space, Spin, Statistic, Steps, Switch, Timeline, Tooltip, Transfer, Typography, Upload, notification } from 'antd';
|
|
54
54
|
export { IButtonProps } from './es/button/interface.js';
|
|
55
55
|
export { IButtonDownloadProps } from './es/button/buttonDownload.js';
|