|
|
/**
|
|
|
* 接口参数校验
|
|
|
*
|
|
|
* Created by y.huang on 17/5/21.
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
* 返回一个错误对象
|
|
|
*
|
|
|
* msg 提示语
|
|
|
*/
|
|
|
const _errJson = (message) => {
|
|
|
return {
|
|
|
code: '203',
|
|
|
description: message,
|
|
|
name: '数据错误',
|
|
|
errKey: 'valid'
|
|
|
};
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 数字校验方法、支持小数负数、支持字符串数字自动转换
|
|
|
*
|
|
|
* option object类型,包含校验条件,如下
|
|
|
* require 是否必须,boolean类型,默认false不必须
|
|
|
* empty 可以是空字符串, boolean类型,默认true可以
|
|
|
* isInteger 是否必须整数,boolean类型,默认false不必须
|
|
|
* equal 等于某个值,number类型
|
|
|
* equalArr 等于几个值中的一个,array类型,array元素为number类型,长度不限
|
|
|
* smaller 小于某个值,number类型
|
|
|
* bigger 大于某个值,number类型
|
|
|
*/
|
|
|
const _numberValid = (option) => {
|
|
|
const value = option.value;
|
|
|
|
|
|
// 设置默认值
|
|
|
option.require = option.require === undefined ? false : option.require;
|
|
|
option.integer = option.integer === undefined ? false : option.integer;
|
|
|
option.empty = option.empty === undefined ? true : option.empty;
|
|
|
|
|
|
if (value === undefined) {
|
|
|
if (option.require === true) {
|
|
|
throw _errJson(`${option.param} 参数是必须的`);
|
|
|
} else {
|
|
|
return value;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (typeof value === 'boolean' || typeof value === 'object') {
|
|
|
throw _errJson(`${option.param} 参数类型必须是数字或字符串数字`);
|
|
|
}
|
|
|
|
|
|
if (value === '') {
|
|
|
if (option.empty === false) {
|
|
|
throw _errJson(`${option.param} 参数不能为空字符串`);
|
|
|
} else {
|
|
|
return undefined;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const numValue = Number(value);
|
|
|
|
|
|
if (!Number.isNaN(numValue) && Math.abs(numValue) !== Infinity) {
|
|
|
if (option.equal !== undefined) {
|
|
|
if (numValue !== option.equal) {
|
|
|
throw _errJson(`${option.param} 参数必须等于 ${option.equal}`);
|
|
|
}
|
|
|
return numValue;
|
|
|
}
|
|
|
if (option.equalArr !== undefined) {
|
|
|
let result = false;
|
|
|
|
|
|
for (let item of option.equalArr) {
|
|
|
if (item === numValue) {
|
|
|
result = true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!result) {
|
|
|
throw _errJson(`${option.param} 参数必须等于 ${option.equalArr} 中的某个`);
|
|
|
}
|
|
|
return numValue;
|
|
|
}
|
|
|
|
|
|
if (option.integer === true) {
|
|
|
if (!Number.isInteger(numValue)) {
|
|
|
throw _errJson(`${option.param} 参数必须是整数`);
|
|
|
}
|
|
|
}
|
|
|
if (option.smaller !== undefined) {
|
|
|
if (!numValue < option.smaller) {
|
|
|
throw _errJson(`${option.param} 参数必须小于 ${option.smaller}`);
|
|
|
}
|
|
|
}
|
|
|
if (option.bigger !== undefined) {
|
|
|
if (!numValue > option.bigger) {
|
|
|
throw _errJson(`${option.param} 参数必须大于 ${option.bigger}`);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return numValue;
|
|
|
} else {
|
|
|
throw _errJson(`${option.param} 参数类型必须是数字或字符串数字`);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 字符串校验方法、支持数字自动转换
|
|
|
*
|
|
|
* option object类型,包含校验条件,如下
|
|
|
* require 是否必须,boolean类型,默认false不必须
|
|
|
* empty 是否可以为空字符串,boolean类型,默认true可以
|
|
|
* emptyFilter 过滤空字符串,boolean类型,true为需要过滤, 使用时empty必须为true
|
|
|
* regex 正则匹配,其值应该是'phone,email'中的一个,或是一个自定义的正则对象或正则自面量
|
|
|
* start 字符串长度大于,number类型
|
|
|
* end 字符串长度小于,number类型
|
|
|
*/
|
|
|
const _stringValid = (option) => {
|
|
|
const value = option.value;
|
|
|
|
|
|
// 设置默认值
|
|
|
option.require = option.require || false;
|
|
|
option.empty = option.empty || true;
|
|
|
|
|
|
if (value === undefined) {
|
|
|
if (option.require === true) {
|
|
|
throw _errJson(`${option.param} 参数是必须的`);
|
|
|
} else {
|
|
|
return value;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (Number.isNaN(value) || Math.abs(value) === Infinity ||
|
|
|
typeof value === 'boolean' || typeof value === 'object') {
|
|
|
throw _errJson(`${option.param} 参数类型必须是数字或字符串`);
|
|
|
}
|
|
|
|
|
|
const strValue = String(value).trim();
|
|
|
|
|
|
if (strValue === '') {
|
|
|
if (option.empty === false) {
|
|
|
throw _errJson(`${option.param} 参数不能为空`);
|
|
|
} else {
|
|
|
if (option.emptyFilter === true) {
|
|
|
return undefined;
|
|
|
}
|
|
|
return strValue;
|
|
|
}
|
|
|
}
|
|
|
if (option.regex !== undefined) {
|
|
|
switch (option.regex) {
|
|
|
case 'phone':
|
|
|
if (!/^1[0-9]{10}$/.test(strValue)) {
|
|
|
throw _errJson(`${option.param} 参数不符合手机格式`);
|
|
|
}
|
|
|
break;
|
|
|
case 'email':
|
|
|
if (!/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(strValue)) {
|
|
|
throw _errJson(`${option.param} 参数不符合邮箱格式`);
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
if (!option.regex.test(strValue)) {
|
|
|
throw _errJson(`${option.param} 参数不符合自定义格式`);
|
|
|
}
|
|
|
}
|
|
|
return strValue;
|
|
|
}
|
|
|
if (option.end !== undefined) {
|
|
|
if (!strValue.length < option.end) {
|
|
|
throw _errJson(`${option.param} 参数长度必须小于 ${option.end}`);
|
|
|
}
|
|
|
}
|
|
|
if (option.start !== undefined) {
|
|
|
if (!strValue.length > option.start) {
|
|
|
throw _errJson(`${option.param} 参数长度必须大于 ${option.start}`);
|
|
|
}
|
|
|
}
|
|
|
return strValue;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 布尔校验方法、支持字符串布尔类型自动转换
|
|
|
*
|
|
|
* option object类型,包含校验条件,如下
|
|
|
* require 是否必须,boolean类型,默认false不必需
|
|
|
* empty 是否可以为空字符串,boolean类型,默认true可以
|
|
|
* emptyFilter 过滤空字符串,boolean类型,true为需要过滤, 使用时empty必须为true
|
|
|
*/
|
|
|
const _booleanValid = (option) => {
|
|
|
const value = option.value;
|
|
|
|
|
|
// 设置默认值
|
|
|
|
|
|
option.require = option.require || false;
|
|
|
option.empty = option.empty || true;
|
|
|
|
|
|
if (value === undefined) {
|
|
|
if (option.require === true) {
|
|
|
throw _errJson(`${option.param} 参数是必须的`);
|
|
|
} else {
|
|
|
return value;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (value === '') {
|
|
|
if (option.empty === false) {
|
|
|
throw _errJson(`${option.param} 参数不能为空`);
|
|
|
} else {
|
|
|
if (option.emptyFilter === true) {
|
|
|
return undefined;
|
|
|
}
|
|
|
return value;
|
|
|
}
|
|
|
} else {
|
|
|
if (typeof value !== 'boolean' && value !== 'true' && value !== 'false') {
|
|
|
throw _errJson(`${option.param} 参数类型必须为boolean`);
|
|
|
}
|
|
|
return Boolean(value);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const _objectValid = (option) => {
|
|
|
const value = option.value;
|
|
|
|
|
|
// 设置默认值
|
|
|
option.require = option.require || false;
|
|
|
option.empty = option.empty || true;
|
|
|
|
|
|
if (value === undefined || value === null) {
|
|
|
if (option.require === true) {
|
|
|
throw _errJson(`${option.param} 参数是必须的`);
|
|
|
} else {
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
if (typeof value === 'object') {
|
|
|
let valueArr = Object.keys(value);
|
|
|
|
|
|
if (!valueArr.length) {
|
|
|
if (option.empty === false) {
|
|
|
throw _errJson(`${option.param} 参数不能为空`);
|
|
|
} else {
|
|
|
return null;
|
|
|
}
|
|
|
} else {
|
|
|
return value;
|
|
|
}
|
|
|
} else {
|
|
|
throw _errJson(`${option.param} 参数格式错误`);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/*
|
|
|
* data: 需要校验的数据对象
|
|
|
* option: 校验规则对象,eg: {'name', {type: 'string', require: true}}
|
|
|
*
|
|
|
*/
|
|
|
const valid = (data, option) => {
|
|
|
Object.keys(option).forEach(item => {
|
|
|
let opt = option[item];
|
|
|
|
|
|
opt.value = data[item];
|
|
|
opt.param = item;
|
|
|
|
|
|
switch (opt.type) {
|
|
|
case 'number':
|
|
|
data[item] = _numberValid(opt);
|
|
|
if (data[item] === undefined) {
|
|
|
delete data[item];
|
|
|
}
|
|
|
break;
|
|
|
case 'string':
|
|
|
data[item] = _stringValid(opt);
|
|
|
if (data[item] === undefined) {
|
|
|
delete data[item];
|
|
|
}
|
|
|
break;
|
|
|
case 'boolean':
|
|
|
data[item] = _booleanValid(opt);
|
|
|
if (data[item] === undefined) {
|
|
|
delete data[item];
|
|
|
}
|
|
|
break;
|
|
|
case 'object':
|
|
|
data[item] = _objectValid(opt);
|
|
|
if (data[item] === undefined) {
|
|
|
delete data[item];
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
return data;
|
|
|
};
|
|
|
|
|
|
module.exports = valid; |
...
|
...
|
|