import { IFieldEnum, IRule, IRuleStatus, IRuleTrigger, IValidateResult, IValidator, IValidatorFunc, IValidatorMap, IValidatorParams } from '@wowpic/xform-types'; import AsyncValidator, { RuleItem, ValidateError } from 'async-validator'; import { groupBy } from './utils'; export default class Validator implements IValidator { private context: IFieldEnum; private validatorMap: IValidatorMap; private validatorFunc: IValidatorFunc; constructor(context: IFieldEnum, params: IValidatorParams) { this.context = context; this.initialize(params); } public initialize(params: IValidatorParams) { const { key, context } = this.context; this.validatorMap = {}; this.validatorFunc = null; const ruleMap = groupBy(params.rules || [], 'trigger', 'submit'); Object.keys(ruleMap).forEach((trigger: IRuleTrigger) => { const rules = ruleMap[trigger]; const errorRules: IRule[] = []; const warningRules: IRule[] = []; rules.forEach((rule: IRule) => { const newRule = { ...rule }; if (newRule.validator) { newRule.validator = (...args: any[]) => rule.validator(...args, context); } if (newRule.asyncValidator) { newRule.asyncValidator = (...args: any[]) => rule.asyncValidator(...args, context); } if (newRule.status === 'warning') { warningRules.push(newRule); } else { errorRules.push(newRule); } }); this.validatorMap[trigger] = {}; if (errorRules.length > 0) { this.validatorMap[trigger].error = new AsyncValidator({ [key]: errorRules }); } if (warningRules.length > 0) { this.validatorMap[trigger].warning = new AsyncValidator({ [key]: warningRules }); } }); } private getValidateResult(trigger: IRuleTrigger, status: IRuleStatus) { const { key } = this.context; const validators = this.validatorMap[trigger]; const value = this.context.value; const result: Promise = new Promise((resolve) => { validators[status].validate({ [key]: value }, { suppressWarning: true }, (errors: ValidateError[]) => { if (errors) { const error = errors[0]; resolve({ valid: false, message: error.message, status: status }); } else { resolve({ valid: true, message: '', status: 'normal' }); } }); }); return result; } // 自定义组件中校验 public setValidtorFunc(callback: IValidatorFunc) { this.validatorFunc = callback; } public async validate(trigger: IRuleTrigger) { if (this.validatorFunc) { const value = this.context.value; const result = await this.validatorFunc(trigger, value); return result || { valid: true, message: '', status: 'normal' }; } const validators = this.validatorMap[trigger]; if (validators) { let res = null; if (validators.error && validators.warning) { const result = await this.getValidateResult(trigger, 'error'); if (result.valid) { res = await this.getValidateResult(trigger, 'warning'); return res; } return result; } if (validators.error && !validators.warning) { res = await this.getValidateResult(trigger, 'error'); return res; } if (!validators.error && validators.warning) { res = await this.getValidateResult(trigger, 'warning'); return res; } return res; } return { valid: true, message: '', status: 'normal' }; } }