zmdms-webui 2.3.7 → 2.3.8
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 +3 -2
- package/dist/es/canvastable/components/CellOverlay.js +3 -2
- package/dist/es/canvastable/hooks/useTableRender.js +42 -42
- package/dist/es/canvastable/hooks/useTableState.js +10 -3
- package/dist/es/canvastable/interface.d.ts +1 -1
- package/dist/es/canvastable/utils/interactionHelpers.js +27 -10
- package/dist/es/table/hooks.js +3 -1
- package/dist/es/table/utils.js +135 -81
- package/package.json +1 -1
|
@@ -91,6 +91,7 @@ function CanvasTable(props) {
|
|
|
91
91
|
columns: processedColumnsOld,
|
|
92
92
|
rowSelection: rowSelection,
|
|
93
93
|
onFilterChange: onFilterChange,
|
|
94
|
+
isAutoMerge: isAutoMerge,
|
|
94
95
|
}), state = _y.state, setState = _y.setState, processedDataSource = _y.processedDataSource, handleFilterChange = _y.handleFilterChange, closeFilterPopover = _y.closeFilterPopover, autoGeneratedFilters = _y.autoGeneratedFilters;
|
|
95
96
|
var order = useMemo(function () {
|
|
96
97
|
return state.sortOrder && state.sortField
|
|
@@ -323,7 +324,7 @@ function CanvasTable(props) {
|
|
|
323
324
|
// 渲染表格
|
|
324
325
|
useTableRender(__assign(__assign({ canvasRef: canvasRef, processedDataSource: finalDataSource, columnRenderInfos: columnRenderInfos, columns: processedColumns, // 传递原始columns用于渲染多级表头
|
|
325
326
|
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 }));
|
|
327
|
+
rowHeight: rowHeight, bordered: bordered, striped: striped, headerAlign: headerAlign }, scrollbarMetrics), { getRowKey: getRowKey, resizeState: resizeState, getColumnWidth: getColumnWidth, RESIZE_HANDLE_WIDTH: RESIZE_HANDLE_WIDTH, mergeCellMap: mergeCellMap, hasSummaryRow: hasSummaryRow, fixedRowsCount: fixedRowsCount, fixedRowsConfig: fixedRowsConfig, summaryFixed: summaryFixed }));
|
|
327
328
|
// 单元格覆盖层
|
|
328
329
|
var cellOverlays = useTableCellOverlay({
|
|
329
330
|
canvasRef: canvasRef,
|
|
@@ -458,7 +459,7 @@ function CanvasTable(props) {
|
|
|
458
459
|
MozOsxFontSmoothing: "grayscale",
|
|
459
460
|
textRendering: "optimizeLegibility",
|
|
460
461
|
} }), 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",
|
|
462
|
+
return exportExcel((exportExcelConfig === null || exportExcelConfig === void 0 ? void 0 : exportExcelConfig.fileName) || "表格数据.xlsx", exportExcelConfig);
|
|
462
463
|
} })) : null] })) })));
|
|
463
464
|
}
|
|
464
465
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { __assign } from '../../_virtual/_tslib.js';
|
|
2
2
|
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { TEXT_PADDING } from '../utils/constants.js';
|
|
3
4
|
|
|
4
5
|
var CellOverlay = function (_a) {
|
|
5
6
|
var overlays = _a.overlays;
|
|
@@ -27,9 +28,9 @@ var CellOverlay = function (_a) {
|
|
|
27
28
|
})(), // 根据固定列和固定行设置 z-index
|
|
28
29
|
} }, { children: jsx("div", __assign({ className: "canvas-table-cell-content", style: {
|
|
29
30
|
position: "absolute",
|
|
30
|
-
left: -overlay.offsetLeft +
|
|
31
|
+
left: -overlay.offsetLeft + TEXT_PADDING,
|
|
31
32
|
top: -overlay.offsetTop,
|
|
32
|
-
width: overlay.originalWidth -
|
|
33
|
+
width: overlay.originalWidth - TEXT_PADDING * 2,
|
|
33
34
|
height: overlay.originalHeight,
|
|
34
35
|
display: "flex",
|
|
35
36
|
alignItems: "center",
|
|
@@ -8,7 +8,7 @@ import 'react/jsx-runtime';
|
|
|
8
8
|
import 'zmdms-utils';
|
|
9
9
|
import '../../node_modules/exceljs/dist/exceljs.min.js';
|
|
10
10
|
import 'dayjs';
|
|
11
|
-
import { COLORS, FONT_WEIGHT, FONT_SIZE, FONT_FAMILY, SCROLLBAR_SIZE, SCROLLBAR_PADDING } from '../utils/constants.js';
|
|
11
|
+
import { COLORS, FONT_WEIGHT, FONT_SIZE, FONT_FAMILY, TEXT_PADDING, SCROLLBAR_SIZE, SCROLLBAR_PADDING } from '../utils/constants.js';
|
|
12
12
|
import { drawCheckbox, wrapText, truncateText, drawFilterIcon, drawSortIcon } from '../utils/canvasDrawHelpers.js';
|
|
13
13
|
import { getMaxDepth, flattenHeaders, calculateLayerHeights, getLeafColumns } from '../utils/multiHeaderHelpers.js';
|
|
14
14
|
import { extractCellText } from '../utils/cellHelpers.js';
|
|
@@ -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, baseHeaderHeight = params.baseHeaderHeight, 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,
|
|
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, baseHeaderHeight = params.baseHeaderHeight, rowHeight = params.rowHeight, bordered = params.bordered, striped = params.striped, _a = params.headerAlign, headerAlign = _a === void 0 ? "center" : _a, 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, _b = params.RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_WIDTH = _b === void 0 ? 8 : _b, mergeCellMap = params.mergeCellMap, _c = params.hasSummaryRow, hasSummaryRow = _c === void 0 ? false : _c, fixedRowsCount = params.fixedRowsCount, fixedRowsConfig = params.fixedRowsConfig, _d = params.summaryFixed, summaryFixed = _d === void 0 ? false : _d;
|
|
23
23
|
// 判断是否是多级表头
|
|
24
24
|
var maxDepth = useMemo(function () { return getMaxDepth(columns); }, [columns]);
|
|
25
25
|
var isMultiHeader = maxDepth > 1;
|
|
@@ -27,13 +27,13 @@ var useTableRender = function (params) {
|
|
|
27
27
|
var flattenedHeaderRows = useMemo(function () { return (isMultiHeader ? flattenHeaders(columns) : []); }, [columns, isMultiHeader]);
|
|
28
28
|
// 计算多级表头每一层的高度(考虑换行)
|
|
29
29
|
// 使用 baseHeaderHeight 或默认计算出的基础高度
|
|
30
|
-
var
|
|
30
|
+
var _e = useMemo(function () {
|
|
31
31
|
var maxDepth = getMaxDepth(columns);
|
|
32
32
|
// 如果提供了 baseHeaderHeight,使用它;否则根据 headerHeight 和深度计算
|
|
33
33
|
var baseHeight = baseHeaderHeight ||
|
|
34
34
|
(maxDepth > 1 ? Math.floor(headerHeight / maxDepth) : headerHeight);
|
|
35
35
|
return calculateLayerHeights(columns, baseHeight, columnRenderInfos);
|
|
36
|
-
}, [columns, headerHeight, baseHeaderHeight, columnRenderInfos]), layerHeights =
|
|
36
|
+
}, [columns, headerHeight, baseHeaderHeight, columnRenderInfos]), layerHeights = _e.layerHeights, layerStartY = _e.layerStartY;
|
|
37
37
|
var dpr = window.devicePixelRatio || 1;
|
|
38
38
|
// ==================== 通用辅助函数 ====================
|
|
39
39
|
/**
|
|
@@ -141,8 +141,8 @@ var useTableRender = function (params) {
|
|
|
141
141
|
else {
|
|
142
142
|
// 计算图标占用的宽度
|
|
143
143
|
var iconArea = calculateIconArea(column, width);
|
|
144
|
-
// 确定表头对齐方式,优先使用列的 headerAlign
|
|
145
|
-
var
|
|
144
|
+
// 确定表头对齐方式,优先使用列的 headerAlign,其次是全局 headerAlign
|
|
145
|
+
var columnHeaderAlign = column.headerAlign || headerAlign;
|
|
146
146
|
// 绘制文本(如果 title 是 React 元素,跳过Canvas渲染,在覆盖层中渲染)
|
|
147
147
|
if (!isValidElement(column.title)) {
|
|
148
148
|
var titleText = String(column.title || "");
|
|
@@ -150,39 +150,39 @@ var useTableRender = function (params) {
|
|
|
150
150
|
var textX_1;
|
|
151
151
|
var textMaxWidth = void 0;
|
|
152
152
|
if (iconArea.iconsWidth > 0) {
|
|
153
|
-
// 有图标时,根据
|
|
154
|
-
if (
|
|
153
|
+
// 有图标时,根据columnHeaderAlign调整文本位置和最大宽度
|
|
154
|
+
if (columnHeaderAlign === "right") {
|
|
155
155
|
ctx.textAlign = "right";
|
|
156
|
-
textX_1 = drawX + width -
|
|
157
|
-
textMaxWidth = width -
|
|
156
|
+
textX_1 = drawX + width - TEXT_PADDING - iconArea.iconsWidth;
|
|
157
|
+
textMaxWidth = width - TEXT_PADDING * 2 - iconArea.iconsWidth;
|
|
158
158
|
}
|
|
159
|
-
else if (
|
|
159
|
+
else if (columnHeaderAlign === "center") {
|
|
160
160
|
ctx.textAlign = "center";
|
|
161
161
|
textX_1 = drawX + (width - iconArea.iconsWidth) / 2;
|
|
162
|
-
textMaxWidth = width -
|
|
162
|
+
textMaxWidth = width - TEXT_PADDING * 2 - iconArea.iconsWidth;
|
|
163
163
|
}
|
|
164
164
|
else {
|
|
165
165
|
ctx.textAlign = "left";
|
|
166
|
-
textX_1 = drawX +
|
|
167
|
-
textMaxWidth = width -
|
|
166
|
+
textX_1 = drawX + TEXT_PADDING;
|
|
167
|
+
textMaxWidth = width - TEXT_PADDING - iconArea.iconsWidth;
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
else {
|
|
171
|
-
// 没有图标时,根据
|
|
172
|
-
if (
|
|
171
|
+
// 没有图标时,根据columnHeaderAlign设置对齐方式
|
|
172
|
+
if (columnHeaderAlign === "left") {
|
|
173
173
|
ctx.textAlign = "left";
|
|
174
|
-
textX_1 = drawX +
|
|
175
|
-
textMaxWidth = width -
|
|
174
|
+
textX_1 = drawX + TEXT_PADDING;
|
|
175
|
+
textMaxWidth = width - TEXT_PADDING * 2;
|
|
176
176
|
}
|
|
177
|
-
else if (
|
|
177
|
+
else if (columnHeaderAlign === "right") {
|
|
178
178
|
ctx.textAlign = "right";
|
|
179
|
-
textX_1 = drawX + width -
|
|
180
|
-
textMaxWidth = width -
|
|
179
|
+
textX_1 = drawX + width - TEXT_PADDING;
|
|
180
|
+
textMaxWidth = width - TEXT_PADDING * 2;
|
|
181
181
|
}
|
|
182
182
|
else {
|
|
183
183
|
ctx.textAlign = "center";
|
|
184
184
|
textX_1 = drawX + width / 2;
|
|
185
|
-
textMaxWidth = width -
|
|
185
|
+
textMaxWidth = width - TEXT_PADDING * 2;
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
// 根据 ellipsis 和 wrap 属性处理文本
|
|
@@ -325,27 +325,27 @@ var useTableRender = function (params) {
|
|
|
325
325
|
var iconArea = shouldShowIcons
|
|
326
326
|
? calculateIconArea(column, width)
|
|
327
327
|
: { hasOrder: false, hasFilter: false, iconsWidth: 0 };
|
|
328
|
-
// 确定表头对齐方式,优先使用列的 headerAlign
|
|
329
|
-
var
|
|
328
|
+
// 确定表头对齐方式,优先使用列的 headerAlign,其次是全局 headerAlign
|
|
329
|
+
var columnHeaderAlign = column.headerAlign || headerAlign;
|
|
330
330
|
// 如果是最末级且有图标,需要调整对齐方式
|
|
331
331
|
if (isLastLevel && iconArea.iconsWidth > 0) {
|
|
332
|
-
// 有图标时,根据
|
|
332
|
+
// 有图标时,根据columnHeaderAlign调整文本位置和最大宽度
|
|
333
333
|
var textX_2;
|
|
334
334
|
var textMaxWidth = void 0;
|
|
335
|
-
if (
|
|
335
|
+
if (columnHeaderAlign === "right") {
|
|
336
336
|
ctx.textAlign = "right";
|
|
337
|
-
textX_2 = drawX + width -
|
|
338
|
-
textMaxWidth = width -
|
|
337
|
+
textX_2 = drawX + width - TEXT_PADDING - iconArea.iconsWidth;
|
|
338
|
+
textMaxWidth = width - TEXT_PADDING * 2 - iconArea.iconsWidth;
|
|
339
339
|
}
|
|
340
|
-
else if (
|
|
340
|
+
else if (columnHeaderAlign === "center") {
|
|
341
341
|
ctx.textAlign = "center";
|
|
342
342
|
textX_2 = drawX + (width - iconArea.iconsWidth) / 2;
|
|
343
|
-
textMaxWidth = width -
|
|
343
|
+
textMaxWidth = width - TEXT_PADDING * 2 - iconArea.iconsWidth;
|
|
344
344
|
}
|
|
345
345
|
else {
|
|
346
346
|
ctx.textAlign = "left";
|
|
347
|
-
textX_2 = drawX +
|
|
348
|
-
textMaxWidth = width -
|
|
347
|
+
textX_2 = drawX + TEXT_PADDING;
|
|
348
|
+
textMaxWidth = width - TEXT_PADDING - iconArea.iconsWidth;
|
|
349
349
|
}
|
|
350
350
|
// 根据 wrap 属性处理文本
|
|
351
351
|
if (column.wrap) {
|
|
@@ -364,15 +364,15 @@ var useTableRender = function (params) {
|
|
|
364
364
|
}
|
|
365
365
|
}
|
|
366
366
|
else {
|
|
367
|
-
// 没有图标时,根据
|
|
367
|
+
// 没有图标时,根据columnHeaderAlign设置对齐方式
|
|
368
368
|
var textX_3;
|
|
369
|
-
if (
|
|
369
|
+
if (columnHeaderAlign === "left") {
|
|
370
370
|
ctx.textAlign = "left";
|
|
371
|
-
textX_3 = drawX +
|
|
371
|
+
textX_3 = drawX + TEXT_PADDING;
|
|
372
372
|
}
|
|
373
|
-
else if (
|
|
373
|
+
else if (columnHeaderAlign === "right") {
|
|
374
374
|
ctx.textAlign = "right";
|
|
375
|
-
textX_3 = drawX + width -
|
|
375
|
+
textX_3 = drawX + width - TEXT_PADDING;
|
|
376
376
|
}
|
|
377
377
|
else {
|
|
378
378
|
ctx.textAlign = "center";
|
|
@@ -381,7 +381,7 @@ var useTableRender = function (params) {
|
|
|
381
381
|
// 根据 wrap 属性处理文本
|
|
382
382
|
if (column.wrap) {
|
|
383
383
|
// 换行显示(支持\n和自动换行)
|
|
384
|
-
var lines = wrapText(ctx, titleText, width -
|
|
384
|
+
var lines = wrapText(ctx, titleText, width - TEXT_PADDING * 2); // 左右各TEXT_PADDING
|
|
385
385
|
var lineHeight_3 = FONT_SIZE + 5; // 字体大小 + 行间距5px
|
|
386
386
|
var startY_3 = textY - ((lines.length - 1) * lineHeight_3) / 2;
|
|
387
387
|
lines.forEach(function (line, index) {
|
|
@@ -390,7 +390,7 @@ var useTableRender = function (params) {
|
|
|
390
390
|
});
|
|
391
391
|
}
|
|
392
392
|
else {
|
|
393
|
-
var truncated = truncateText(ctx, titleText, width -
|
|
393
|
+
var truncated = truncateText(ctx, titleText, width - TEXT_PADDING * 2); // 左右各TEXT_PADDING
|
|
394
394
|
ctx.fillText(truncated, textX_3, textY);
|
|
395
395
|
}
|
|
396
396
|
}
|
|
@@ -672,20 +672,20 @@ var useTableRender = function (params) {
|
|
|
672
672
|
: "".concat(FONT_WEIGHT, " ").concat(FONT_SIZE, "px ").concat(FONT_FAMILY);
|
|
673
673
|
ctx.textBaseline = "middle";
|
|
674
674
|
var align = column.align || "left";
|
|
675
|
-
var textX_4 = drawX +
|
|
675
|
+
var textX_4 = drawX + TEXT_PADDING;
|
|
676
676
|
if (align === "center") {
|
|
677
677
|
ctx.textAlign = "center";
|
|
678
678
|
textX_4 = drawX + width / 2;
|
|
679
679
|
}
|
|
680
680
|
else if (align === "right") {
|
|
681
681
|
ctx.textAlign = "right";
|
|
682
|
-
textX_4 = drawX + width -
|
|
682
|
+
textX_4 = drawX + width - TEXT_PADDING;
|
|
683
683
|
}
|
|
684
684
|
else {
|
|
685
685
|
ctx.textAlign = "left";
|
|
686
686
|
}
|
|
687
687
|
// 处理文本显示(ellipsis 或 wrap)
|
|
688
|
-
var maxWidth = width -
|
|
688
|
+
var maxWidth = width - TEXT_PADDING * 2; // 左右各TEXT_PADDING
|
|
689
689
|
var ellipsis = column.ellipsis !== false; // 默认为true
|
|
690
690
|
var wrap = column.wrap === true; // 默认为false
|
|
691
691
|
if (wrap) {
|
|
@@ -9,7 +9,7 @@ import { getAllLeafColumns, findColumnByKey } from '../utils/columnHelpers.js';
|
|
|
9
9
|
* 表格状态管理 Hook
|
|
10
10
|
*/
|
|
11
11
|
var useTableState = function (params) {
|
|
12
|
-
var dataSource = params.dataSource, columns = params.columns, rowSelection = params.rowSelection, onFilterChange = params.onFilterChange;
|
|
12
|
+
var dataSource = params.dataSource, columns = params.columns, rowSelection = params.rowSelection, onFilterChange = params.onFilterChange, isAutoMerge = params.isAutoMerge;
|
|
13
13
|
// 表格状态
|
|
14
14
|
var _a = useState({
|
|
15
15
|
sortField: null,
|
|
@@ -157,7 +157,7 @@ var useTableState = function (params) {
|
|
|
157
157
|
}
|
|
158
158
|
});
|
|
159
159
|
// 应用排序
|
|
160
|
-
if (state.sortField && state.sortOrder) {
|
|
160
|
+
if (state.sortField && state.sortOrder && !isAutoMerge) {
|
|
161
161
|
var column_2 = findColumnByKey(columns, state.sortField);
|
|
162
162
|
if (column_2 && column_2.isOrder !== false) {
|
|
163
163
|
var sortFn_1 = typeof column_2.sorter === "function"
|
|
@@ -187,7 +187,14 @@ var useTableState = function (params) {
|
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
189
|
return data;
|
|
190
|
-
}, [
|
|
190
|
+
}, [
|
|
191
|
+
dataSource,
|
|
192
|
+
columns,
|
|
193
|
+
state.filters,
|
|
194
|
+
state.sortField,
|
|
195
|
+
state.sortOrder,
|
|
196
|
+
isAutoMerge,
|
|
197
|
+
]);
|
|
191
198
|
// 处理过滤变化
|
|
192
199
|
var handleFilterChange = useMemoizedFn(function (columnKey, values) {
|
|
193
200
|
var _a;
|
|
@@ -405,7 +405,7 @@ interface ICanvasTableProps<RecordType = any> {
|
|
|
405
405
|
/**
|
|
406
406
|
* 表格ref句柄,用于暴露表格的一些方法
|
|
407
407
|
*/
|
|
408
|
-
tableRefHandle?: React__default.Ref<ICanvasTableRefHandle>;
|
|
408
|
+
tableRefHandle?: React__default.Ref<ICanvasTableRefHandle | undefined>;
|
|
409
409
|
/**
|
|
410
410
|
* 导出excel的一些配置
|
|
411
411
|
*/
|
|
@@ -104,26 +104,43 @@ var toggleSelectAll = function (dataSource, isAllSelected, getRowKey, getCheckbo
|
|
|
104
104
|
};
|
|
105
105
|
/**
|
|
106
106
|
* 处理排序点击
|
|
107
|
+
* 优化后的逻辑:
|
|
108
|
+
* - 点击上箭头:升序 → 降序 → 取消排序 → 升序...(循环)
|
|
109
|
+
* - 点击下箭头:降序 → 升序 → 取消排序 → 降序...(循环)
|
|
107
110
|
*/
|
|
108
111
|
var handleSortClick = function (clickedUpper, currentSortField, currentSortOrder, columnKey) {
|
|
109
112
|
var newOrder = null;
|
|
113
|
+
// 判断当前列是否已经是排序列
|
|
114
|
+
var isCurrentColumn = currentSortField === columnKey;
|
|
110
115
|
if (clickedUpper) {
|
|
111
|
-
//
|
|
112
|
-
if (
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
+
// 点击上箭头的循环逻辑:升序 → 降序 → 取消排序
|
|
117
|
+
if (!isCurrentColumn || currentSortOrder === null) {
|
|
118
|
+
// 没有排序或不是当前列,设置为升序
|
|
116
119
|
newOrder = "ascend";
|
|
117
120
|
}
|
|
121
|
+
else if (currentSortOrder === "ascend") {
|
|
122
|
+
// 已经是升序,切换到降序
|
|
123
|
+
newOrder = "descend";
|
|
124
|
+
}
|
|
125
|
+
else if (currentSortOrder === "descend") {
|
|
126
|
+
// 已经是降序,取消排序
|
|
127
|
+
newOrder = null;
|
|
128
|
+
}
|
|
118
129
|
}
|
|
119
130
|
else {
|
|
120
|
-
//
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
131
|
+
// 点击下箭头的循环逻辑:降序 → 升序 → 取消排序
|
|
132
|
+
if (!isCurrentColumn || currentSortOrder === null) {
|
|
133
|
+
// 没有排序或不是当前列,设置为降序
|
|
125
134
|
newOrder = "descend";
|
|
126
135
|
}
|
|
136
|
+
else if (currentSortOrder === "descend") {
|
|
137
|
+
// 已经是降序,切换到升序
|
|
138
|
+
newOrder = "ascend";
|
|
139
|
+
}
|
|
140
|
+
else if (currentSortOrder === "ascend") {
|
|
141
|
+
// 已经是升序,取消排序
|
|
142
|
+
newOrder = null;
|
|
143
|
+
}
|
|
127
144
|
}
|
|
128
145
|
return {
|
|
129
146
|
sortField: newOrder ? columnKey : null,
|
package/dist/es/table/hooks.js
CHANGED
|
@@ -423,7 +423,8 @@ function useAutoMerge(dataSource, columns, _a) {
|
|
|
423
423
|
if (!mergeKeys)
|
|
424
424
|
return dataSource;
|
|
425
425
|
else {
|
|
426
|
-
var newDataSource_2 = flattenRecordsOptimized(__spreadArray([], (dataSource || []), true), mergeKeys, dimensionSummaryKeys, summaryKeys, isDimensionDynamic, order, dimensionCustomSumKeys
|
|
426
|
+
var newDataSource_2 = flattenRecordsOptimized(__spreadArray([], (dataSource || []), true), mergeKeys, dimensionSummaryKeys, summaryKeys, isDimensionDynamic, order, dimensionCustomSumKeys, columns // 添加 columns 参数,支持自定义排序
|
|
427
|
+
);
|
|
427
428
|
return newDataSource_2;
|
|
428
429
|
}
|
|
429
430
|
}
|
|
@@ -436,6 +437,7 @@ function useAutoMerge(dataSource, columns, _a) {
|
|
|
436
437
|
isDimensionDynamic,
|
|
437
438
|
order,
|
|
438
439
|
dimensionCustomSumKeys,
|
|
440
|
+
columns, // 添加 columns 依赖
|
|
439
441
|
]);
|
|
440
442
|
var newColumns = useMemo(function () {
|
|
441
443
|
var _columns = columns;
|
package/dist/es/table/utils.js
CHANGED
|
@@ -449,7 +449,7 @@ function startColumnInsertTableData(options) {
|
|
|
449
449
|
* @param summaryKeys 合计字段
|
|
450
450
|
* @param isDimensionDynamic 维度合并
|
|
451
451
|
*/
|
|
452
|
-
function flattenRecordsOptimized(records, mergeKeys, dimensionSummaryKeys, summaryKeys, isDimensionDynamic, order, dimensionCustomSumKeys) {
|
|
452
|
+
function flattenRecordsOptimized(records, mergeKeys, dimensionSummaryKeys, summaryKeys, isDimensionDynamic, order, dimensionCustomSumKeys, columns) {
|
|
453
453
|
var _a;
|
|
454
454
|
if (!records ||
|
|
455
455
|
records.length === 0 ||
|
|
@@ -461,7 +461,7 @@ function flattenRecordsOptimized(records, mergeKeys, dimensionSummaryKeys, summa
|
|
|
461
461
|
var result = [];
|
|
462
462
|
// 如果order没有排序方向,但isDimensionDynamic为true,则按维度字段排序
|
|
463
463
|
if (isDimensionDynamic) {
|
|
464
|
-
result = sortByDimensions(__spreadArray([], records, true), mergeKeys);
|
|
464
|
+
result = sortByDimensions(__spreadArray([], records, true), mergeKeys, undefined, columns);
|
|
465
465
|
}
|
|
466
466
|
// 否则保持原样
|
|
467
467
|
else {
|
|
@@ -478,6 +478,7 @@ function flattenRecordsOptimized(records, mergeKeys, dimensionSummaryKeys, summa
|
|
|
478
478
|
// 开启自定义维度后因为最后一个维度字段会合并为一行,所以可以不排序最后一个维度字段
|
|
479
479
|
mergeKeys: isDimensionDynamic ? mergeKeys.slice(0, -1) : mergeKeys,
|
|
480
480
|
order: order,
|
|
481
|
+
columns: columns,
|
|
481
482
|
});
|
|
482
483
|
// 2. 首先插入维度合计行
|
|
483
484
|
if (dimensionSummaryKeys &&
|
|
@@ -579,10 +580,10 @@ function flattenRecordsOptimized(records, mergeKeys, dimensionSummaryKeys, summa
|
|
|
579
580
|
return result;
|
|
580
581
|
}
|
|
581
582
|
function sortRecords(_a) {
|
|
582
|
-
var records = _a.records, mergeKeys = _a.mergeKeys, order = _a.order;
|
|
583
|
+
var records = _a.records, mergeKeys = _a.mergeKeys, order = _a.order, columns = _a.columns;
|
|
583
584
|
var result = [];
|
|
584
585
|
if (order && order.order) {
|
|
585
|
-
result = sortByDimensions(__spreadArray([], records, true), mergeKeys, order);
|
|
586
|
+
result = sortByDimensions(__spreadArray([], records, true), mergeKeys, order, columns);
|
|
586
587
|
}
|
|
587
588
|
// 否则保持原样
|
|
588
589
|
else {
|
|
@@ -597,92 +598,145 @@ function sortRecords(_a) {
|
|
|
597
598
|
* @param dimensionKeys 维度字段
|
|
598
599
|
* @param order 排序配置
|
|
599
600
|
*/
|
|
600
|
-
function sortByDimensions(records, dimensionKeys, order) {
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
if (
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
var
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
var key = dimensionKeys[i];
|
|
611
|
-
var valueA_1 = a[key] || "";
|
|
612
|
-
var valueB_1 = b[key] || "";
|
|
613
|
-
// 字符串比较
|
|
614
|
-
if (valueA_1 < valueB_1)
|
|
615
|
-
return -1;
|
|
616
|
-
if (valueA_1 > valueB_1)
|
|
617
|
-
return 1;
|
|
618
|
-
// 如果当前字段相等,继续比较下一个字段
|
|
619
|
-
}
|
|
620
|
-
// 按排序字段进行排序
|
|
621
|
-
var valueA = a[field] || "";
|
|
622
|
-
var valueB = b[field] || "";
|
|
623
|
-
var compareResult = 0;
|
|
624
|
-
if (valueA < valueB)
|
|
625
|
-
compareResult = -1;
|
|
626
|
-
else if (valueA > valueB)
|
|
627
|
-
compareResult = 1;
|
|
628
|
-
if (compareResult !== 0) {
|
|
629
|
-
return sortOrder === "ascend" ? compareResult : -compareResult;
|
|
601
|
+
function sortByDimensions(records, dimensionKeys, order, columns) {
|
|
602
|
+
// 根据字段名查找对应的列配置
|
|
603
|
+
var findColumnByKey = function (field) {
|
|
604
|
+
if (!columns)
|
|
605
|
+
return null;
|
|
606
|
+
var findInColumns = function (cols) {
|
|
607
|
+
for (var _i = 0, cols_1 = cols; _i < cols_1.length; _i++) {
|
|
608
|
+
var col = cols_1[_i];
|
|
609
|
+
if (col.key === field || col.dataIndex === field) {
|
|
610
|
+
return col;
|
|
630
611
|
}
|
|
631
|
-
//
|
|
632
|
-
|
|
633
|
-
var
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
// 字符串比较
|
|
637
|
-
if (valueA_2 < valueB_2)
|
|
638
|
-
return -1;
|
|
639
|
-
if (valueA_2 > valueB_2)
|
|
640
|
-
return 1;
|
|
641
|
-
// 如果当前字段相等,继续比较下一个字段
|
|
612
|
+
// 如果有子列,递归查找
|
|
613
|
+
if (col.children && Array.isArray(col.children)) {
|
|
614
|
+
var found = findInColumns(col.children);
|
|
615
|
+
if (found)
|
|
616
|
+
return found;
|
|
642
617
|
}
|
|
643
618
|
}
|
|
619
|
+
return null;
|
|
620
|
+
};
|
|
621
|
+
return findInColumns(columns);
|
|
622
|
+
};
|
|
623
|
+
// 通用排序比较函数
|
|
624
|
+
var compareValues = function (valueA, valueB, order, recordA, recordB, field) {
|
|
625
|
+
// 处理 null/undefined
|
|
626
|
+
if (valueA === valueB)
|
|
627
|
+
return 0;
|
|
628
|
+
if (valueA === null || valueA === undefined)
|
|
629
|
+
return 1;
|
|
630
|
+
if (valueB === null || valueB === undefined)
|
|
631
|
+
return -1;
|
|
632
|
+
var compareResult = 0;
|
|
633
|
+
// 如果提供了字段名,尝试获取自定义排序函数
|
|
634
|
+
if (field && recordA && recordB) {
|
|
635
|
+
var column = findColumnByKey(field);
|
|
636
|
+
if (column && typeof column.sorter === "function") {
|
|
637
|
+
// 使用列配置中的自定义排序函数
|
|
638
|
+
compareResult = column.sorter(recordA, recordB);
|
|
639
|
+
}
|
|
644
640
|
else {
|
|
645
|
-
//
|
|
646
|
-
|
|
647
|
-
var key = dimensionKeys[i];
|
|
648
|
-
var valueA_3 = a[key] || "";
|
|
649
|
-
var valueB_3 = b[key] || "";
|
|
650
|
-
// 字符串比较
|
|
651
|
-
if (valueA_3 < valueB_3)
|
|
652
|
-
return -1;
|
|
653
|
-
if (valueA_3 > valueB_3)
|
|
654
|
-
return 1;
|
|
655
|
-
// 如果当前字段相等,继续比较下一个字段
|
|
656
|
-
}
|
|
657
|
-
// 最后按排序字段排序
|
|
658
|
-
var valueA = a[field] || "";
|
|
659
|
-
var valueB = b[field] || "";
|
|
660
|
-
var compareResult = 0;
|
|
661
|
-
if (valueA < valueB)
|
|
662
|
-
compareResult = -1;
|
|
663
|
-
else if (valueA > valueB)
|
|
664
|
-
compareResult = 1;
|
|
665
|
-
if (compareResult !== 0) {
|
|
666
|
-
return sortOrder === "ascend" ? compareResult : -compareResult;
|
|
667
|
-
}
|
|
641
|
+
// 使用默认排序逻辑
|
|
642
|
+
compareResult = getDefaultCompareResult(valueA, valueB);
|
|
668
643
|
}
|
|
669
644
|
}
|
|
670
645
|
else {
|
|
671
|
-
//
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
646
|
+
// 使用默认排序逻辑
|
|
647
|
+
compareResult = getDefaultCompareResult(valueA, valueB);
|
|
648
|
+
}
|
|
649
|
+
return compareResult !== 0
|
|
650
|
+
? order === "ascend"
|
|
651
|
+
? compareResult
|
|
652
|
+
: -compareResult
|
|
653
|
+
: 0;
|
|
654
|
+
};
|
|
655
|
+
// 默认排序比较逻辑
|
|
656
|
+
var getDefaultCompareResult = function (valueA, valueB) {
|
|
657
|
+
// 数字比较
|
|
658
|
+
if (typeof valueA === "number" && typeof valueB === "number") {
|
|
659
|
+
return valueA - valueB;
|
|
660
|
+
}
|
|
661
|
+
// 字符串比较(使用 localeCompare 支持中文等)
|
|
662
|
+
else {
|
|
663
|
+
return String(valueA).localeCompare(String(valueB), "zh-CN", {
|
|
664
|
+
numeric: true,
|
|
665
|
+
sensitivity: "base", // 忽略大小写和重音符号
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
// 通用的分层分组函数
|
|
670
|
+
var groupByDimensionsHierarchical = function (data, dimensions, currentDimensionIndex, sortConfig) {
|
|
671
|
+
if (currentDimensionIndex === void 0) { currentDimensionIndex = 0; }
|
|
672
|
+
if (currentDimensionIndex >= dimensions.length) {
|
|
673
|
+
// 到达叶子节点,如果排序字段不是维度字段,在这里排序
|
|
674
|
+
if (sortConfig && !dimensions.includes(sortConfig.field)) {
|
|
675
|
+
return data.sort(function (a, b) {
|
|
676
|
+
var valueA = a[sortConfig.field];
|
|
677
|
+
var valueB = b[sortConfig.field];
|
|
678
|
+
return compareValues(valueA, valueB, sortConfig.order, a, b, sortConfig.field);
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
else {
|
|
682
|
+
// 无排序配置或排序字段是维度字段,直接返回
|
|
683
|
+
return data;
|
|
682
684
|
}
|
|
683
685
|
}
|
|
684
|
-
|
|
685
|
-
|
|
686
|
+
var currentDimension = dimensions[currentDimensionIndex];
|
|
687
|
+
// 按当前维度分组,同时记录原始值用于排序
|
|
688
|
+
var groupData = new Map();
|
|
689
|
+
var groupOrder = []; // 记录分组出现的顺序
|
|
690
|
+
data.forEach(function (item) {
|
|
691
|
+
var value = item[currentDimension];
|
|
692
|
+
var key = String(value || "");
|
|
693
|
+
if (!groupData.has(key)) {
|
|
694
|
+
groupData.set(key, { items: [], originalValue: value });
|
|
695
|
+
groupOrder.push(key); // 记录第一次出现的顺序
|
|
696
|
+
}
|
|
697
|
+
groupData.get(key).items.push(item);
|
|
698
|
+
});
|
|
699
|
+
// 如果当前维度是排序字段,对分组的key进行排序
|
|
700
|
+
var finalGroupOrder = groupOrder;
|
|
701
|
+
if (sortConfig && sortConfig.field === currentDimension) {
|
|
702
|
+
finalGroupOrder = __spreadArray([], groupOrder, true).sort(function (keyA, keyB) {
|
|
703
|
+
// 使用保存的原始值进行比较
|
|
704
|
+
var valueA = groupData.get(keyA).originalValue;
|
|
705
|
+
var valueB = groupData.get(keyB).originalValue;
|
|
706
|
+
// 获取对应的记录用于自定义排序
|
|
707
|
+
var recordA = groupData.get(keyA).items[0];
|
|
708
|
+
var recordB = groupData.get(keyB).items[0];
|
|
709
|
+
return compareValues(valueA, valueB, sortConfig.order, recordA, recordB, sortConfig.field);
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
// 递归处理每个分组的子维度,并按排序后的顺序合并结果
|
|
713
|
+
var result = [];
|
|
714
|
+
for (var _i = 0, finalGroupOrder_1 = finalGroupOrder; _i < finalGroupOrder_1.length; _i++) {
|
|
715
|
+
var groupKey = finalGroupOrder_1[_i];
|
|
716
|
+
var group = groupData.get(groupKey);
|
|
717
|
+
var sortedGroupData = groupByDimensionsHierarchical(group.items, dimensions, currentDimensionIndex + 1, sortConfig);
|
|
718
|
+
result.push.apply(result, sortedGroupData);
|
|
719
|
+
}
|
|
720
|
+
return result;
|
|
721
|
+
};
|
|
722
|
+
// 根据是否有排序配置调用分组函数
|
|
723
|
+
var sortConfig;
|
|
724
|
+
if (order && order.order && order.field) {
|
|
725
|
+
// 如果有明确的排序配置,使用它
|
|
726
|
+
sortConfig = { field: order.field, order: order.order };
|
|
727
|
+
}
|
|
728
|
+
else {
|
|
729
|
+
// 如果没有明确排序,检查维度字段是否有自定义sorter,优先使用第一个有sorter的字段
|
|
730
|
+
for (var _i = 0, dimensionKeys_1 = dimensionKeys; _i < dimensionKeys_1.length; _i++) {
|
|
731
|
+
var dimensionKey = dimensionKeys_1[_i];
|
|
732
|
+
var column = findColumnByKey(dimensionKey);
|
|
733
|
+
if (column && typeof column.sorter === "function") {
|
|
734
|
+
sortConfig = { field: dimensionKey, order: "ascend" };
|
|
735
|
+
break; // 找到第一个有sorter的字段就使用,按维度顺序优先
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
return groupByDimensionsHierarchical(records, dimensionKeys, 0, sortConfig);
|
|
686
740
|
}
|
|
687
741
|
/**
|
|
688
742
|
* 插入维度合计行
|