feat: constraints_config.requires 联动控制 — enable_switch 开关同步启用/禁用依赖字段

- DependentFormItem: 透传 disabled 为顶层 prop(之前藏在 config.disabled 中,widget 组件读取不到)
- ImageInput: 值语义分层 — undefined(开关关) / [](开关开但空) / [{...}](已上传)
- isValueEmpty: 空数组[] 不再视为空,配合 enable_switch 语义
- handleFileWidgetValue: 兼容 Upload DOM事件 和 enable_switch 裸值两种 onChange 形态

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-09 17:36:53 +08:00
parent 4261915679
commit 0c7b33aac1
3 changed files with 43 additions and 8 deletions

View File

@@ -6,6 +6,11 @@
// 当 API ui.enable_switch === true 时,默认禁用(灰色),
// 需点击 Switch 开关后才能上传——匹配原 Qt 客户端行为。
// 开关关闭时清除已上传文件。
//
// 表单值语义(配合 constraints_config.requires 依赖禁用):
// undefined → 开关关闭 / 未启用 → isValueEmpty = true → 依赖字段禁用
// [] → 开关开启但未上传文件 → isValueEmpty = false → 依赖字段启用
// [{...}] → 已上传文件 → isValueEmpty = false → 依赖字段启用
// ============================================================
import { useState, useCallback } from 'react';
@@ -22,6 +27,9 @@ function buildAccept(filters?: string[]): string {
return filters.map((ext) => `image/${ext}`).join(',');
}
/** 标记"已启用但空"的空数组,避免 react 渲染时引用变化 */
const ENABLED_EMPTY: UploadFile[] = [];
export function ImageInput({ value, onChange, disabled, config }: WidgetProps) {
const fileList = (value as UploadFile[]) || [];
const maxSizeMb = (config.maxFileSizeMb as number) || 10;
@@ -35,16 +43,18 @@ export function ImageInput({ value, onChange, disabled, config }: WidgetProps) {
(on: boolean) => {
setSwitchOn(on);
if (!on) {
// 关闭开关 → 清除已上传文件
onChange?.([] as unknown as UploadFile[]);
// 关闭开关 → 表单值置为 undefinedisValueEmpty = true依赖字段禁用
onChange?.(undefined);
} else {
// 开启开关 → 空数组 = "已启用但未上传"isValueEmpty = false依赖字段启用
onChange?.(ENABLED_EMPTY as unknown as UploadFile[]);
}
},
[onChange],
);
return (
<Space orientation={"vertical"}
style={{ width: '100%' }} size={8}>
<Space orientation="vertical" style={{ width: '100%' }} size={8}>
{hasEnableSwitch && (
<Space size={8}>
<Switch
@@ -64,7 +74,12 @@ export function ImageInput({ value, onChange, disabled, config }: WidgetProps) {
maxCount={1}
accept={buildAccept(config.fileFilter as string[] | undefined)}
fileList={fileList}
onChange={({ fileList: newList }) => onChange?.(newList as unknown as UploadFile[])}
onChange={({ fileList: newList }) => {
// 仅当开关开启时上报文件变化
if (switchOn || !hasEnableSwitch) {
onChange?.(newList as unknown as UploadFile[]);
}
}}
disabled={isUploadDisabled}
beforeUpload={(file) => {
const isImage = file.type.startsWith('image/');