zmdms-webui 2.6.1 → 2.6.3

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.
@@ -13,6 +13,7 @@ import HeaderOverlay from './components/HeaderOverlay.js';
13
13
  import { useContextMenu as Fe } from '../node_modules/react-contexify/dist/index.js';
14
14
  import { useTableState } from './hooks/useTableState.js';
15
15
  import { useTableSelection } from './hooks/useTableSelection.js';
16
+ import { useExpandable } from './hooks/useExpandable.js';
16
17
  import { useTableRender } from './hooks/useTableRender.js';
17
18
  import { useTableInteraction } from './hooks/useTableInteraction.js';
18
19
  import { useScrollbarMetrics, useTableScroll, useScrollReset } from './hooks/useScroll.js';
@@ -39,7 +40,7 @@ import { getTableColumns } from '../table/utils.js';
39
40
  import DynamicSetting from '../dynamicsetting/dynamicSetting.js';
40
41
 
41
42
  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, mode = props.mode, dynamicKey = props.dynamicKey, dynamicVersion = props.dynamicVersion, customDynamicListHandle = props.customDynamicListHandle, isDimensionDynamic = props.isDimensionDynamic, dimensionCustomSumKeys = props.dimensionCustomSumKeys, isAutoMerge = props.isAutoMerge, _m = props.isIndexMerge, isIndexMerge = _m === void 0 ? true : _m, _o = props.isSelectionMerge, isSelectionMerge = _o === void 0 ? false : _o, _p = props.renderMode, renderMode = _p === void 0 ? "object" : _p, fixedRowsCount = props.fixedRowsCount, fixedRowsConfig = props.fixedRowsConfig, _q = props.summaryFixed, summaryFixed = _q === void 0 ? false : _q, _r = props.isAutoScrollY, isAutoScrollY = _r === void 0 ? false : _r, _s = props.autoScrollYMarginBottom, autoScrollYMarginBottom = _s === void 0 ? 65 : _s, canvasTableId = props.canvasTableId, headerWrap = props.headerWrap, _t = props.headerAlign, headerAlign = _t === void 0 ? "center" : _t, tableRefHandle = props.tableRefHandle, exportExcelConfig = props.exportExcelConfig, _u = props.maxHeight, maxHeight = _u === void 0 ? 3000 : _u;
43
+ 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, mode = props.mode, dynamicKey = props.dynamicKey, dynamicVersion = props.dynamicVersion, customDynamicListHandle = props.customDynamicListHandle, isDimensionDynamic = props.isDimensionDynamic, dimensionCustomSumKeys = props.dimensionCustomSumKeys, isAutoMerge = props.isAutoMerge, _m = props.isIndexMerge, isIndexMerge = _m === void 0 ? true : _m, _o = props.isSelectionMerge, isSelectionMerge = _o === void 0 ? false : _o, _p = props.renderMode, renderMode = _p === void 0 ? "object" : _p, fixedRowsCount = props.fixedRowsCount, fixedRowsConfig = props.fixedRowsConfig, _q = props.summaryFixed, summaryFixed = _q === void 0 ? false : _q, _r = props.isAutoScrollY, isAutoScrollY = _r === void 0 ? false : _r, _s = props.autoScrollYMarginBottom, autoScrollYMarginBottom = _s === void 0 ? 65 : _s, canvasTableId = props.canvasTableId, headerWrap = props.headerWrap, _t = props.headerAlign, headerAlign = _t === void 0 ? "center" : _t, tableRefHandle = props.tableRefHandle, exportExcelConfig = props.exportExcelConfig, _u = props.maxHeight, maxHeight = _u === void 0 ? 3000 : _u, expandable = props.expandable;
43
44
  var actualMode = "mode" in props ? mode : "index";
44
45
  var canvasRef = useRef(null);
45
46
  var containerRef = useRef(null);
@@ -94,26 +95,39 @@ function CanvasTable(props) {
94
95
  onFilterChange: onFilterChange,
95
96
  isAutoMerge: isAutoMerge,
96
97
  }), state = _y.state, setState = _y.setState, processedDataSource = _y.processedDataSource, handleFilterChange = _y.handleFilterChange, closeFilterPopover = _y.closeFilterPopover, autoGeneratedFilters = _y.autoGeneratedFilters;
98
+ // 树形展开管理
99
+ var _z = useExpandable({
100
+ dataSource: dataSource,
101
+ expandable: expandable,
102
+ rowKey: rowKey,
103
+ }), expandedKeys = _z.expandedKeys, flattenedData = _z.flattenedData, toggleExpand = _z.toggleExpand, expandRow = _z.expandRow, collapseRow = _z.collapseRow, setExpandedRowKeys = _z.setExpandedRowKeys, hasExpandable = _z.hasExpandable;
97
104
  var order = useMemo(function () {
98
105
  return state.sortOrder && state.sortField
99
106
  ? { field: state.sortField, order: state.sortOrder }
100
107
  : undefined;
101
108
  }, [state.sortOrder, state.sortField]);
102
- var _z = useAutoMerge(processedDataSource, processedColumnsOld, {
109
+ var _0 = useAutoMerge(processedDataSource, processedColumnsOld, {
103
110
  isAutoMerge: isAutoMerge,
104
111
  isDimensionDynamic: isDimensionDynamic,
105
112
  order: order,
106
113
  dimensionCustomSumKeys: dimensionCustomSumKeys,
107
- }), newDataSource = _z[0], processedColumns = _z[1];
114
+ }), newDataSource = _0[0], processedColumns = _0[1];
115
+ // 如果开启了树形展开,使用扁平化后的数据源
116
+ var expandedDataSource = useMemo(function () {
117
+ if (hasExpandable) {
118
+ return flattenedData.map(function (item) { return item.record; });
119
+ }
120
+ return newDataSource;
121
+ }, [hasExpandable, flattenedData, newDataSource]);
108
122
  // 生成合计行和最终数据源
109
- var _0 = useSummaryRow({
123
+ var _1 = useSummaryRow({
110
124
  columns: processedColumns,
111
- dataSource: newDataSource,
112
- }), finalDataSource = _0.finalDataSource, hasSummaryRow = _0.hasSummaryRow;
125
+ dataSource: expandedDataSource,
126
+ }), finalDataSource = _1.finalDataSource, hasSummaryRow = _1.hasSummaryRow;
113
127
  // 用于存储计算后的表头高度(用于自动高度的精确计算)
114
- var _1 = useState(undefined), preciseHeaderHeight = _1[0], setPreciseHeaderHeight = _1[1];
128
+ var _2 = useState(undefined), preciseHeaderHeight = _2[0], setPreciseHeaderHeight = _2[1];
115
129
  // 用于存储是否需要横向滚动条(用于自动高度的精确计算)
116
- var _2 = useState(false), needHorizontalScrollbar = _2[0], setNeedHorizontalScrollbar = _2[1];
130
+ var _3 = useState(false), needHorizontalScrollbar = _3[0], setNeedHorizontalScrollbar = _3[1];
117
131
  // 自动高度计算(需要在容器尺寸计算之前)
118
132
  var autoHeight = useCanvasTableAutoHeight(isAutoScrollY, autoScrollYMarginBottom, canvasTableId, finalDataSource.length, // 数据行数(用于 content 模式)
119
133
  headerHeight, // 表头基础高度(用于 content 模式的初始计算)
@@ -180,7 +194,7 @@ function CanvasTable(props) {
180
194
  return calculateTotalHeight(calculatedHeaderHeight, finalDataSource.length, rowHeight);
181
195
  }, [calculatedHeaderHeight, finalDataSource.length, rowHeight]);
182
196
  // 计算滚动条指标
183
- var _3 = useScrollbarMetrics({
197
+ var _4 = useScrollbarMetrics({
184
198
  containerWidth: containerWidth,
185
199
  containerHeight: containerHeight,
186
200
  totalWidth: totalWidth,
@@ -188,14 +202,14 @@ function CanvasTable(props) {
188
202
  headerHeight: calculatedHeaderHeight,
189
203
  scrollTop: 0,
190
204
  scrollLeft: 0,
191
- }), maxScrollTop = _3.maxScrollTop, maxScrollLeft = _3.maxScrollLeft;
205
+ }), maxScrollTop = _4.maxScrollTop, maxScrollLeft = _4.maxScrollLeft;
192
206
  // 滚动管理(使用预先计算的maxScrollTop和maxScrollLeft)
193
- var _4 = useTableScroll({
207
+ var _5 = useTableScroll({
194
208
  containerRef: containerRef,
195
209
  maxScrollTop: maxScrollTop,
196
210
  maxScrollLeft: maxScrollLeft,
197
211
  onScroll: onScroll,
198
- }), scrollState = _4.scrollState, setScrollState = _4.setScrollState;
212
+ }), scrollState = _5.scrollState, setScrollState = _5.setScrollState;
199
213
  // 使用 ref 保存最新的滚动位置,确保在组件卸载过程中仍能访问
200
214
  var scrollPositionRef = useRef({ x: 0, y: 0 });
201
215
  useEffect(function () {
@@ -235,12 +249,12 @@ function CanvasTable(props) {
235
249
  needHorizontalScrollbar,
236
250
  ]);
237
251
  // 单元格框选
238
- var _5 = useTableSelection({
252
+ var _6 = useTableSelection({
239
253
  state: state,
240
254
  setState: setState,
241
255
  }),
242
256
  // selectionStartRef,
243
- startSelection = _5.startSelection, updateSelection = _5.updateSelection, extendSelection = _5.extendSelection;
257
+ startSelection = _6.startSelection, updateSelection = _6.updateSelection, extendSelection = _6.extendSelection;
244
258
  // 处理列宽调整
245
259
  var handleColumnResize = useCallback(function (columnKey, newWidth) {
246
260
  var _a;
@@ -295,20 +309,20 @@ function CanvasTable(props) {
295
309
  onCurrentListChange,
296
310
  ]);
297
311
  // 列宽调整
298
- var _6 = useColumnResize({
312
+ var _7 = useColumnResize({
299
313
  columnRenderInfos: columnRenderInfos,
300
314
  containerWidth: containerWidth,
301
315
  headerHeight: calculatedHeaderHeight,
302
316
  scrollLeft: scrollState.scrollLeft,
303
317
  onColumnResize: handleColumnResize,
304
- }), resizeState = _6.resizeState, checkResizeHandle = _6.checkResizeHandle, startResize = _6.startResize, updateResize = _6.updateResize, endResize = _6.endResize, setHoverResizeColumn = _6.setHoverResizeColumn, getColumnWidth = _6.getColumnWidth, RESIZE_HANDLE_WIDTH = _6.RESIZE_HANDLE_WIDTH;
318
+ }), resizeState = _7.resizeState, checkResizeHandle = _7.checkResizeHandle, startResize = _7.startResize, updateResize = _7.updateResize, endResize = _7.endResize, setHoverResizeColumn = _7.setHoverResizeColumn, getColumnWidth = _7.getColumnWidth, RESIZE_HANDLE_WIDTH = _7.RESIZE_HANDLE_WIDTH;
305
319
  // 复制到剪贴板
306
- var _7 = useCopyToClipboard({
320
+ var _8 = useCopyToClipboard({
307
321
  cellSelection: state.cellSelection,
308
322
  processedDataSource: finalDataSource,
309
323
  columns: processedColumns,
310
324
  containerRef: containerRef,
311
- }), getSelectedCellsText = _7.getSelectedCellsText, copyToClipboard = _7.copyToClipboard;
325
+ }), getSelectedCellsText = _8.getSelectedCellsText, copyToClipboard = _8.copyToClipboard;
312
326
  // 处理右键菜单的复制操作
313
327
  var handleCopy = useCallback(function () {
314
328
  var text = getSelectedCellsText();
@@ -327,7 +341,7 @@ function CanvasTable(props) {
327
341
  summaryConfig: (exportExcelConfig === null || exportExcelConfig === void 0 ? void 0 : exportExcelConfig.isExportNoSummary) ? undefined : [],
328
342
  });
329
343
  // 交互事件处理(使用baseScrollbarMetrics的maxScrollTop/maxScrollLeft以保持稳定)
330
- var _8 = useTableInteraction({
344
+ var _9 = useTableInteraction({
331
345
  state: state,
332
346
  setState: setState,
333
347
  scrollState: scrollState,
@@ -335,6 +349,8 @@ function CanvasTable(props) {
335
349
  processedDataSource: finalDataSource,
336
350
  columnRenderInfos: columnRenderInfos,
337
351
  columns: processedColumns,
352
+ expandable: expandable,
353
+ flattenedData: flattenedData,
338
354
  rowSelection: rowSelection,
339
355
  rowHeight: rowHeight,
340
356
  headerHeight: calculatedHeaderHeight,
@@ -359,6 +375,7 @@ function CanvasTable(props) {
359
375
  onSortChange: onSortChange,
360
376
  onRowClick: onRowClick,
361
377
  getRowKey: getRowKey,
378
+ onExpand: toggleExpand,
362
379
  startSelection: startSelection,
363
380
  updateSelection: updateSelection,
364
381
  extendSelection: extendSelection,
@@ -374,11 +391,11 @@ function CanvasTable(props) {
374
391
  fixedRowsCount: fixedRowsCount,
375
392
  fixedRowsConfig: fixedRowsConfig,
376
393
  summaryFixed: summaryFixed,
377
- }), handleCanvasMouseDown = _8.handleCanvasMouseDown, handleCanvasMouseMove = _8.handleCanvasMouseMove, handleCanvasMouseUp = _8.handleCanvasMouseUp, handleCanvasMouseLeave = _8.handleCanvasMouseLeave, handleCanvasContextMenu = _8.handleCanvasContextMenu;
394
+ }), handleCanvasMouseDown = _9.handleCanvasMouseDown, handleCanvasMouseMove = _9.handleCanvasMouseMove, handleCanvasMouseUp = _9.handleCanvasMouseUp, handleCanvasMouseLeave = _9.handleCanvasMouseLeave, handleCanvasContextMenu = _9.handleCanvasContextMenu;
378
395
  // 渲染表格
379
396
  useTableRender(__assign(__assign({ canvasRef: canvasRef, processedDataSource: finalDataSource, columnRenderInfos: columnRenderInfos, columns: processedColumns, // 传递原始columns用于渲染多级表头
380
397
  state: state, scrollState: scrollState, rowSelection: rowSelection, containerWidth: containerWidth, containerHeight: containerHeight, headerHeight: calculatedHeaderHeight, baseHeaderHeight: headerHeight, // 传入原始基础高度用于计算每层高度
381
- 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 }));
398
+ 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, expandable: expandable, flattenedData: flattenedData }));
382
399
  // 单元格覆盖层
383
400
  var cellOverlays = useTableCellOverlay({
384
401
  canvasRef: canvasRef,
@@ -469,6 +486,26 @@ function CanvasTable(props) {
469
486
  setSelectedRowKeys: function (keys) {
470
487
  setState(function (prev) { return (__assign(__assign({}, prev), { selectedRowKeys: keys })); });
471
488
  },
489
+ /** 获取展开的keys */
490
+ getExpandedRowKeys: function () {
491
+ return Array.from(expandedKeys);
492
+ },
493
+ /** 设置展开的keys */
494
+ setExpandedRowKeys: function (keys) {
495
+ setExpandedRowKeys(keys);
496
+ },
497
+ /** 展开指定行 */
498
+ expandRow: function (key) {
499
+ expandRow(key);
500
+ },
501
+ /** 收起指定行 */
502
+ collapseRow: function (key) {
503
+ collapseRow(key);
504
+ },
505
+ /** 切换指定行展开状态 */
506
+ toggleExpandRow: function (key) {
507
+ toggleExpand(key);
508
+ },
472
509
  /** 滚动到指定位置 */
473
510
  scrollTo: function (params) {
474
511
  setScrollState(function (prev) { return (__assign(__assign({}, prev), { scrollLeft: params.x !== undefined ? params.x : prev.scrollLeft, scrollTop: params.y !== undefined ? params.y : prev.scrollTop })); });
@@ -510,6 +547,11 @@ function CanvasTable(props) {
510
547
  state.filters,
511
548
  setState,
512
549
  setScrollState,
550
+ expandedKeys,
551
+ setExpandedRowKeys,
552
+ expandRow,
553
+ collapseRow,
554
+ toggleExpand,
513
555
  ]);
514
556
  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: {
515
557
  display: "block",
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Badge 渲染�?
3
+ * 负责绘制单元格角标(三角形标记,类似Excel批注�?
4
+ */
5
+ var BadgeRenderer = /** @class */ (function () {
6
+ function BadgeRenderer() {
7
+ this.context = null;
8
+ }
9
+ BadgeRenderer.prototype.setContext = function (context) {
10
+ this.context = context;
11
+ };
12
+ /**
13
+ * 绘制角标
14
+ */
15
+ BadgeRenderer.prototype.render = function (badge, cellX, cellY, cellWidth, cellHeight) {
16
+ if (!this.context) {
17
+ throw new Error("BadgeRenderer: Context not set");
18
+ }
19
+ var ctx = this.context.ctx;
20
+ var triangleSize = 12; // 三角形边�?
21
+ var position = badge.position || "top-right";
22
+ var color = badge.color || "#ff4d4f";
23
+ ctx.fillStyle = color;
24
+ ctx.beginPath();
25
+ // 根据位置绘制不同方向的三角形
26
+ switch (position) {
27
+ case "top-left":
28
+ // 左上角三角形
29
+ ctx.moveTo(cellX, cellY);
30
+ ctx.lineTo(cellX + triangleSize, cellY);
31
+ ctx.lineTo(cellX, cellY + triangleSize);
32
+ break;
33
+ case "top-right":
34
+ // 右上角三角形(默认)
35
+ ctx.moveTo(cellX + cellWidth, cellY);
36
+ ctx.lineTo(cellX + cellWidth - triangleSize, cellY);
37
+ ctx.lineTo(cellX + cellWidth, cellY + triangleSize);
38
+ break;
39
+ case "bottom-left":
40
+ // 左下角三角形
41
+ ctx.moveTo(cellX, cellY + cellHeight);
42
+ ctx.lineTo(cellX, cellY + cellHeight - triangleSize);
43
+ ctx.lineTo(cellX + triangleSize, cellY + cellHeight);
44
+ break;
45
+ case "bottom-right":
46
+ // 右下角三角形
47
+ ctx.moveTo(cellX + cellWidth, cellY + cellHeight);
48
+ ctx.lineTo(cellX + cellWidth, cellY + cellHeight - triangleSize);
49
+ ctx.lineTo(cellX + cellWidth - triangleSize, cellY + cellHeight);
50
+ break;
51
+ }
52
+ ctx.closePath();
53
+ ctx.fill();
54
+ };
55
+ return BadgeRenderer;
56
+ }());
57
+
58
+ export { BadgeRenderer };
@@ -0,0 +1,229 @@
1
+ import { COLORS, SCROLLBAR_SIZE } from '../../utils/constants.js';
2
+ import 'zmdms-utils';
3
+ import 'dayjs';
4
+ import '../../../_virtual/_tslib.js';
5
+ import { calculateFixedColumnsRightEdge } from '../../utils/renderHelpers.js';
6
+
7
+ /**
8
+ * 边框渲染�?
9
+ * 负责渲染表格的所有边框(数据行、固定行、表头)
10
+ */
11
+ var BorderRenderer = /** @class */ (function () {
12
+ function BorderRenderer() {
13
+ this.context = null;
14
+ }
15
+ BorderRenderer.prototype.setContext = function (context) {
16
+ this.context = context;
17
+ };
18
+ /**
19
+ * 渲染数据行边�?
20
+ */
21
+ BorderRenderer.prototype.renderDataBorders = function (startRow, endRow, onlyFixed) {
22
+ if (onlyFixed === void 0) { onlyFixed = false; }
23
+ if (!this.context || !this.context.bordered)
24
+ return;
25
+ var _a = this.context, ctx = _a.ctx, processedDataSource = _a.processedDataSource, headerHeight = _a.headerHeight, rowHeight = _a.rowHeight, scrollState = _a.scrollState, displayWidth = _a.displayWidth, displayHeight = _a.displayHeight, needHorizontalScrollbar = _a.needHorizontalScrollbar, fixedRowsCount = _a.fixedRowsCount, fixedRowsConfig = _a.fixedRowsConfig, summaryFixed = _a.summaryFixed, hasSummaryRow = _a.hasSummaryRow, columnRenderInfos = _a.columnRenderInfos, getColumnWidth = _a.getColumnWidth, mergeCellMap = _a.mergeCellMap;
26
+ ctx.strokeStyle = COLORS.border;
27
+ ctx.lineWidth = 1;
28
+ var dataRowCount = processedDataSource.length;
29
+ // 计算固定行占用的高度
30
+ var fixedTopRowsCount = fixedRowsCount || (fixedRowsConfig === null || fixedRowsConfig === void 0 ? void 0 : fixedRowsConfig.topCount) || 0;
31
+ var fixedBottomRowsCount = (fixedRowsConfig === null || fixedRowsConfig === void 0 ? void 0 : fixedRowsConfig.bottomCount) || 0;
32
+ var fixedSummaryHeight = summaryFixed && hasSummaryRow ? rowHeight : 0;
33
+ var fixedBottomHeight = fixedBottomRowsCount * rowHeight;
34
+ // 计算可滚动数据行的数�?
35
+ var scrollableDataRowCount = dataRowCount -
36
+ fixedTopRowsCount -
37
+ fixedBottomRowsCount -
38
+ (summaryFixed && hasSummaryRow ? 1 : 0);
39
+ // 计算实际数据区域的底部位�?
40
+ var dataBottomY = Math.min(headerHeight +
41
+ fixedTopRowsCount * rowHeight +
42
+ scrollableDataRowCount * rowHeight -
43
+ scrollState.scrollTop, displayHeight -
44
+ (needHorizontalScrollbar ? SCROLLBAR_SIZE : 0) -
45
+ fixedBottomHeight -
46
+ fixedSummaryHeight);
47
+ // 绘制垂直边框
48
+ columnRenderInfos.forEach(function (info, colIndex) {
49
+ var x = info.x, width = info.width, fixed = info.fixed, fixedLeft = info.fixedLeft;
50
+ if (onlyFixed && !fixed)
51
+ return;
52
+ if (!onlyFixed && fixed)
53
+ return;
54
+ var actualWidth = getColumnWidth ? getColumnWidth(colIndex) : width;
55
+ var drawX = fixed
56
+ ? fixedLeft + actualWidth
57
+ : x + actualWidth - scrollState.scrollLeft;
58
+ if (drawX >= 0 && drawX <= displayWidth) {
59
+ ctx.beginPath();
60
+ ctx.moveTo(drawX, headerHeight);
61
+ ctx.lineTo(drawX, dataBottomY);
62
+ ctx.stroke();
63
+ }
64
+ });
65
+ // 绘制水平边框
66
+ var maxRow = Math.min(endRow, dataRowCount, fixedTopRowsCount + scrollableDataRowCount);
67
+ var _loop_1 = function (i) {
68
+ var y = headerHeight +
69
+ fixedTopRowsCount * rowHeight +
70
+ (i - fixedTopRowsCount) * rowHeight -
71
+ scrollState.scrollTop;
72
+ if (y >= headerHeight + fixedTopRowsCount * rowHeight &&
73
+ y <= dataBottomY) {
74
+ // 分段绘制,只绘制当前范围的边�?
75
+ columnRenderInfos.forEach(function (info, colIndex) {
76
+ if (onlyFixed && !info.fixed)
77
+ return;
78
+ if (!onlyFixed && info.fixed)
79
+ return;
80
+ var mergeCellKey = "".concat(i, "-").concat(colIndex);
81
+ var mergeInfo = mergeCellMap === null || mergeCellMap === void 0 ? void 0 : mergeCellMap.get(mergeCellKey);
82
+ // 只有被合并的单元格(skip=true)才跳过绘制上边�?
83
+ if (mergeInfo && mergeInfo.skip) {
84
+ return;
85
+ }
86
+ var x = info.x, width = info.width, fixed = info.fixed, fixedLeft = info.fixedLeft;
87
+ var actualWidth = getColumnWidth ? getColumnWidth(colIndex) : width;
88
+ var drawX = fixed ? fixedLeft : x - scrollState.scrollLeft;
89
+ if (!fixed && (drawX + actualWidth < 0 || drawX > displayWidth)) {
90
+ return;
91
+ }
92
+ ctx.beginPath();
93
+ ctx.moveTo(Math.max(drawX, 0), y);
94
+ ctx.lineTo(Math.min(drawX + actualWidth, displayWidth), y);
95
+ ctx.stroke();
96
+ });
97
+ }
98
+ };
99
+ for (var i = startRow; i <= maxRow; i++) {
100
+ _loop_1(i);
101
+ }
102
+ // 为合并单元格绘制底部边框
103
+ if (mergeCellMap && mergeCellMap.size > 0) {
104
+ mergeCellMap.forEach(function (mergeInfo) {
105
+ if (!mergeInfo.skip && mergeInfo.rowSpan > 1) {
106
+ var rowIndex = mergeInfo.rowIndex, colIndex = mergeInfo.colIndex, rowSpan = mergeInfo.rowSpan;
107
+ if (rowIndex >= startRow && rowIndex <= maxRow) {
108
+ var columnInfo = columnRenderInfos[colIndex];
109
+ if (!columnInfo)
110
+ return;
111
+ if (onlyFixed && !columnInfo.fixed)
112
+ return;
113
+ if (!onlyFixed && columnInfo.fixed)
114
+ return;
115
+ var x = columnInfo.x, width = columnInfo.width, fixed = columnInfo.fixed, fixedLeft = columnInfo.fixedLeft;
116
+ var actualWidth = getColumnWidth
117
+ ? getColumnWidth(colIndex)
118
+ : width;
119
+ var drawX = fixed ? fixedLeft : x - scrollState.scrollLeft;
120
+ var bottomY = headerHeight +
121
+ fixedTopRowsCount * rowHeight +
122
+ (rowIndex + rowSpan - fixedTopRowsCount) * rowHeight -
123
+ scrollState.scrollTop;
124
+ if (bottomY >= headerHeight + fixedTopRowsCount * rowHeight &&
125
+ bottomY <= dataBottomY) {
126
+ ctx.beginPath();
127
+ ctx.moveTo(drawX, bottomY);
128
+ ctx.lineTo(drawX + actualWidth, bottomY);
129
+ ctx.stroke();
130
+ }
131
+ }
132
+ }
133
+ });
134
+ }
135
+ };
136
+ /**
137
+ * 渲染固定行边框(通用�?
138
+ */
139
+ BorderRenderer.prototype.renderFixedRowBorders = function (rowCount, startYCalculator, onlyFixed, borderType) {
140
+ var _this = this;
141
+ if (onlyFixed === void 0) { onlyFixed = false; }
142
+ if (borderType === void 0) { borderType = "normal"; }
143
+ if (!this.context || !this.context.bordered)
144
+ return;
145
+ var _a = this.context, ctx = _a.ctx, columnRenderInfos = _a.columnRenderInfos, scrollState = _a.scrollState, displayWidth = _a.displayWidth, getColumnWidth = _a.getColumnWidth;
146
+ ctx.save();
147
+ ctx.strokeStyle = COLORS.border;
148
+ ctx.lineWidth = borderType === "summary" ? 2 : 1;
149
+ var startY = startYCalculator();
150
+ // 计算固定列的右边�?
151
+ var fixedColumnsRightEdge = 0;
152
+ if (onlyFixed) {
153
+ fixedColumnsRightEdge = calculateFixedColumnsRightEdge(columnRenderInfos, getColumnWidth);
154
+ }
155
+ // 绘制水平边框
156
+ for (var i = 0; i <= rowCount; i++) {
157
+ var y = startY + i * this.context.rowHeight;
158
+ ctx.beginPath();
159
+ if (onlyFixed) {
160
+ ctx.moveTo(0, y);
161
+ ctx.lineTo(fixedColumnsRightEdge, y);
162
+ }
163
+ else {
164
+ ctx.moveTo(0, y);
165
+ ctx.lineTo(displayWidth, y);
166
+ }
167
+ ctx.stroke();
168
+ }
169
+ // 绘制垂直边框
170
+ ctx.lineWidth = 1;
171
+ columnRenderInfos.forEach(function (info, colIndex) {
172
+ var _a;
173
+ var x = info.x, width = info.width, fixed = info.fixed, fixedLeft = info.fixedLeft;
174
+ if (onlyFixed && !fixed)
175
+ return;
176
+ if (!onlyFixed && fixed)
177
+ return;
178
+ var actualWidth = getColumnWidth ? getColumnWidth(colIndex) : width;
179
+ var drawX = fixed
180
+ ? fixedLeft + actualWidth
181
+ : x + actualWidth - scrollState.scrollLeft;
182
+ if (drawX >= 0 && drawX <= displayWidth) {
183
+ ctx.beginPath();
184
+ ctx.moveTo(drawX, startY);
185
+ ctx.lineTo(drawX, startY + rowCount * (((_a = _this.context) === null || _a === void 0 ? void 0 : _a.rowHeight) || 0));
186
+ ctx.stroke();
187
+ }
188
+ });
189
+ ctx.restore();
190
+ };
191
+ /**
192
+ * 渲染固定顶部行边�?
193
+ */
194
+ BorderRenderer.prototype.renderFixedTopBorders = function (rowCount, onlyFixed) {
195
+ var _this = this;
196
+ if (onlyFixed === void 0) { onlyFixed = false; }
197
+ if (!this.context)
198
+ return;
199
+ this.renderFixedRowBorders(rowCount, function () { return _this.context.headerHeight; }, onlyFixed, "normal");
200
+ };
201
+ /**
202
+ * 渲染固定底部行边�?
203
+ */
204
+ BorderRenderer.prototype.renderFixedBottomBorders = function (rowCount, onlyFixed) {
205
+ if (onlyFixed === void 0) { onlyFixed = false; }
206
+ if (!this.context)
207
+ return;
208
+ var _a = this.context, displayHeight = _a.displayHeight, needHorizontalScrollbar = _a.needHorizontalScrollbar, summaryFixed = _a.summaryFixed, hasSummaryRow = _a.hasSummaryRow, rowHeight = _a.rowHeight;
209
+ this.renderFixedRowBorders(rowCount, function () {
210
+ var fixedSummaryHeight = summaryFixed && hasSummaryRow ? rowHeight : 0;
211
+ return (displayHeight -
212
+ (needHorizontalScrollbar ? SCROLLBAR_SIZE : 0) -
213
+ fixedSummaryHeight -
214
+ rowCount * rowHeight);
215
+ }, onlyFixed, "normal");
216
+ };
217
+ /**
218
+ * 渲染固定合计行边�?
219
+ */
220
+ BorderRenderer.prototype.renderFixedSummaryBorder = function (fixedY, onlyFixed) {
221
+ if (onlyFixed === void 0) { onlyFixed = false; }
222
+ if (!this.context)
223
+ return;
224
+ this.renderFixedRowBorders(1, function () { return fixedY; }, onlyFixed, "summary");
225
+ };
226
+ return BorderRenderer;
227
+ }());
228
+
229
+ export { BorderRenderer };