diff --git a/furniture-3d-system/src/app/supply-chain/database/product-archive/ProductArchiveTableBody.tsx b/furniture-3d-system/src/app/supply-chain/database/product-archive/ProductArchiveTableBody.tsx index b56b420f..48af5e58 100644 --- a/furniture-3d-system/src/app/supply-chain/database/product-archive/ProductArchiveTableBody.tsx +++ b/furniture-3d-system/src/app/supply-chain/database/product-archive/ProductArchiveTableBody.tsx @@ -5,6 +5,7 @@ import type { ArchiveColumnGroup } from './columns' import { ProductArchiveActions } from './ProductArchiveActions' import { ProductArchiveMaterialImageCell } from './ProductArchiveMaterialImageCell' import type { ProductArchivePageImageState } from './useProductArchivePageImages' +import { ARCHIVE_ROW_HEIGHT, type ArchiveRowWindow } from './useArchiveRowWindowing' const IDLE_IMAGE_STATE: ProductArchivePageImageState = { status: 'idle', @@ -15,6 +16,8 @@ type ProductArchiveTableBodyProps = { rows: SupplyChainProductArchiveRow[] columns: ArchiveColumnGroup[] startIndex: number + /** 行虚拟化窗口:只渲染 [start, end) 的行,其余用占位行撑高。 */ + rowWindow: ArchiveRowWindow imageStates: Record onImageVisible: (archiveId: string) => void onPreviewImage: (image: string, title: string) => void @@ -57,6 +60,8 @@ function areTableBodyPropsEqual( return previous.rows === next.rows && previous.startIndex === next.startIndex + && previous.rowWindow.start === next.rowWindow.start + && previous.rowWindow.end === next.rowWindow.end && previous.onImageVisible === next.onImageVisible && previous.onPreviewImage === next.onPreviewImage && previous.onViewRow === next.onViewRow @@ -94,17 +99,29 @@ export const ProductArchiveTableBody = memo(function ProductArchiveTableBody({ rows, columns, startIndex, + rowWindow, imageStates, onImageVisible, onPreviewImage, onViewRow, onOpenChangeLog, }: ProductArchiveTableBodyProps) { + const columnCount = columns.reduce((count, group) => count + group.columns.length, 0) + const spacerColSpan = columnCount + 2 + const visibleRows = rows.slice(rowWindow.start, rowWindow.end) + const topPadHeight = rowWindow.start * ARCHIVE_ROW_HEIGHT + const bottomPadHeight = Math.max(0, rows.length - rowWindow.end) * ARCHIVE_ROW_HEIGHT + return ( - {rows.map((row, rowIndex) => ( + {topPadHeight > 0 && ( + + + + )} + {visibleRows.map((row, rowIndex) => ( - {startIndex + rowIndex + 1} + {startIndex + rowWindow.start + rowIndex + 1} {columns.map((group) => group.columns.map((column) => { const value = renderCell( @@ -139,12 +156,23 @@ export const ProductArchiveTableBody = memo(function ProductArchiveTableBody({ ))} + {bottomPadHeight > 0 && ( + + + + )}