大家好!我叫戴向天
QQ群:602504799
QQ:809002582
/**
@Author 戴向天
@English Name Clover
@Frist date 2019-08-08
@Last update date 2020-05-19
@Last date 2020-05-19
@Tips
Ver option's type undetermined
date & json & funciton
@arguments
method one
option
data:需要判断的数据 json | array | string | number | null | boolean
ver:[ 需要效验的字段
'name', //需要效验的key名
{
key:'age', //需要效验的key名
type:'number', //判断数据是否为指定为类型 type的参数:String | number | string | array | date | tel | zuoji(座机|固话) | json | funciton | email
tips:'请输入正确的年龄',//数据错误回馈信息
},{
key:'createTime',
type:'date'
},{
key:'telephone',
type:'tel'
},{
key:'note',
type:'string',
trim:true
}]
method two
arg[0]: 需要判断的数据 json | array | string | number | null | boolean
arg[1]: 需要效验的字段 array | string | number | boolean
Tips: 如果是ts文件 请把参数改为 (a: any = null, b: any = null)
2019-10-08 Update log
1.修复判断不严谨的bug 不能深入查询进行判断
2.新增type类型:date、json、function、
3.当需要判断的字段数据里面没有的时候会进行提错误,没有指定的字段名
4.ver 新增单字符串的字段
2020-05-19 Update log
1.可多个效验条件 --- type可为数组,字符串
2.新增效验条件: 汉字(纯,包含),特殊字符串(包含),字母(纯,包含),身份证号码
3.加上限制提交(类似于禁止条件,例如禁止有汉子,禁止有特殊字符)
4.关于tips提示可以为字符串和数据,(若是多个效验条件,将按照一一对应的方式进行提示,若有多个效验条件,而tips是字符串则只返回字符串)
5.另外加上限制提示语
6.可自定义效验方式:会将效验的结果返回给 resulr 函数,参数(结果,当前正在效验的值,当前的效验条件)
*/
function verification(a, b) {
const
// 获取数据类型的方法
getType = (o, s = null) => {
let t = Object.prototype.toString.call(o).split(' ')[1]
t = t.substring(0, t.length - 1).trim().toLowerCase()
if (t === 'object' && Object.prototype.toString.call(o).toLowerCase() === '[object object]' && !o.length) t = 'json'
return s ? t === s : t
}
// 获取包含指定k的对象
const findData = (item, k) => {
let arr = []
for (let d in item) {
if (d === k) {
arr.push(item[d])
} else if (getType(item[d], 'json') || getType(item[d], 'array')) {
arr = arr.concat(findData(item[d], k))
}
}
return arr
}
const rule = (it, k, v, r) => {
let bool = true;
let isJson = getType(it[k], 'json')
switch (k) {
case 'tel': // 手机号
bool = /^((\+?86)|(\(\+86\)))?(13[012356789][0-9]{8}|15[012356789][0-9]{8}|18[02356789][0-9]{8}|147[0-9]{8}|1349[0-9]{7})$/.test(v) || (isJson ? it[k].tips : it.tips || false)
break
case 'zuoji': // 座机
bool = /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(v) || (isJson ? it[k].tips : it.tips || false)
break
case 'email': // 邮箱
bool = /^([a-zA-Z]|[0-9])(\w|\\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(v) || (isJson ? it[k].tips : (it.tips || false))
break
case 'date': // 日期
bool = (isNaN(v) && !isNaN(Date.parse(v))) || (isJson ? it[k].tips : it.tips || false)
break
case 'json': // json
bool = getType(v, 'json') || (isJson ? it[k].tips : it.tips || false)
break
case 'function': // 函数
bool = getType(v, 'function') || (isJson ? it[k].tips : it.tips || false)
break
case 'number': // 纯数字
bool = getType(+v, 'number') || (isJson ? it[k].tips : it.tips || false)
break
case 'hasNumber': // 包含数字
bool = /\d/.test(v) || (isJson ? it[k].tips : it.tips || false)
break
case 'word': // 纯汉字
bool = /^[\u4e00-\u9fa5]+$/.test(v) || (isJson ? it[k].tips : (it.tips || false))
break;
case 'hasWord': // 包含汉字
bool = /[\u4E00-\u9FA5]/g.test(v) || (isJson ? it[k].tips : (it.tips || false))
break;
case 'letter': // 纯字母
bool = /^[a-zA-Z]+$/.test(v) || (isJson ? it[k].tips : (it.tips || false))
break;
case 'hasLetter': // 包含字母
bool = /[a-zA-Z]/g.test(v) || (isJson ? it[k].tips : (it.tips || false))
break;
case 'hasSpecialCharacters': // 包含特殊符号
bool = new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>《》/?~!@#¥……&*()——|{}【】‘;:”“'。,、? ]").test(v) || (isJson ? it[k].tips : (it.tips || false))
break;
case 'id': // 身份证号码
bool = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(v) || (isJson ? it[k].tips : (it.tips || false))
break;
default: // 普通判断
bool = getType(v, k) || (isJson ? it[k].tips : it.tips || false)
}
if(bool === true)return bool
return r ? (getType(bool, 'array') || getType(bool, 'string') || bool === false) : bool;
}
// 单独的效验判断 (还未完善)
const judge = (item, v) => {
let bool = true
let getJudgeResult = (it, k) => {
if (bool === true) {
let isJson = getType(it[k], 'json')
let val = isJson ? it[k].value : it[k]
if (k === 'type') {
let isTypeArray = getType(val, 'array');
if (isTypeArray) {
for (let s = 0; s < val.length; s++) {
if (bool === true) {
bool = rule(it, val[s], v)
if (getType(bool, 'array')) {
if (bool[s]) {
bool = bool[s]
} else if (bool[0]) {
bool = bool[0]
}
}
} else {
break;
}
}
} else {
bool = rule(it, val, v)
}
} else if (it[k] && (it[k] + '').toString()) {
if (condition[k]) {
bool = condition[k](val) || (isJson ? it[k].tips : it.tips || false)
} else if (k === 'limit') {
if (getType(it[k], 'array')) {
for (let s = 0; s < val.length; s++) {
if (bool === true) {
bool = rule(it, val[s], v, true)
if (!bool && it.limitTips) {
if (getType(it.limitTips, 'array')) {
bool = it.limitTips[s] || it.limitTips[0] || false
} else {
bool = it.limitTips || false
}
}else if(!bool && it.tips){
bool = it.tips || false
}
} else {
break;
}
}
} else {
bool = rule(it, val, v, true)
if (!bool && it.limitTips) {
if (getType(it.limitTips, 'array')) {
bool = it.limitTips[0] || false
} else {
bool = it.limitTips || false
}
}else if(!bool && it.tips){
bool = it.tips || false
}
}
} else if (['limitTips'].indexOf(k) < 0) {
console.warn(`Have not ${k} attribute at present. You can join QQ Group Provide advice. QQ Group: 602504799. Welcome you join.`)
}
} else {
bool = isJson ? it[k].tips : it.tips || false
}
}
return bool
}
const condition = {
// 数字判断
min: (val) => v >= val,
max: (val) => v <= val,
value: (val) => v == val,
// 字符串判断
minLength: (val) => v.toString().length >= val,
maxLength: (val) => v.toString().length <= val,
length: (val) => v.toString().length === val
}
if (getType(item, 'string')) {
bool = !!item
} else {
for (let key in item) {
if (key === 'tips' || key === 'key') {
const arr = findData(data, item.key)
if (arr.length) {
for (let i = 0; i < arr.length; i++) {
if (bool === true && !arr[i]) {
bool = item.tips || false
}
}
} else {
console.warn(`Data have not field is '${getType(item, 'string') ? item : item.key}'`)
}
} else {
getJudgeResult(item, key)
}
}
}
return bool
}
// 获取结果值
const getResult = () => {
let bool = true
for (let k in ver) {
const item = ver[k]
if (bool === true) {
const arr = getType(item, 'string') ? findData(data, item) : findData(data, item.key)
if (arr.length) {
for (let i = 0; i < arr.length; i++) {
const v = arr[i] || ''
bool = judge(item, v)
if (item.result && getType(item.result, 'function')) {
bool = item.result(bool, v, item)
}
}
} else {
console.warn(`Data have not field is '${getType(item, 'string') ? item : item.key}'`)
}
} else {
return bool
}
}
return bool
}
// 效验条件处理
const verHandle = {
string: () => data === ver,
number: () => data === ver,
json: () => getResult(),
array: () => getResult()
}
// 获取所有的参数
const arg = arguments
// 如果没有参数就直接返回false
if (!arg.length) return false
// 获取正确的data
const data = arg.length > 1 ? arg[0] : arg[0].data
const ver = arg.length > 1 ? arg[1] : arg[0].ver
return data
? ver
? verHandle[getType(ver)]()
: console.warn(`verification error: param ver is ${ver},can't verification`)
: console.warn(`verification error: param data is ${data},can't verification`)
}
export default verification
// demo 验证测试
const result = verification({
data,
ver: [
'grilfriend',
{
key: 'special',
type: 'hasSpecialCharacters',
tips: '必须含有特殊字符'
},{
key: 'id',
type: 'id',
tips: 'id必须是身份证号码'
},
{
key: 'note',
tips: '请输入备注',
result:(res,value,item)=>{
return res
}
}, {
key: 'name',
tips: ['请输入名字,并且包含汉字','请输入名字,并且包含字母'],
type: ['hasWord','hasLetter'],
limit: 'hasSpecialCharacters',
limitTips: '名字不允许含有特殊字符',
}, {
key: 'englishName',
type: 'letter',
tips: '英文名词必须是全字母'
},{
key: 'age',
tips: '请输入年龄',
type: {
value: 'number',
tips: '年龄必须是数字类型'
},
min: {
value: 20,
tips: '年龄不能小于20岁'
},
max: {
value: 30,
tips: '年龄不能大于30岁'
},
value: {
value: 25,
tips: '年龄必须是25岁'
}
}, {
key: 'fristName',
tips: '请输入名'
}, {
key: 'lastName',
tips: '请输入姓'
}, {
key: 'telPhone',
tips: '请输入正确的手机号',
type: 'tel'
}, {
key: 'homeTel',
tips: '请输入正确的座机号码',
type: 'zuoji'
},{
key:'birthd',
type:'date',
tips:'请选择生日'
},{
key:'email',
type:'email',
tips:'请输入邮箱'
},{
key:'children',
type:'json',
tips:'children字段必须是json格式'
},{
key:'other',
type:'function',
tips:'other字段必须是一个函数'
}]
})
// demo 输出验证结果
console.log('result=>', result)