生产力有两项,一项是人,一项是工具。工具用得好不好,决定我们下班早不早。
前言
我们在业务开发过程中,经常会重复用到数据类型校验,日期格式化、数据加密、随机数生成、节流函数等工具方法,这些工具类函数,适当封装整理方便拿来就用,可以提高开发效率。
数据类型校验
也许你喜欢把方法封装成 ES6 Class 的 method,但是考虑到使用的时候还需要实例化比较麻烦(当然写成 static method 也可以),不过我还是习惯把方法挂在对象的属性上,如下:
const Validator = {};
/**
* 判断是否是数字, 如:'123.1' 、123.1 都是true
*
* @static
* @param {any} value
* @returns
*/
Validator.isNumber = (value) => {
const re = /^[0-9]+\.?[0-9]*$/;
return re.test(value);
};
/**
* 整形数字: 2=true; '2'=true
*
* @static
* @param {any} value
* @returns
*/
Validator.isIntNumber = (value) => {
if (value === '0' || value === 0) {
return true;
}
const re = /^[1-9]+[0-9]*]*$/;
return re.test(value);
};
/**
* 整形数 2 = true; '2' = false
* 这个方法会严格区分string类型的数字
* @static
* @param {any} val
* @returns
*/
Validator.isInt = (val) => {
if (Validator.isIntNumber(val)) {
return typeof val === 'number';
}
return false;
};
/**
* 是不是浮点型, 如:'123.1' = false 、123.1 = true
*
* @static
* @param {any} value
* @returns
*/
Validator.isFloat = (value) => {
const result = Validator.isNumber(value);
return result && parseFloat === value;
};
/**
* 时间戳判断
*
* @static
* @param {any} value
* @returns
*/
Validator.isTimestamp = (value) => {
return typeof value === 'number';
};
/**
* 验证手机号
*
* @static
* @param {any} value
* @returns
*/
Validator.isPhone = (value) => {
const reg = /^0?(1[34578])[0-9]{9}$/;
return reg.test(value);
};
/**
* Url验证
*
* @static
* @param {any} value
* @returns
*/
Validator.isUrl = (value) => {
const strRegex = /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/;
return strRegex.test(value);
};
/**
* 是否大写字母
*
* @static
* @param {any} value
* @returns
*/
Validator.isCapital = (value) => {
const reg = /[A-Z]/;
return reg.test(value);
};
/**
* 是否为空
*
* @static
* @param {any} value
* @returns
*/
Validator.isEmpty = (value) => {
// return value?true:false;
return !!value;
};
/**
* 是否是一个对象
*
* @static
* @param {any} value 要判断的对象
* @returns
*/
Validator.isObject = (value) => {
const keys = Object.keys(value);
const values = Object.values(value);
console.log('is object typeof value is:', typeof value);
return keys.length > 0 && values.length > 0 && typeof value === 'object';
};
/**
* 是否为空
*
* @static
* @param {any} value
* @returns
*/
Validator.isNotEmpty = (value) => {
return !this.isEmpty(value);
};
Validator.isMobilePhone = (value) => {
const reg = /^(\+?0?86\-?)?1[345789]\d{9}$/;
return reg.test(value);
};
/**
* 是否是monogoDB里的objectId值
*
* @static
* @param {any} value
* @returns
*/
Validator.isMongoDBObjectId = (value) => {
return objectId.isValid(value);
};
/**
* 此方法特殊方法。obj只能传一个对象。
*
* @static
* @param {any} obj 对象
* @param {any} value 值
*/
Validator.isObjectValue = (obj, value) => {
if (!Validator.isObject(obj)) {
return false;
}
return Object.values(obj).includes(value);
};
/**
* 检测邮箱
* @param email
* @returns {boolean}
*/
Validator.testEmail = (email) => {
const reg = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
return reg.test(email);
};
/**
* 身份证号码验证
*
* @param cardNo {String} 证件号码
* @returns info {Object} 身份证信息.
*
*/
Validator.getIdCardInfo = (cardNo) => {
const info = {
isTrue: false, // 身份证号是否有效。默认为 false
year: null, // 出生年。默认为null
month: null, // 出生月。默认为null
day: null, // 出生日。默认为null
isMale: false, // 是否为男性。默认false
isFemale: false, // 是否为女性。默认false
};
if (!cardNo && cardNo.length !== 15 && cardNo.length !== 18) {
info.isTrue = false;
return info;
}
if (cardNo.length === 15) {
const year = cardNo.substring(6, 8);
const month = cardNo.substring(8, 10);
const day = cardNo.substring(10, 12);
const p = cardNo.substring(14, 15); // 性别位
const birthday = new Date(year,
parseFloat(month) - 1,
parseFloat(day), 12, 0, 0, 0);
// 对于老身份证中的年龄则不需考虑千年虫问题而使用getYear()方法
if (birthday.getYear() !== parseFloat(year) ||
birthday.getMonth() !== parseFloat(month) - 1 ||
birthday.getDate() !== parseFloat(day)) {
info.isTrue = false;
} else {
info.isTrue = true;
info.year = birthday.getFullYear();
info.month = birthday.getMonth() + 1;
info.day = birthday.getDate();
if (p % 2 === 0) {
info.isFemale = true;
info.isMale = false;
} else {
info.isFemale = false;
info.isMale = true;
}
}
return info;
}
if (cardNo.length === 18) {
const year = cardNo.substring(6, 10);
const month = cardNo.substring(10, 12);
const day = cardNo.substring(12, 14);
const p = cardNo.substring(14, 17);
const birthday = new Date(year,
parseFloat(month) - 1,
parseFloat(day), 12, 0, 0, 0);
// 这里用getFullYear()获取年份,避免千年虫问题
if (birthday.getFullYear() !== parseFloat(year) ||
birthday.getMonth() !== parseFloat(month) - 1 ||
birthday.getDate() !== parseFloat(day)) {
info.isTrue = false;
return info;
}
const Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1]; // 加权因子
const Y = [1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2]; // 身份证验证位值.10代表X
// 验证校验位
let sum = 0; // 声明加权求和变量
const _cardNo = cardNo.split('');
if (_cardNo[17].toLowerCase() === 'x') {
_cardNo[17] = 10; // 将最后位为x的验证码替换为10方便后续操作
}
for (let i = 0; i < 17; i++) {
sum += Wi[i] * _cardNo[i]; // 加权求和
}
const i = sum % 11; // 得到验证码所位置
if (_cardNo[17] !== Y[i]) {
info.isTrue = false;
return info;
}
info.isTrue = true;
info.year = birthday.getFullYear();
info.month = birthday.getMonth() + 1;
info.day = birthday.getDate();
if (p % 2 === 0) {
info.isFemale = true;
info.isMale = false;
} else {
info.isFemale = false;
info.isMale = true;
}
return info;
}
return info;
};
module.exports = Validator;
日期格式化
需要引入一个package,moment用来处理时间比较方便。
const moment = require('moment');
const DateHandler = {};
/**
* 获取现在时间(13位时间戳) 1641185119507
* @returns {number|*}
*/
DateHandler.getNowTime = () => {
return new Date().getTime();
};
/**
* 格式化时间戳
* @param timestamp
* @param patten
*/
DateHandler.formatDate = (timestamp, patten) => {
console.log(timestamp);
return moment(timestamp).format(patten);
};
/**
* excel读取2018/01/01这种时间格式是会将它装换成数字类似于46254.1545151415
* @param numb numb是传过来的整数数字
* @param format 是之间间隔的符号
* @returns {string}
*/
DateHandler.formatExcelDate = (numb, format) => {
const time = new Date((numb - 1) * 24 * 3600000 + 1);
time.setYear(time.getFullYear() - 70);
const year = `${time.getFullYear()}`;
const month = `${time.getMonth() + 1}`;
const date = `${time.getDate() - 1}`;
if (format && format.length === 1) {
return year + format + month + format + date;
}
return year + (month < 10 ? `0${month}` : month) + (date < 10 ? `0${date}` : date);
};
/**
* 毫秒格式化
* @param t (ms)
* @returns {string}
*/
DateHandler.formatTime = (t) => {
const HOUR = 1000 * 60 * 60;
const d = parseInt(t / (HOUR * 24));
const h = parseInt((t % (HOUR * 24)) / (HOUR));
const m = parseInt((t % (HOUR)) / (1000 * 60));
const s = parseInt((t % (1000 * 60)) / 1000);
let text = '';
d && (text += `${d}天`);
h && (text += `${h}小时`);
m && (text += `${m}分`);
s && (text += `${s}秒`);
return text || '-';
};
module.exports = DateHandler;
随机数生成
需要用到的package有,randomstring,lodash,dateformat
const randomstring = require('randomstring');
const dateformat = require('dateformat');
const _ = require('lodash');
/**
* an integer between start and end
* @param start
* @param end
* @returns {number}
* @constructor
*/
NumHandler.Random = (start, end) => {
return _.random(start, end);
};
NumHandler.removeEmptyField = (list, field) => {
list.forEach(v => (v[field].length === 0 ? delete v[field] : this.removeEmptyField(v[field], field)));
return list;
};
/**
* 生成随机编号
* @param n 位数
* @param collection
* @returns {string}
*/
NumHandler.generateRandom = (n, collection = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']) => {
let res = '';
for (let i = 0; i < n; i++) {
const id = Math.ceil(Math.random() * (collection.length - 1));
res += collection[id];
}
return res;
};
const Collection_Num = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
NumHandler.generateUUID = () => {
const Collection_Alpha = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
return NumHandler.generateRandom(31, Collection_Num.concat(Collection_Alpha));
};
/**
* 生成订单编号
*
* @static
*/
NumHandler.generateOrderCode = () => {
const time = dateformat(this.getNowTime(), 'yyyymmddHHMMss');
const randNumber = this.generateRandom(3, Collection_Num);
return `${time}${randNumber}`;
};
/**
* 生成序列号
*
* @static
* @returns
*/
NumHandler.generateSerNum = () => {
const time = dateformat(this.getNowTime(), 'yyyymmddHHMMss');
const randomNum = randomstring.generate({ length: 12, charset: 'numeric' });
return `${time}2${randomNum}`;
};
module.exports = NumHandler;
总结
工欲善其事必先利其器。有了属于自己的这把利器,也许才能在抗议加班的时候不至于太怂~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。