diff --git a/packages/@core/ui-kit/form-ui/src/form-api.ts b/packages/@core/ui-kit/form-ui/src/form-api.ts index bdc44de787d..7d315f547fa 100644 --- a/packages/@core/ui-kit/form-ui/src/form-api.ts +++ b/packages/@core/ui-kit/form-ui/src/form-api.ts @@ -511,40 +511,118 @@ export class FormApi { fieldMappingTime.forEach( ([field, [startTimeKey, endTimeKey], format = 'YYYY-MM-DD']) => { + // 处理多级路径的辅助函数 + const setNestedValue = ( + obj: Record, + path: string, + value: any, + ): void => { + const keys = path.split('.'); + if (keys.length === 1) { + // 单级路径直接赋值 + obj[path] = value; + } else { + // 多级路径创建嵌套对象 + let target: Record = obj; + for (let i = 0; i < keys.length - 1; i++) { + const key = keys[i]; + if (key !== undefined) { + // 添加类型检查 + if ( + !(key in target) || + typeof target[key] !== 'object' || + target[key] === null + ) { + target[key] = {}; + } + target = target[key] as Record; + } + } + const lastKey = keys[keys.length - 1]; + if (lastKey !== undefined) { + target[lastKey] = value; + } + } + }; + + // 处理多级路径的删除函数 + const deleteNestedProperty = ( + obj: Record, + path: string, + ): void => { + const keys = path.split('.'); + if (keys.length === 1) { + // 单级路径直接删除 + Reflect.deleteProperty(obj, path); + } else { + // 多级路径导航到目标对象并删除属性 + let target: Record = obj; + for (let i = 0; i < keys.length - 1; i++) { + const key = keys[i]; + if (key !== undefined) { + // 添加类型检查 + if ( + !(key in target) || + typeof target[key] !== 'object' || + target[key] === null + ) { + return; + } + target = target[key] as Record; + } + } + const lastKey = keys[keys.length - 1]; + if (lastKey !== undefined) { + Reflect.deleteProperty(target, lastKey); + } + } + }; + + // 类型安全检查 + if (!field || !startTimeKey || !endTimeKey) { + return; + } + if (startTimeKey && endTimeKey && values[field] === null) { - Reflect.deleteProperty(values, startTimeKey); - Reflect.deleteProperty(values, endTimeKey); - // delete values[startTimeKey]; - // delete values[endTimeKey]; + deleteNestedProperty(values, startTimeKey); + deleteNestedProperty(values, endTimeKey); } if (!values[field]) { - Reflect.deleteProperty(values, field); - // delete values[field]; + deleteNestedProperty(values, field); + return; + } + + const timeRange = values[field]; + if (!Array.isArray(timeRange) || timeRange.length < 2) { return; } - const [startTime, endTime] = values[field]; + const [startTime, endTime] = timeRange; if (format === null) { - values[startTimeKey] = startTime; - values[endTimeKey] = endTime; + setNestedValue(values, startTimeKey, startTime); + setNestedValue(values, endTimeKey, endTime); } else if (isFunction(format)) { - values[startTimeKey] = format(startTime, startTimeKey); - values[endTimeKey] = format(endTime, endTimeKey); + setNestedValue(values, startTimeKey, format(startTime, startTimeKey)); + setNestedValue(values, endTimeKey, format(endTime, endTimeKey)); } else { const [startTimeFormat, endTimeFormat] = Array.isArray(format) ? format : [format, format]; - values[startTimeKey] = startTime - ? formatDate(startTime, startTimeFormat) - : undefined; - values[endTimeKey] = endTime - ? formatDate(endTime, endTimeFormat) - : undefined; + setNestedValue( + values, + startTimeKey, + startTime ? formatDate(startTime, startTimeFormat) : undefined, + ); + setNestedValue( + values, + endTimeKey, + endTime ? formatDate(endTime, endTimeFormat) : undefined, + ); } - // delete values[field]; - Reflect.deleteProperty(values, field); + + deleteNestedProperty(values, field); }, ); return values; diff --git a/playground/src/views/examples/form/basic.vue b/playground/src/views/examples/form/basic.vue index d0e91d33a6b..f1a2328b6f7 100644 --- a/playground/src/views/examples/form/basic.vue +++ b/playground/src/views/examples/form/basic.vue @@ -43,7 +43,7 @@ const [BaseForm, baseFormApi] = useVbenForm({ class: 'w-full', }, }, - fieldMappingTime: [['rangePicker', ['startTime', 'endTime'], 'YYYY-MM-DD']], + fieldMappingTime: [['rangePicker', ['startTime', 'endTime'], 'YYYY-MM-DD'], ['rangePicker2', ['createTimeQuery.startTime', 'createTimeQuery.endTime'], 'YYYY-MM-DD HH:mm:ss']], // 提交函数 handleSubmit: onSubmit, handleValuesChange(_values, fieldsChanged) { @@ -281,6 +281,17 @@ const [BaseForm, baseFormApi] = useVbenForm({ fieldName: 'rangePicker', label: '范围选择器', }, + { + component: 'RangePicker', + fieldName: 'rangePicker2', + componentProps: { + showTime: true, + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'YYYY-MM-DD HH:mm:ss', + placeholder: ['开始日期', '结束日期'], + }, + label: '时间范围选择器', + }, { component: 'TimePicker', fieldName: 'timePicker',