refactor: 中间栏三层架构 — useUI 组件体系 + useModelUI Hook

- 新建 useUI/ 目录:12 个文件,10 个 Qt 控件 → antd 组件封装 + 类型 + 注册表
- 新建 useModelUI Hook:param_schema → UIFieldConfig[] 自动映射
- ModelInputForm 瘦身 ~160 行:删除 buildParamDescriptors/renderParamControl/文件状态管理
- WIDGET_MAP: Record<string, ComponentType<WidgetProps>> — 零 any,完全类型安全
- 新增控件只需两步:创建组件文件 + 在 WIDGET_MAP 加一行
- 删除旧 widgets/ 目录

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-09 15:32:17 +08:00
parent 76e66a37c8
commit d5ba7e63cd
14 changed files with 733 additions and 339 deletions

View File

@@ -0,0 +1,55 @@
// ============================================================
// ImageListInput — imageList → Dragger多张图片拖拽上传
// 用于图生图模型的多图输入场景
// ============================================================
import { Upload, message } from 'antd';
import { InboxOutlined } from '@ant-design/icons';
import type { UploadFile } from 'antd/es/upload';
import type { WidgetProps } from './types';
const { Dragger } = Upload;
export function ImageListInput({ value, onChange, disabled, config }: WidgetProps) {
const fileList = (value as UploadFile[]) || [];
const maxSizeMb = (config.maxFileSizeMb as number) || 10;
const maxCount = (config.maxFiles as number) || 10;
const filters = config.fileFilter as string[] | undefined;
return (
<Dragger
multiple
listType="picture"
accept={
filters
? filters.map((ext) => `image/${ext}`).join(',')
: 'image/png,image/jpg,image/jpeg,image/webp'
}
fileList={fileList}
onChange={({ fileList: newList }) => onChange?.(newList)}
disabled={disabled}
beforeUpload={(file) => {
const isImage = file.type.startsWith('image/');
if (!isImage) {
message.error('只能上传图片文件');
return Upload.LIST_IGNORE;
}
if (file.size / 1024 / 1024 >= maxSizeMb) {
message.error(`图片大小不能超过 ${maxSizeMb}MB`);
return Upload.LIST_IGNORE;
}
return false;
}}
maxCount={maxCount}
>
<p className="ant-upload-drag-icon">
<InboxOutlined />
</p>
<p className="ant-upload-text"></p>
<p className="ant-upload-hint">
{filters?.join(' / ').toUpperCase() || 'PNG / JPG / WebP'}
{maxSizeMb}MB
</p>
</Dragger>
);
}