From af0b2d8ed129cd3f8751a42d6827a31245fb5dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=A8=E9=9C=96=E9=93=83?= Date: Sat, 6 Jun 2026 09:58:57 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=BB=9F=E4=B8=80=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E5=8D=A1=E7=89=87=E9=AB=98=E5=BA=A6=EF=BC=8C?= =?UTF-8?q?=E6=9C=80=E5=A4=A7=E5=AD=97=E6=AE=B5=E6=95=B0=E6=94=B9=E4=B8=BA?= =?UTF-8?q?40?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - MAX_FIELDS: 20 → 40 - 固定卡片高度52px,无论虚拟/非虚拟模式视觉一致 - 5条以上容器高度固定,启用虚拟滚动 - 主页面添加字段时检查MAX_FIELDS限制 --- .../components/FieldList.tsx | 124 +++++++++++++++--- src/pages/TestDataGenerator/index.tsx | 9 +- 2 files changed, 110 insertions(+), 23 deletions(-) diff --git a/src/pages/TestDataGenerator/components/FieldList.tsx b/src/pages/TestDataGenerator/components/FieldList.tsx index 5b695c1..a64a9c3 100644 --- a/src/pages/TestDataGenerator/components/FieldList.tsx +++ b/src/pages/TestDataGenerator/components/FieldList.tsx @@ -1,8 +1,10 @@ /** * 字段列表组件 * 展示所有字段配置,支持添加、删除、拖拽排序 + * 超过 5 条时启用虚拟列表滚动 */ +import { useState, useRef, useCallback } from 'react'; import { Plus, GripVertical, Trash2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { useI18n } from '@/utils/chromeI18n'; @@ -25,6 +27,15 @@ import { CSS } from '@dnd-kit/utilities'; import type { FieldConfig } from '@/types/testDataGenerator'; import FieldItem from './FieldItem'; +/** 最大字段数量 */ +export const MAX_FIELDS = 40; + +/** 虚拟列表配置 */ +const VISIBLE_COUNT = 5; +const ROW_HEIGHT = 60; // 卡片高度 52 + 间距 8 +const ROW_GAP = 8; +const OVERSCAN = 2; + interface FieldListProps { fields: FieldConfig[]; onUpdate: (index: number, field: FieldConfig) => void; @@ -56,6 +67,7 @@ function SortableFieldItem({ transition, opacity: isDragging ? 0.5 : 1, zIndex: isDragging ? 10 : 0, + height: ROW_HEIGHT - ROW_GAP, // 固定卡片高度 52px,与虚拟模式一致 }; return ( @@ -70,22 +82,24 @@ function SortableFieldItem({ : 'border-border hover:border-muted-foreground/30' }`} > -
+
{/* 拖拽手柄 */} - +
+ +
-
+
{fields.length === 0 ? (
@@ -154,15 +201,60 @@ export default function FieldList({ onDragEnd={handleDragEnd} > f.id)} strategy={verticalListSortingStrategy}> - {fields.map((field, index) => ( - onSelect(index)} - onRemove={() => onRemove(index)} - /> - ))} +
+ {isVirtual ? ( + /* 虚拟滚动模式 */ +
+
+ {visibleFields.map((field, vi) => { + const realIndex = fields.findIndex((f) => f.id === field.id); + const isLast = visibleStart + vi === fields.length - 1; + return ( +
+ onSelect(realIndex)} + onRemove={() => onRemove(realIndex)} + /> +
+ ); + })} +
+
+ ) : ( + /* 普通模式(≤5 条) */ +
+ {fields.map((field, index) => ( + onSelect(index)} + onRemove={() => onRemove(index)} + /> + ))} +
+ )} +
)} diff --git a/src/pages/TestDataGenerator/index.tsx b/src/pages/TestDataGenerator/index.tsx index a1ef778..fc641f2 100644 --- a/src/pages/TestDataGenerator/index.tsx +++ b/src/pages/TestDataGenerator/index.tsx @@ -15,7 +15,7 @@ function generateId(): string { return `field_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`; } -import FieldList from './components/FieldList'; +import FieldList, { MAX_FIELDS } from './components/FieldList'; import FieldEditor from './components/FieldEditor'; import GenerateOptions from './components/GenerateOptions'; import GenerateButton from './components/GenerateButton'; @@ -98,6 +98,7 @@ export default function TestDataGeneratorPage() { // 添加新字段 const handleAddField = useCallback(() => { + if (fields.length >= MAX_FIELDS) return; const newField: FieldConfig = { id: generateId(), name: `field${fields.length + 1}`, @@ -178,12 +179,6 @@ export default function TestDataGeneratorPage() { return (
- {/* 页面标题 */} -
-

{t('testDataGenerator_title')}

-

{t('testDataGenerator_description')}

-
- {/* 主要内容区域 - 左右分栏 */}
{/* 左侧面板 - 字段配置 */}