Files
xk-admin/apps/web-antd/src/adapter/form.ts
李琦 879efb8f29 feat: 管理端公账支付与确认、锁店遮罩及表单提交修复
新增公账账单/到账确认页与全局锁店组件;系统配置补公账参数面板;
统一弹窗 onConfirm 校验提交,并完善订单详情与门店相关交互。
2026-08-21 12:51:42 +08:00

109 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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===0InputNumber 是 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<ComponentType>({
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<TFormValues, ComponentType, ComponentPropsMap, TSubmitValues>(
options,
);
}
export { initSetupVbenForm, useVbenForm, z };
export type VbenFormSchema<TValues extends FormValues = FormValues> =
FormSchema<ComponentType, ComponentPropsMap, TValues>;
export type VbenFormProps<
TFormValues extends FormValues = FormValues,
TSubmitValues extends FormValues = TFormValues,
> = FormProps<ComponentType, ComponentPropsMap, TFormValues, TSubmitValues>;