import type { ZodRawShape } from 'zod'; import type { ComputedRef } from 'vue'; import type { ExtendedFormApi, FormActions, VbenFormProps } from './types'; import { computed, unref, useSlots } from 'vue'; import { createContext } from '@vben-core/shadcn-ui'; import { isString, mergeWithArrayOverride, set } from '@vben-core/shared/utils'; import { useForm } from 'vee-validate'; import { object, ZodIntersection, ZodNumber, ZodObject, ZodString } from 'zod'; import { getDefaultsForSchema } from 'zod-defaults'; type ExtendFormProps = VbenFormProps & { formApi: ExtendedFormApi }; export const [injectFormProps, provideFormProps] = createContext<[ComputedRef | ExtendFormProps, FormActions]>( 'VbenFormProps', ); export const [injectComponentRefMap, provideComponentRefMap] = createContext>('ComponentRefMap'); export function useFormInitial( props: ComputedRef | VbenFormProps, ) { const slots = useSlots(); const initialValues = generateInitialValues(); const form = useForm({ ...(Object.keys(initialValues)?.length ? { initialValues } : {}), }); const delegatedSlots = computed(() => { const resultSlots: string[] = []; for (const key of Object.keys(slots)) { if (key !== 'default') { resultSlots.push(key); } } return resultSlots; }); function generateInitialValues() { const initialValues: Record = {}; const zodObject: ZodRawShape = {}; (unref(props).schema || []).forEach((item) => { if (Reflect.has(item, 'defaultValue')) { set(initialValues, item.fieldName, item.defaultValue); } else if (item.rules && !isString(item.rules)) { // 检查规则是否适合提取默认值 const customDefaultValue = getCustomDefaultValue(item.rules); zodObject[item.fieldName] = item.rules; if (customDefaultValue !== undefined) { initialValues[item.fieldName] = customDefaultValue; } } }); const schemaInitialValues = getDefaultsForSchema(object(zodObject)); const zodDefaults: Record = {}; for (const key in schemaInitialValues) { set(zodDefaults, key, schemaInitialValues[key]); } return mergeWithArrayOverride(initialValues, zodDefaults); } // 自定义默认值提取逻辑 function getCustomDefaultValue(rule: any): any { if (rule instanceof ZodString) { return ''; // 默认为空字符串 } else if (rule instanceof ZodNumber) { return null; // 默认为 null(避免显示 0) } else if (rule instanceof ZodObject) { // 递归提取嵌套对象的默认值 const defaultValues: Record = {}; for (const [key, valueSchema] of Object.entries(rule.shape)) { defaultValues[key] = getCustomDefaultValue(valueSchema); } return defaultValues; } else if (rule instanceof ZodIntersection) { // 对于交集类型,从schema 提取默认值 const leftDefaultValue = getCustomDefaultValue(rule._def.left); const rightDefaultValue = getCustomDefaultValue(rule._def.right); // 如果左右两边都能提取默认值,合并它们 if ( typeof leftDefaultValue === 'object' && typeof rightDefaultValue === 'object' ) { return { ...leftDefaultValue, ...rightDefaultValue }; } // 否则优先使用左边的默认值 return leftDefaultValue ?? rightDefaultValue; } else { return undefined; // 其他类型不提供默认值 } } return { delegatedSlots, form, }; }