UNPKG

d-render

Version:

基于 Element Plus 二次封装的数据驱动渲染组件库 - 表单、搜索表单、表格配置化渲染

131 lines (126 loc) 4.87 kB
// 可以转换的validateType import { createValidators } from './form-validator' import type { TValidator } from './form-validator' import type { IAnyObject, TFormConfig, IRenderConfig, ICustomValidator } from '@d-render/shared' import type { FormItemRule } from 'element-plus' import { defaultLocale, translate, type Translator } from '../locale' const fallbackT: Translator = (path, option) => translate(path, option, defaultLocale) const isInputType = (config: TFormConfig) => { if (config.triggerType === 'input') { return true } if (config.triggerType === 'select') { return false } // 兼容老的未设置triggerType的表单数据验证 return ['input', 'textarea', 'number', 'numberRange', 'table', 'password', undefined].includes(config.type) } export interface RequiredRule { type?: string required?: boolean message?: string [propname: string]: unknown } // 获取单字段规则 export const getRulesByFieldConfig = ( config: TFormConfig, otherValue: unknown, dependOnValues: IAnyObject, outDependOnValues: IAnyObject, t: Translator = fallbackT ) => { const rules = [] as FormItemRule[] const validatorMap: Record<string, TValidator> = createValidators(t) if (config.required) { // 必填 const defaultMessage = isInputType(config) ? t('dr.form.requiredInput', { label: config.label ?? '' }) : t('dr.form.requiredSelect', { label: config.label ?? '' }) const requiredMessage = config.requiredErrorMessage || defaultMessage const requiredRule = { required: true, message: requiredMessage, ...config.requiredRuleConfig as IAnyObject } as FormItemRule if (config.requiredType) { requiredRule.type = config.requiredType } rules.push(requiredRule) // 双值验证 if (config.type === 'dateRange' && config.otherKey) { // 日期范围 const validator:TValidator = (rule, value, cb) => { if (value) { if (otherValue) { cb() } else { cb(new Error(t('dr.form.requiredEndTime', { message: requiredMessage }))) } } else { cb() } } const otherRules = { validator } rules.push(otherRules) } } if (typeof config.customRequiredRule === 'function') { const CRR = config.customRequiredRule(config as IRenderConfig, otherValue as IAnyObject, dependOnValues, outDependOnValues) rules.push(CRR) } // 提取公共函数 const pushValidatorFunction = (validator: TValidator, type?: string) => { const message = config.validateValueErrorMessage as string const rule: { validator: TValidator, trigger: string, message?: string } = { validator, trigger: type || 'blur' } if (message) { rule.message = message } return rule } if (config.validateValue && validatorMap[config.validateValue]) { // 内置值类型校验 const validator = validatorMap[config.validateValue] as TValidator if (validator) { rules.push(pushValidatorFunction(validator)) } } // 正则校验 if (config.regexpValidate) { try { const reg = new RegExp(config.regexpValidate as string) const rule = { pattern: reg, message: config.regexpValidateErrorMessage || t('dr.form.regexpFail', { pattern: reg.toString() }), trigger: 'blur' } rules.push(rule) } catch (e: unknown) { console.log((e as Error).message) } } // 远程校验值是否已经存在 if (config.validateExistRemote) { // @ts-ignore Promise<void> === void const validator: TValidator = async (rule, value, callback) => { const { data } = await config.validateExistRemote!(value, dependOnValues, outDependOnValues) if (data) { // data 为真值是校验失败 callback(new Error(config.validateExistRemoteErrorMessage || rule.message as string || t('dr.form.alreadyExists'))) } else { callback() } } rules.push(pushValidatorFunction(validator)) } // 自定义验证器 if (config.customValidators) { const customRules = ( config.customValidators as Array<ICustomValidator> ).map(customValidator => { // @ts-ignore Promise<void> === void const validator: TValidator = async (rule, value, callback) => { const { data, message } = await customValidator(value, dependOnValues, outDependOnValues) if (!data) { // data 为假值是校验失败 const errorMessage = customValidator.message || message || rule.message as string callback(new Error(errorMessage)) } else { callback() } } return pushValidatorFunction(validator, customValidator.type) }) rules.push(...customRules) } return rules }