validate

2022-10-27  本文已影响0人  芸芸众生ing

// validate.ts
/**
 * 判断url协议
 * @param path url
 * @returns boolean
 */
export function isExternal(path: string | any): boolean {
  return /^(https?:|mailto:|tel:)/.test(path);
}

/**
 * 获取数据类型 
 * @param arg 数据
 * @returns string
 */
export function getType(arg: any): string {
  return Object.prototype.toString.call(arg).replace(/^\[\w+\s(\w+)\]$/, '$1').toLowerCase()
}
/**
 * 判断数据是否为指定类型
 * @param arg 数据
 * @param type 类型
 * @returns Boolean
 */
export function isType(arg: any, type: string): boolean {
  return getType(arg) === type.toString().toLowerCase();
}
/**
 * 判断是否为空
 * @param arg 数据
 * @returns Boolean
 */
export function isNull(arg: any): boolean {
  if (isType(arg, 'object')) return JSON.stringify(arg) == '{}';
  if (isType(arg, 'string')) return arg === '' || arg === ' ';
  if (isType(arg, 'null')) return true;
  if (isType(arg, 'undefined')) return true;
  return false
}

/**
 * 验证邮箱
 */
export function isEmail(arg: string): boolean {
  return /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(arg)
}

/**
 * 验证手机号
 */
export function isPhone(arg: string): boolean {
  return /^1[3-9][0-9]{9}$/.test(arg)
}
/**
 * 校验身份证号码
 */
export function isIdCard(arg: string): boolean {
  let x = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
  let y = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"];
  let i = arg.split('');
  let t = x.reduce((total, item, index) => Number(i[index]) * item + total, 0);
  let r = t % 11;
  return arg.slice(-1) === y[r];
}

// validator.ts
import { getType, isNull, isType, isEmail } from "./validate";

interface Rule {
  type?: string | any,
  required?: boolean,
  message?: string,
  min?: number,
  max?: number,
  [key: string]: any
}

interface Rules {
  [key: string]: Rule | Rule[] | string
}
interface Target {
  [key: string]: boolean | string | boolean | object | any[]
}
interface Err {
  key: string,
  message: string
}
/**
 * 验证器
 * @param target 元数据
 * @param rules 验证规则
 * @returns Boolean || 不通过字段数组
 */
export default function validator(target: Target, rules: Rules): Promise<Err[] | boolean> {
  return new Promise((resolve, reject) => {
    const errorArr: Err[] = [];
    for (let key in rules) {
      let msg: string[] = [];
      let rule = rules[key];
      let val = target[key];
      if (Array.isArray(rule)) rule.forEach((item: Rule) => validate(item, val, msg));
      else if (typeof rule === 'string') validate({ type: rule }, val, msg);
      else validate(rule, val, msg);
      msg.length && errorArr.push({ key, message: msg.join(',且') });
    }
    errorArr.length ? reject(errorArr) : resolve(false);
  });
}

function validate(rule: Rule, val: any, msg: string[]) {
  let { type = null, required = false, min = 0, max = 0, message = '' } = rule;
  if (required && isNull(val)) msg.push('不能为空');
  if (isType(type, 'String')) type = type.toLowerCase();
  if (isType(type, 'regexp') && new RegExp(type).test(val)) msg.push('校验失败');
  if ((min || max) && (min > val.length || max < val.length)) msg.push('长度错误');
  if (type === Array && !isType(val, 'array')) pushErrorInfo('array', getType(val));
  if (type === Object && !isType(val, 'object')) pushErrorInfo('object', getType(val));
  if (type === Number && !isType(val, 'number')) pushErrorInfo('number', getType(val));
  if (type === String && !isType(val, 'string')) pushErrorInfo('string', getType(val));
  if (type === Boolean && !isType(val, 'boolean')) pushErrorInfo('boolean', getType(val));
  if (type === 'array' && !isType(val, 'array')) pushErrorInfo(type, getType(val));
  if (type === 'object' && !isType(val, 'object')) pushErrorInfo(type, getType(val));
  if (type === 'number' && !isType(val, 'number')) pushErrorInfo(type, getType(val));
  if (type === 'string' && !isType(val, 'string')) pushErrorInfo(type, getType(val));
  if (type === 'boolean' && !isType(val, 'boolean')) pushErrorInfo(type, getType(val));
  if (type === 'email' && !isEmail(val)) msg.push('email地址错误');
  function pushErrorInfo(a: string, b: string) {
    msg.push(message || `需要[${a}], 但得到[${b}]`)
  }
}
上一篇下一篇

猜你喜欢

热点阅读