import type { VbenFormProps as FormProps, VbenFormSchema as FormSchema, FormValues, } from '@vben/common-ui'; import type { ComponentPropsMap, ComponentType } from './component'; import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui'; import { $t } from '@vben/locales'; /** * 判断表单值是否「空」(必填校验共用) * 为什么不写 value.length===0:InputNumber 是 number,.length 为 undefined,会误判/漏判 * 数字 0 视为有值(比例、金额等合法) */ function isEmptyFormValue(value: unknown): boolean { if (value === undefined || value === null) return true; if (typeof value === 'string') return value.trim() === ''; if (Array.isArray(value)) return value.length === 0; return false; } /** 校验文案用的字段名:优先 label,避免 i18n {0} 裸露成「请输入x」 */ function ruleLabel(ctx: { label?: string; name?: string }): string { return (ctx.label || ctx.name || '该项').trim() || '该项'; } async function initSetupVbenForm() { setupVbenForm({ config: { // ant design vue组件库默认都是 v-model:value baseModelPropName: 'value', // antd Input 的 onChange 带的是 event,打开回退后表单能从 event.target.value 取值 // (与 v-model:value 双通道写入,避免包装层漏绑时查询条件一直是空) changeEventFallback: true, // 一些组件是 v-model:checked 或者 v-model:fileList // Vben* 走 modelValue,避免被 baseModelPropName=value 误绑后把 Event 写进字段 modelPropNameMap: { Checkbox: 'checked', Radio: 'checked', Switch: 'checked', Upload: 'fileList', UploadImage: 'modelValue', UploadOssFile: 'modelValue', VbenInput: 'modelValue', VbenInputPassword: 'modelValue', VbenPinInput: 'modelValue', }, }, rules: { // 输入项目必填国际化适配(兼容 InputNumber number) required: (value, _params, ctx) => { if (isEmptyFormValue(value)) { return $t('ui.formRules.required', [ruleLabel(ctx)]); } return true; }, // 选择项目必填国际化适配 selectRequired: (value, _params, ctx) => { if (isEmptyFormValue(value)) { return $t('ui.formRules.selectRequired', [ruleLabel(ctx)]); } return true; }, /** * 大陆手机号:必填 + 11 位且号段 13-19(与后端 UtilsService::checkPhone 一致) * 表单字段 rules: 'mobile' 即可,无需再叠 required */ mobile: (value, _params, ctx) => { const phone = typeof value === 'string' ? value.trim() : value; if (isEmptyFormValue(phone)) { return $t('ui.formRules.required', [ruleLabel(ctx)]); } if (!/^1[3456789]\d{9}$/.test(String(phone))) { return $t('ui.formRules.mobile', [ruleLabel(ctx)]); } return true; }, }, }); } function useVbenForm< TFormValues extends FormValues = FormValues, TSubmitValues extends FormValues = TFormValues, >( options: FormProps< ComponentType, ComponentPropsMap, TFormValues, TSubmitValues >, ) { return useForm( options, ); } export { initSetupVbenForm, useVbenForm, z }; export type VbenFormSchema = FormSchema; export type VbenFormProps< TFormValues extends FormValues = FormValues, TSubmitValues extends FormValues = TFormValues, > = FormProps;