zmdms-webui 2.3.5 → 2.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { __assign } from '../_virtual/_tslib.js';
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
- import { useRef, useState, useCallback, useMemo } from 'react';
3
+ import { useRef, useState, useCallback, useMemo, useImperativeHandle } from 'react';
4
4
  import { Spin } from 'antd';
5
5
  import './components/FilterPopover.js';
6
6
  import CellOverlay from './components/CellOverlay.js';
@@ -39,7 +39,7 @@ import { getTableColumns } from '../table/utils.js';
39
39
  import DynamicSetting from '../dynamicsetting/dynamicSetting.js';
40
40
 
41
41
  function CanvasTable(props) {
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;
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, _u = props.headerAlign, headerAlign = _u === void 0 ? "center" : _u, tableRefHandle = props.tableRefHandle, exportExcelConfig = props.exportExcelConfig;
43
43
  var canvasRef = useRef(null);
44
44
  var containerRef = useRef(null);
45
45
  var filterPopoverRef = useRef(null);
@@ -61,20 +61,17 @@ function CanvasTable(props) {
61
61
  return String((_a = record[rowKey]) !== null && _a !== void 0 ? _a : index);
62
62
  }, [rowKey]);
63
63
  // 动态列配置
64
- var _u = useDynamicListByColumns(columns, {
64
+ var _v = useDynamicListByColumns(columns, {
65
65
  dynamicKey: dynamicKey,
66
66
  dynamicVersion: dynamicVersion,
67
67
  customDynamicListHandle: customDynamicListHandle,
68
- }), defaultDynamicList = _u.defaultDynamicList, currentDynamicList = _u.currentDynamicList, onCurrentListChange = _u.onCurrentListChange, dynamicSettingRef = _u.dynamicSettingRef;
68
+ }), defaultDynamicList = _v.defaultDynamicList, currentDynamicList = _v.currentDynamicList, onCurrentListChange = _v.onCurrentListChange, dynamicSettingRef = _v.dynamicSettingRef;
69
69
  // 根据动态列配置处理columns
70
70
  var dynamicColumns = useMemo(function () { return getTableColumns(columns, currentDynamicList); }, [columns, currentDynamicList]).columns;
71
- // 计算表头动态高度(支持wrap换行)
72
- var calculatedHeaderHeight = useHeaderHeight({
73
- columns: (dynamicColumns || columns),
74
- headerHeight: headerHeight,
75
- });
76
71
  // 内部列宽状态(未开启动态配置时使用)
77
- var _v = useState({}), internalColumnWidths = _v[0], setInternalColumnWidths = _v[1];
72
+ var _w = useState({}), internalColumnWidths = _w[0], setInternalColumnWidths = _w[1];
73
+ // 跟踪用户手动调整过宽度的列(用于排除自动宽度分配)
74
+ var _x = useState(new Set()), manuallyResizedColumnKeys = _x[0], setManuallyResizedColumnKeys = _x[1];
78
75
  // 处理选中框列、序号列等
79
76
  var processedColumnsOld = useProcessedColumns({
80
77
  columns: columns,
@@ -86,32 +83,53 @@ function CanvasTable(props) {
86
83
  renderMode: renderMode,
87
84
  dynamicSettingRef: dynamicSettingRef,
88
85
  headerWrap: headerWrap,
86
+ headerAlign: headerAlign,
89
87
  });
90
88
  // 表格状态管理
91
- var _w = useTableState({
89
+ var _y = useTableState({
92
90
  dataSource: dataSource,
93
91
  columns: processedColumnsOld,
94
92
  rowSelection: rowSelection,
95
93
  onFilterChange: onFilterChange,
96
- }), state = _w.state, setState = _w.setState, processedDataSource = _w.processedDataSource, handleFilterChange = _w.handleFilterChange, closeFilterPopover = _w.closeFilterPopover, autoGeneratedFilters = _w.autoGeneratedFilters;
94
+ }), state = _y.state, setState = _y.setState, processedDataSource = _y.processedDataSource, handleFilterChange = _y.handleFilterChange, closeFilterPopover = _y.closeFilterPopover, autoGeneratedFilters = _y.autoGeneratedFilters;
97
95
  var order = useMemo(function () {
98
96
  return state.sortOrder && state.sortField
99
97
  ? { field: state.sortField, order: state.sortOrder }
100
98
  : undefined;
101
99
  }, [state.sortOrder, state.sortField]);
102
- var _x = useAutoMerge(processedDataSource, processedColumnsOld, {
100
+ var _z = useAutoMerge(processedDataSource, processedColumnsOld, {
103
101
  isAutoMerge: isAutoMerge,
104
102
  isDimensionDynamic: isDimensionDynamic,
105
103
  order: order,
106
104
  dimensionCustomSumKeys: dimensionCustomSumKeys,
107
- }), newDataSource = _x[0], processedColumns = _x[1];
105
+ }), newDataSource = _z[0], processedColumns = _z[1];
108
106
  // 生成合计行和最终数据源
109
- var _y = useSummaryRow({
107
+ var _0 = useSummaryRow({
110
108
  columns: processedColumns,
111
109
  dataSource: newDataSource,
112
- }), finalDataSource = _y.finalDataSource, hasSummaryRow = _y.hasSummaryRow;
113
- // 计算列的渲染信息
114
- var columnRenderInfos = useMemo(function () { return calculateColumnRenderInfos(processedColumns); }, [processedColumns]);
110
+ }), finalDataSource = _0.finalDataSource, hasSummaryRow = _0.hasSummaryRow;
111
+ // 自动高度计算(需要在容器尺寸计算之前)
112
+ var autoHeight = useCanvasTableAutoHeight(isAutoScrollY, autoScrollYMarginBottom, canvasTableId);
113
+ // 监听容器尺寸变化(提前计算,用于列宽自适应)
114
+ var containerSize = useContainerSize({
115
+ containerRef: containerRef,
116
+ width: width,
117
+ height: isAutoScrollY ? autoHeight || height : height,
118
+ });
119
+ var containerWidth = containerSize.width;
120
+ var containerHeight = containerSize.height;
121
+ // 计算列的渲染信息(使用容器宽度进行自适应填充)
122
+ // 手动调整过宽度的列不参与自动宽度分配
123
+ var columnRenderInfos = useMemo(function () {
124
+ return calculateColumnRenderInfos(processedColumns, containerWidth, manuallyResizedColumnKeys);
125
+ }, [processedColumns, containerWidth, manuallyResizedColumnKeys]);
126
+ // 计算表头动态高度(支持wrap换行)
127
+ // 注意:必须在 columnRenderInfos 计算之后,以便使用实际的列宽
128
+ var calculatedHeaderHeight = useHeaderHeight({
129
+ columns: processedColumns,
130
+ headerHeight: headerHeight,
131
+ columnRenderInfos: columnRenderInfos,
132
+ });
115
133
  // 计算合并单元格信息
116
134
  var mergeCellMap = useMergeCells({
117
135
  dataSource: finalDataSource,
@@ -124,18 +142,8 @@ function CanvasTable(props) {
124
142
  var totalHeight = useMemo(function () {
125
143
  return calculateTotalHeight(calculatedHeaderHeight, finalDataSource.length, rowHeight);
126
144
  }, [calculatedHeaderHeight, finalDataSource.length, rowHeight]);
127
- // 自动高度计算
128
- var autoHeight = useCanvasTableAutoHeight(isAutoScrollY, autoScrollYMarginBottom, canvasTableId);
129
- // 监听容器尺寸变化
130
- var containerSize = useContainerSize({
131
- containerRef: containerRef,
132
- width: width,
133
- height: isAutoScrollY ? autoHeight || height : height,
134
- });
135
- var containerWidth = containerSize.width;
136
- var containerHeight = containerSize.height;
137
145
  // 计算滚动条指标
138
- var _z = useScrollbarMetrics({
146
+ var _1 = useScrollbarMetrics({
139
147
  containerWidth: containerWidth,
140
148
  containerHeight: containerHeight,
141
149
  totalWidth: totalWidth,
@@ -143,15 +151,15 @@ function CanvasTable(props) {
143
151
  headerHeight: calculatedHeaderHeight,
144
152
  scrollTop: 0,
145
153
  scrollLeft: 0,
146
- }), maxScrollTop = _z.maxScrollTop, maxScrollLeft = _z.maxScrollLeft;
154
+ }), maxScrollTop = _1.maxScrollTop, maxScrollLeft = _1.maxScrollLeft;
147
155
  // 滚动管理(使用预先计算的maxScrollTop和maxScrollLeft)
148
- var _0 = useTableScroll({
156
+ var _2 = useTableScroll({
149
157
  canvasRef: canvasRef,
150
158
  containerRef: containerRef,
151
159
  maxScrollTop: maxScrollTop,
152
160
  maxScrollLeft: maxScrollLeft,
153
161
  onScroll: onScroll,
154
- }), scrollState = _0.scrollState, setScrollState = _0.setScrollState;
162
+ }), scrollState = _2.scrollState, setScrollState = _2.setScrollState;
155
163
  // 数据变化时重置滚动位置(筛选、排序、数据源更新等操作后)
156
164
  useScrollReset({
157
165
  dataSourceLength: dataSource.length,
@@ -172,17 +180,23 @@ function CanvasTable(props) {
172
180
  scrollLeft: scrollState.scrollLeft,
173
181
  }).actualMetrics;
174
182
  // 单元格框选
175
- var _1 = useTableSelection({
183
+ var _3 = useTableSelection({
176
184
  state: state,
177
185
  setState: setState,
178
186
  }),
179
187
  // selectionStartRef,
180
- startSelection = _1.startSelection, updateSelection = _1.updateSelection, extendSelection = _1.extendSelection;
188
+ startSelection = _3.startSelection, updateSelection = _3.updateSelection, extendSelection = _3.extendSelection;
181
189
  // 处理列宽调整
182
190
  var handleColumnResize = useCallback(function (columnKey, newWidth) {
183
191
  var _a;
184
192
  // 先调用外部回调(用户可以监听列宽变化)
185
193
  onColumnResize === null || onColumnResize === void 0 ? void 0 : onColumnResize(columnKey, newWidth);
194
+ // 记录用户手动调整过的列
195
+ setManuallyResizedColumnKeys(function (prev) {
196
+ var newSet = new Set(prev);
197
+ newSet.add(columnKey);
198
+ return newSet;
199
+ });
186
200
  if (dynamicKey && currentDynamicList) {
187
201
  // 开启了动态配置:更新到动态配置中
188
202
  var newList = currentDynamicList.map(function (item) { return (__assign({}, item)); });
@@ -226,13 +240,13 @@ function CanvasTable(props) {
226
240
  onCurrentListChange,
227
241
  ]);
228
242
  // 列宽调整
229
- var _2 = useColumnResize({
243
+ var _4 = useColumnResize({
230
244
  columnRenderInfos: columnRenderInfos,
231
245
  containerWidth: containerWidth,
232
246
  headerHeight: calculatedHeaderHeight,
233
247
  scrollLeft: scrollState.scrollLeft,
234
248
  onColumnResize: handleColumnResize,
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;
249
+ }), resizeState = _4.resizeState, checkResizeHandle = _4.checkResizeHandle, startResize = _4.startResize, updateResize = _4.updateResize, endResize = _4.endResize, setHoverResizeColumn = _4.setHoverResizeColumn, getColumnWidth = _4.getColumnWidth, RESIZE_HANDLE_WIDTH = _4.RESIZE_HANDLE_WIDTH;
236
250
  // 复制到剪贴板
237
251
  var getSelectedCellsText = useCopyToClipboard({
238
252
  cellSelection: state.cellSelection,
@@ -249,13 +263,17 @@ function CanvasTable(props) {
249
263
  });
250
264
  }
251
265
  }, [getSelectedCellsText]);
266
+ // 过滤勾选框和index行给导出用
267
+ var exportColumns = useMemo(function () {
268
+ return processedColumns.filter(function (item) { return !item.key.includes("__"); });
269
+ }, [processedColumns]);
252
270
  // Excel导出功能
253
271
  var exportExcel = useExcelExport(processedDataSource, {
254
- columns: processedColumns,
272
+ columns: exportColumns,
255
273
  isAutoMerge: isAutoMerge,
256
274
  });
257
275
  // 交互事件处理(使用baseScrollbarMetrics的maxScrollTop/maxScrollLeft以保持稳定)
258
- var _3 = useTableInteraction({
276
+ var _5 = useTableInteraction({
259
277
  state: state,
260
278
  setState: setState,
261
279
  scrollState: scrollState,
@@ -301,10 +319,11 @@ function CanvasTable(props) {
301
319
  fixedRowsCount: fixedRowsCount,
302
320
  fixedRowsConfig: fixedRowsConfig,
303
321
  summaryFixed: summaryFixed,
304
- }), handleCanvasMouseDown = _3.handleCanvasMouseDown, handleCanvasMouseMove = _3.handleCanvasMouseMove, handleCanvasMouseUp = _3.handleCanvasMouseUp, handleCanvasMouseLeave = _3.handleCanvasMouseLeave, handleCanvasContextMenu = _3.handleCanvasContextMenu;
322
+ }), handleCanvasMouseDown = _5.handleCanvasMouseDown, handleCanvasMouseMove = _5.handleCanvasMouseMove, handleCanvasMouseUp = _5.handleCanvasMouseUp, handleCanvasMouseLeave = _5.handleCanvasMouseLeave, handleCanvasContextMenu = _5.handleCanvasContextMenu;
305
323
  // 渲染表格
306
324
  useTableRender(__assign(__assign({ canvasRef: canvasRef, processedDataSource: finalDataSource, columnRenderInfos: columnRenderInfos, columns: processedColumns, // 传递原始columns用于渲染多级表头
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 }));
325
+ state: state, scrollState: scrollState, rowSelection: rowSelection, containerWidth: containerWidth, containerHeight: containerHeight, headerHeight: calculatedHeaderHeight, baseHeaderHeight: headerHeight, // 传入原始基础高度用于计算每层高度
326
+ 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 }));
308
327
  // 单元格覆盖层
309
328
  var cellOverlays = useTableCellOverlay({
310
329
  canvasRef: canvasRef,
@@ -362,11 +381,85 @@ function CanvasTable(props) {
362
381
  isVisible: state.badgePopover.visible,
363
382
  onClose: handleCloseBadgePopover,
364
383
  });
384
+ // 暴露给外部的方法
385
+ useImperativeHandle(tableRefHandle, function () { return ({
386
+ /** 获取当前表格的配置信息(动态列配置) */
387
+ getDynamicList: function () {
388
+ return currentDynamicList || [];
389
+ },
390
+ /** 动态列配置重置 */
391
+ onResetDynamicList: function () {
392
+ var _a, _b;
393
+ (_b = (_a = dynamicSettingRef.current) === null || _a === void 0 ? void 0 : _a.resetList) === null || _b === void 0 ? void 0 : _b.call(_a);
394
+ },
395
+ /** 动态列配置设置 */
396
+ onSetDynamicList: function (list) {
397
+ var _a, _b;
398
+ (_b = (_a = dynamicSettingRef.current) === null || _a === void 0 ? void 0 : _a.updateList) === null || _b === void 0 ? void 0 : _b.call(_a, list);
399
+ },
400
+ /** 导出Excel */
401
+ exportExcel: exportExcel,
402
+ /** 获取表格容器 */
403
+ getContainer: function () { return containerRef.current; },
404
+ /** 全屏展示表格 */
405
+ toggleFullScreen: function () {
406
+ var _a;
407
+ (_a = tableMenuRef.current) === null || _a === void 0 ? void 0 : _a.toggleFullscreen();
408
+ },
409
+ /** 获取选中的行keys */
410
+ getSelectedRowKeys: function () {
411
+ return state.selectedRowKeys;
412
+ },
413
+ /** 设置选中的行keys */
414
+ setSelectedRowKeys: function (keys) {
415
+ setState(function (prev) { return (__assign(__assign({}, prev), { selectedRowKeys: keys })); });
416
+ },
417
+ /** 滚动到指定位置 */
418
+ scrollTo: function (params) {
419
+ setScrollState(function (prev) { return (__assign(__assign({}, prev), { scrollLeft: params.x !== undefined ? params.x : prev.scrollLeft, scrollTop: params.y !== undefined ? params.y : prev.scrollTop })); });
420
+ },
421
+ /** 获取当前排序状态 */
422
+ getSortState: function () {
423
+ return {
424
+ field: state.sortField,
425
+ order: state.sortOrder,
426
+ };
427
+ },
428
+ /** 获取当前过滤状态 */
429
+ getFilterState: function () {
430
+ return state.filters;
431
+ },
432
+ /** 清除排序 */
433
+ clearSort: function () {
434
+ setState(function (prev) { return (__assign(__assign({}, prev), { sortField: null, sortOrder: null })); });
435
+ },
436
+ /** 清除过滤 */
437
+ clearFilter: function () {
438
+ setState(function (prev) { return (__assign(__assign({}, prev), { filters: {} })); });
439
+ },
440
+ }); }, [
441
+ currentDynamicList,
442
+ dynamicSettingRef,
443
+ exportExcel,
444
+ state.selectedRowKeys,
445
+ state.sortField,
446
+ state.sortOrder,
447
+ state.filters,
448
+ setState,
449
+ setScrollState,
450
+ ]);
365
451
  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: {
366
452
  display: "block",
367
453
  // cursor 由 useTableInteraction 动态管理
368
454
  touchAction: "none",
369
- } }), dynamicKey ? (jsx(DynamicSetting, { parentDynamicKey: TABLE_DYNAMIC_KEY, dynamicKey: dynamicKey, defaultList: defaultDynamicList, onCurrentListChange: onCurrentListChange, ref: dynamicSettingRef, hiddenOperationIcon: true, isMore: true, isFixed: true, isDimensionDynamic: isDimensionDynamic })) : null, jsx(EmptyPlaceholder, { visible: finalDataSource.length === 0, text: emptyText, headerHeight: calculatedHeaderHeight }), jsx(HeaderOverlay, { overlays: headerOverlays }), jsx(CellOverlay, { overlays: cellOverlays }), filterPopoverElement, jsx(Tooltip, { visible: state.tooltip.visible, content: state.tooltip.content, position: state.tooltip.position }), jsx(BadgePopover, { visible: state.badgePopover.visible, content: state.badgePopover.content, position: state.badgePopover.position, popoverRef: badgePopoverRef }), menuId ? (jsx(CanvasTableMenu, { menuId: menuId, containerRef: containerRef, isFullscreenHandle: isFullscreenHandle, tableMenuRef: tableMenuRef, onCopy: handleCopy, onExport: dynamicKey ? exportExcel : undefined })) : null] })) })));
455
+ // 优化文本渲染 - 使用系统级文本渲染优化
456
+ fontSmooth: "always",
457
+ WebkitFontSmoothing: "antialiased",
458
+ MozOsxFontSmoothing: "grayscale",
459
+ textRendering: "optimizeLegibility",
460
+ } }), dynamicKey ? (jsx(DynamicSetting, { parentDynamicKey: TABLE_DYNAMIC_KEY, dynamicKey: dynamicKey, defaultList: defaultDynamicList, onCurrentListChange: onCurrentListChange, ref: dynamicSettingRef, hiddenOperationIcon: true, isMore: true, isFixed: true, isDimensionDynamic: isDimensionDynamic })) : null, jsx(EmptyPlaceholder, { visible: finalDataSource.length === 0, text: emptyText, headerHeight: calculatedHeaderHeight }), jsx(HeaderOverlay, { overlays: headerOverlays }), jsx(CellOverlay, { overlays: cellOverlays }), filterPopoverElement, jsx(Tooltip, { visible: state.tooltip.visible, content: state.tooltip.content, position: state.tooltip.position }), jsx(BadgePopover, { visible: state.badgePopover.visible, content: state.badgePopover.content, position: state.badgePopover.position, popoverRef: badgePopoverRef }), menuId ? (jsx(CanvasTableMenu, { menuId: menuId, containerRef: containerRef, isFullscreenHandle: isFullscreenHandle, tableMenuRef: tableMenuRef, onCopy: handleCopy, onExport: function () {
461
+ return exportExcel((exportExcelConfig === null || exportExcelConfig === void 0 ? void 0 : exportExcelConfig.fileName) || "表格数据.xlsx", __assign({}, exportExcelConfig));
462
+ } })) : null] })) })));
370
463
  }
371
464
 
372
465
  export { CanvasTable as default };
@@ -32,8 +32,7 @@ var CanvasTableMenu = function (_a) {
32
32
  break;
33
33
  }
34
34
  case "export": {
35
- var fileName = "\u8868\u683C\u6570\u636E_".concat(new Date().toLocaleDateString());
36
- onExport === null || onExport === void 0 ? void 0 : onExport(fileName);
35
+ onExport === null || onExport === void 0 ? void 0 : onExport();
37
36
  break;
38
37
  }
39
38
  }
@@ -1,14 +1,8 @@
1
1
  import { __spreadArray } from '../../_virtual/_tslib.js';
2
2
  import { useState, useEffect } from 'react';
3
- import { getMaxDepth } from '../utils/multiHeaderHelpers.js';
3
+ import { getMaxDepth, calculateLayerHeights } from '../utils/multiHeaderHelpers.js';
4
+ import { FONT_SIZE, FONT_FAMILY, LINE_HEIGHT, TEXT_PADDING, FILTER_ICON_WIDTH, SORT_ICON_WIDTH, ICON_SPACING } from '../utils/constants.js';
4
5
 
5
- var FONT_SIZE = 13;
6
- var FONT_FAMILY = '"Microsoft YaHei", 微软雅黑, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
7
- var LINE_HEIGHT = 20;
8
- var FILTER_ICON_WIDTH = 15;
9
- var SORT_ICON_WIDTH = 15;
10
- var ICON_SPACING = 4;
11
- var TEXT_PADDING = 16;
12
6
  /**
13
7
  * 计算文本在给定宽度下需要的行数
14
8
  */
@@ -46,12 +40,11 @@ var calculateTextLines = function (ctx, text, maxWidth) {
46
40
  /**
47
41
  * 计算单个列标题需要的行数
48
42
  */
49
- var calculateColumnLines = function (ctx, column) {
43
+ var calculateColumnLines = function (ctx, column, columnWidth) {
50
44
  if (!column.wrap || !column.title) {
51
45
  return 1;
52
46
  }
53
47
  var titleText = String(column.title);
54
- var columnWidth = column.width || 100;
55
48
  // 计算图标占用的宽度
56
49
  var hasOrder = column.isOrder !== false;
57
50
  var hasFilter = column.isFilter !== false;
@@ -69,18 +62,19 @@ var calculateColumnLines = function (ctx, column) {
69
62
  };
70
63
  /**
71
64
  * Hook: 计算表头动态高度
72
- * 支持多级表头
65
+ * 支持多级表头和文本换行
73
66
  */
74
67
  var useHeaderHeight = function (params) {
75
- var columns = params.columns, headerHeight = params.headerHeight;
68
+ var columns = params.columns, headerHeight = params.headerHeight, columnRenderInfos = params.columnRenderInfos;
76
69
  var _a = useState(headerHeight), calculatedHeight = _a[0], setCalculatedHeight = _a[1];
77
70
  useEffect(function () {
78
71
  var calculateHeight = function () {
79
72
  // 获取多级表头的最大深度
80
73
  var maxDepth = getMaxDepth(columns);
81
- // 如果是多级表头,每层使用基础表头高度
74
+ // 如果是多级表头,使用 calculateLayerHeights 计算总高度
82
75
  if (maxDepth > 1) {
83
- return headerHeight * maxDepth;
76
+ var layerHeights = calculateLayerHeights(columns, headerHeight, columnRenderInfos).layerHeights;
77
+ return layerHeights.reduce(function (sum, h) { return sum + h; }, 0);
84
78
  }
85
79
  // 单层表头,考虑文本换行
86
80
  var tempCanvas = document.createElement("canvas");
@@ -88,15 +82,20 @@ var useHeaderHeight = function (params) {
88
82
  if (!ctx)
89
83
  return headerHeight;
90
84
  ctx.font = "".concat(FONT_SIZE, "px ").concat(FONT_FAMILY);
91
- // 计算所有列需要的最大行数
92
- var maxLines = Math.max.apply(Math, __spreadArray([1], columns.map(function (column) { return calculateColumnLines(ctx, column); }), false));
93
- // 基础高度 + (额外行数 * 行高)
85
+ var maxLines = Math.max.apply(Math, __spreadArray([1], columns.map(function (column, index) {
86
+ var _a;
87
+ // 使用实际的列宽(如果有的话)
88
+ var columnWidth = ((_a = columnRenderInfos === null || columnRenderInfos === void 0 ? void 0 : columnRenderInfos[index]) === null || _a === void 0 ? void 0 : _a.width) || column.width || 100;
89
+ return calculateColumnLines(ctx, column, columnWidth);
90
+ }), false));
91
+ // 当有换行时:上边距(5px) + 行数 * 行高 + 下边距(5px)
92
+ // 当没有换行时:使用原始的 headerHeight
94
93
  return maxLines > 1
95
- ? headerHeight + (maxLines - 1) * LINE_HEIGHT
94
+ ? 10 + maxLines * LINE_HEIGHT // 上下边距各5px,共10px
96
95
  : headerHeight;
97
96
  };
98
97
  setCalculatedHeight(calculateHeight());
99
- }, [columns, headerHeight]);
98
+ }, [columns, headerHeight, columnRenderInfos]);
100
99
  return calculatedHeight;
101
100
  };
102
101
 
@@ -16,7 +16,7 @@ import '../../node_modules/screenfull/index.js';
16
16
  import ColumnDynamic from '../components/ColumnDynamic.js';
17
17
 
18
18
  var useProcessedColumns = function (params) {
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;
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, _b = params.headerAlign, headerAlign = _b === void 0 ? "center" : _b;
20
20
  return useMemo(function () {
21
21
  var cols = __spreadArray([], (dynamicColumns || columns), true);
22
22
  // 添加序号列
@@ -62,11 +62,19 @@ var useProcessedColumns = function (params) {
62
62
  }
63
63
  // 应用内部列宽状态(未开启动态配置时)
64
64
  if (!dynamicKey && Object.keys(internalColumnWidths).length > 0) {
65
- cols.forEach(function (col) {
66
- if (col.key && internalColumnWidths[col.key]) {
67
- col.width = internalColumnWidths[col.key];
68
- }
69
- });
65
+ // 递归应用列宽
66
+ var applyColumnWidths_1 = function (columns) {
67
+ columns.forEach(function (col) {
68
+ if (col.key && internalColumnWidths[col.key]) {
69
+ col.width = internalColumnWidths[col.key];
70
+ }
71
+ // 递归处理子列(多级表头)
72
+ if (col.children && col.children.length > 0) {
73
+ applyColumnWidths_1(col.children);
74
+ }
75
+ });
76
+ };
77
+ applyColumnWidths_1(cols);
70
78
  }
71
79
  // 验证动态列配置
72
80
  if (dynamicKey) {
@@ -79,7 +87,7 @@ var useProcessedColumns = function (params) {
79
87
  }
80
88
  // 处理render函数
81
89
  return cols.map(function (col) {
82
- return processColumnRender(col, renderMode, headerWrap);
90
+ return processColumnRender(col, renderMode, headerWrap, headerAlign);
83
91
  });
84
92
  }, [
85
93
  dynamicColumns,
@@ -90,6 +98,8 @@ var useProcessedColumns = function (params) {
90
98
  internalColumnWidths,
91
99
  renderMode,
92
100
  dynamicSettingRef,
101
+ headerWrap,
102
+ headerAlign,
93
103
  ]);
94
104
  };
95
105
 
@@ -22,15 +22,8 @@ var useSummaryRow = function (params) {
22
22
  if (!hasSummary)
23
23
  return null;
24
24
  var summaryRecord = {};
25
- // 找到第一个数据列(非序号列、非选择框列)
26
- var firstDataColIndex = -1;
27
- for (var i = 0; i < leafColumns.length; i++) {
28
- var col = leafColumns[i];
29
- if (col.key !== "__index__" && col.key !== "__selection__") {
30
- firstDataColIndex = i;
31
- break;
32
- }
33
- }
25
+ // 找到第一个列(包括序号列、选择框列)
26
+ var firstColIndex = leafColumns.length > 0 ? 0 : -1;
34
27
  leafColumns.forEach(function (column, colIndex) {
35
28
  var dataIndex = column.dataIndex || column.key;
36
29
  if (column.isSummary) {
@@ -60,8 +53,8 @@ var useSummaryRow = function (params) {
60
53
  }
61
54
  summaryRecord[dataIndex] = formattedSum;
62
55
  }
63
- else if (colIndex === firstDataColIndex) {
64
- // 第一个数据列显示"合计"
56
+ else if (colIndex === firstColIndex) {
57
+ // 第一列显示"合计"(可以是序号列、选择框列或数据列)
65
58
  summaryRecord[dataIndex] = "合计";
66
59
  }
67
60
  else {
@@ -187,7 +187,7 @@ var useTableInteraction = function (params) {
187
187
  var badgeProps = typeof column.badge === "function"
188
188
  ? column.badge(record)
189
189
  : column.badge;
190
- if (!badgeProps || !badgeProps.text)
190
+ if (!badgeProps)
191
191
  return false;
192
192
  // 计算单元格的位置和大小
193
193
  var cellX = fixed ? fixedLeft : colX - scrollState.scrollLeft;
@@ -198,10 +198,12 @@ var useTableInteraction = function (params) {
198
198
  // 使用工具函数判断点击位置是否在三角形区域内
199
199
  var isInTriangle = isPointInTriangle(x, y, cellX, cellY, cellWidth, cellHeight, position);
200
200
  if (isInTriangle) {
201
+ // 获取要显示的内容
202
+ var popoverContent_1 = badgeProps.title || "";
201
203
  // 如果已经显示相同内容的弹框,则关闭;否则显示新弹框
202
204
  setState(function (prev) {
203
205
  if (prev.badgePopover.visible &&
204
- prev.badgePopover.content === badgeProps.text) {
206
+ prev.badgePopover.content === popoverContent_1) {
205
207
  return __assign(__assign({}, prev), { badgePopover: {
206
208
  visible: false,
207
209
  content: "",
@@ -211,7 +213,7 @@ var useTableInteraction = function (params) {
211
213
  else {
212
214
  return __assign(__assign({}, prev), { badgePopover: {
213
215
  visible: true,
214
- content: badgeProps.text,
216
+ content: popoverContent_1,
215
217
  position: { x: clientX + 10, y: clientY + 10 },
216
218
  } });
217
219
  }