大家好!我叫戴向天
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)
}
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{
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(['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`)
}
// demo 數據
const data = {
note: '無',
tips: {
name: '戴向天',
grilfriend:'clover'
},
user: {
parents: {
father: {
children: {
fristName: '向天',
lastName: '戴',
telPhone: '15072939115',
homeTel: '020-12345678',
birthd:'2019-10-09',
email:'[email protected]'
}
}
}
},
formData: [
[{
age: '25'
}]
],
other:function(){}
}
// demo 數據
const data = {
note: '無',
tips: {
name: '戴向天aa',
englishName: 'aaaa',
grilfriend:'clover',
special: 'aaa!',
id: '4202221996xxxxxxxxx'
},
user: {
parents: {
father: {
children: {
fristName: '向天',
lastName: '戴',
telPhone: '15072939115',
homeTel: '020-12345678',
birthd:'2019-10-09',
email:'[email protected]'
}
}
}
},
formData: [
[{
age: 25
}]
],
other:function(){}
}
// 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)