const Utils = {
_typeof(obj) {
return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
},
isString(o) { //是否字符串
return Utils._typeof(o) === 'string'
},
isNumber(o) { //是否数字
return Utils._typeof(o) === 'number'
},
isBoolean(o) { //是否boolean
return Utils._typeof(obj) === 'boolean'
},
isFunction(o) { //是否函数
return Utils._typeof(o) === 'function'
},
isNull(o) { //是否为null
return Utils._typeof(o) === 'null'
},
isUndefined(o) { //是否undefined
return Utils._typeof(o) === 'undefined'
},
isArray(o) { //是否数组
return Utils._typeof(o) === 'array'
},
isDate(o) { //是否时间
return Utils._typeof(o) === 'date'
},
/*是否是纯粹的对象*/
isPlainObject(obj) {
return Utils._typeof(obj) === 'object';
},
isString(obj) {
return typeof (obj) === 'string';
},
/*是否是空数组*/
isNonEmptyArray(obj = []) {
return obj && obj.length > 0 && Array.isArray(obj) && typeof obj !== 'undefined';
},
/*是否是对象*/
isObject(item) {
return (item && typeof item === 'object' && !Array.isArray(item));
},
/*是否是空对象*/
isEmptyObject(obj) {
return Object.keys(obj).length === 0 && obj.constructor === Object;
},
//对象是否包含某属性
isIncludeAttr(obj, attr) {
//判断是否有该键值
if (obj && obj.hasOwnProperty(attr)) {
//如果有返回true
return true;
}
return false;
},
decodeIconFont(text) {
// 正则匹配 图标和文字混排 eg: 我去上学校,天天不迟到
const regExp = /[a-z|0-9]{4,5};?/g;
if (regExp.test(text)) {
return text.replace(new RegExp(regExp, 'g'), function (iconText) {
const replace = iconText.replace(//, '0x').replace(/;$/, '');
return String.fromCharCode(replace);
});
} else {
return text;
}
},
/*深拷贝*/
mergeDeep(target) {
let tempObj = Array.isArray(target) ? [] : {};
for (let key in target) {
tempObj[key] = Utils.isObject(target[key]) ? Util.mergeDeep(target[key]) : target[key];
}
return tempObj;
},
/**
* 分割数组
* @param arr 被分割数组
* @param size 分割数组的长度
* @returns {Array}
*/
arrayChunk(arr = [], size = 4) {
let groups = [];
if (arr && arr.length > 0) {
groups = arr.map((e, i) => {
return i % size === 0 ? arr.slice(i, i + size) : null;
}).filter(e => {
return e;
});
}
return groups;
},
/*
* 截断字符串
* @param str 传入字符串
* @param len 截断长度
* @param hasDot 末尾是否...
* @returns {String}
*/
truncateString(str, len, hasDot = true) {
let newLength = 0;
let newStr = '';
let singleChar = '';
const chineseRegex = /[^\x00-\xff]/g;
const strLength = str.replace(chineseRegex, '*').length;
for (let i = 0; i < strLength; i++) {
singleChar = str.charAt(i).toString();
if (singleChar.match(chineseRegex) !== null) {
newLength += 2;
} else {
newLength++;
}
if (newLength > len) {
break;
}
newStr += singleChar;
}
if (hasDot && strLength > len) {
newStr += '...';
}
return newStr;
},
/*
* 转换 obj 为 url params参数
* @param obj 传入对象
* @param isEncodeURIComponent 是否编码,默认不编码
* @returns {String}
* eg. objToParams({name:'大佬',age:18})
*/
objToParams(obj, isEncodeURIComponent = false) {
let str = "";
for (let key in obj) {
if (str !== "") {
str += "&";
}
str += key + "=" + (isEncodeURIComponent ? encodeURIComponent(obj[key]) : obj[key]);
}
return str;
},
/*
* 转换 url params参数为obj
* @param str 传入url参数字符串
* @param isDecodeURI 是否解码,默认不解码
* @returns {Object}
* eg. paramsToObj('http://www.cctv.com?name=大佬&age=18')
*/
paramsToObj(str, isDecodeURI = false) {
let obj = {};
str = str.substring(str.indexOf('?') + 1);
try {
obj = JSON.parse('{"' + (isDecodeURI ? decodeURI(str) : str).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}')
} catch (e) {
console.log(e);
}
return obj;
},
/*
*保留n位小数
*@param num {Number|String} 原数字 1.33或者'1.33'
*@returns {String} 返回字符串
*/
toThousands(num, n) {
return parseFloat(num).toFixed(n).replace(/(\d{1,3})(?=(\d{3})+(?:\.))/g, "$1,");
},
/*
*生成两位整数之间的随机整数(包括两端的整数 )
*
**/
randomA(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
},
/*
*生成两位整数之间的随机整数(不包括两端的整数)
*
**/
randomB(min, max) {
min += 1, max -= 1;
return Math.floor(Math.random() * (max - min + 1)) + min;
},
/*时间格式化*/
formatTime(obj, format) {
if (format) {
var date;
if (obj instanceof Date) {
date = obj;
} else {
date = new Date(obj);
}
var dayNames = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日',]
var o = {
'M+': date.getMonth() < 9 ? "0" + (date.getMonth() + 1) : (date.getMonth() + 1), // 月份
'd+': date.getDate() < 10 ? "0" + date.getDate() : date.getDate(), // 日
'h+': date.getHours(), // 小时
'm+': date.getMinutes(), // 分
's+': date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds(), // 秒
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
'S+': date.getMilliseconds(), // 毫秒
'D+': dayNames[date.getDay()], //星期
};
if (/(y+)/.test(format)) format = format.replace(RegExp.$1, (`${date.getFullYear()}`).substr(4 - RegExp.$1.length));
for (var k in o) {
if (new RegExp(`(${k})`).test(format)) {
format = format.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : ((`
00${o[k]}`).substr((`${o[k]}`).length)));
}
}
return format;
} else {
let date = new Date(obj)
let _year = date.getFullYear(),
_month = (date.getMonth() + 1) > 9 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1),
_date = date.getDate(),
_hour = date.getHours(),
_minute = date.getMinutes(),
_second = date.getSeconds()
return _year + '-' + _month + '-' + _date + ' ' + _hour + ':' + _minute + ':' + _second
}
},
/*去掉首尾空格*/
trimStr(str) {
return str.replace(/(^\s*)|(\s*$)/g, "");
},
/*正则匹配*/
checkStr(str, type) {
switch (type) {
case 'phone': //手机号码
return /^1[3|4|5|6|7|8|9][0-9]{9}$/.test(str);
case 'tel': //座机
return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(str);
case 'card': //身份证
return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(str);
case 'pwd': //密码以字母开头,长度在6~18之间,只能包含字母、数字和下划线
return /^[a-zA-Z]\w{5,17}$/.test(str)
case 'postal': //邮政编码
return /[1-9]\d{5}(?!\d)/.test(str);
case 'QQ': //QQ号
return /^[1-9][0-9]{4,9}$/.test(str);
case 'email': //邮箱
return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str);
case 'money': //金额(小数点2位)
return /^\d*(?:\.\d{0,2})?$/.test(str);
case 'URL': //网址
return /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/.test(str)
case 'IP': //IP
return /((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))/.test(str);
case 'date': //日期时间
return /^(\d{4})\-(\d{2})\-(\d{2}) (\d{2})(?:\:\d{2}|:(\d{2}):(\d{2}))$/.test(str) || /^(\d{4})\-(\d{2})\-(\d{2})$/.test(str)
case 'number': //数字
return /^[0-9]$/.test(str);
case 'positiveInteger': //正整数
return /^[1-9]\d*$/.test(str);
case 'price': //价格
return /(^[1-9]\d*(\.\d{1,2})?$)|(^0(\.\d{1,2})?$)/.test(str);//价格非0则去掉'?'
case 'english': //英文
return /^[a-zA-Z]+$/.test(str);
case 'chinese': //中文
return /^[\u4E00-\u9FA5]+$/.test(str);
case 'lower': //小写
return /^[a-z]+$/.test(str);
case 'upper': //大写
return /^[A-Z]+$/.test(str);
case 'HTML': //HTML标记
return /<("[^"]*"|'[^']*'|[^'">])*>/.test(str);
default:
return true;
}
},
/**
* @param {s} 秒数
* @return {String} 字符串
*
* @example formatHMS(3610) // -> 1h0m10s
*/
formatHMS(s) {
var str = ''
if (s > 3600) {
str = Math.floor(s / 3600) + 'h' + Math.floor(s % 3600 / 60) + 'm' + s % 60 + 's'
} else if (s > 60) {
str = Math.floor(s / 60) + 'm' + s % 60 + 's'
} else {
str = s % 60 + 's'
}
return str
},
//根据月份获取起止时间戳
getTimeFromMonth(year, month) {
return [
new Date(year, month - 1, 1).getTime() / 1000,
new Date(year, month, 0).getTime() / 1000
]
},
//根据日期获取一天起止时间戳
getTimeFromDay(year, month, day) {
return [
new Date(year, month - 1, day).getTime() / 1000,
new Date(year, month - 1, (day + 1)).getTime() / 1000
]
},
/*数组删除指定元素*/
remove(arr, ele) {
var index = arr.indexOf(ele);
if (index > -1) {
arr.splice(index, 1);
}
return arr;
},
// 数组求并集
union(a, b) {
return [...new Set([...a, ...b])];
},
// 数组求交集
intersect(a, b) {
return [...new Set([...a].filter(x => b.includes(x)))];
},
//数组求差集
difference(a, b) {
return [...new Set([...a].filter(x => !b.includes(x)))];
},
//数组内部交换
internalExchange(n, m, arr) {
[arr[n], arr[m]] = [arr[m], arr[n]];
},
//数组去重
Deduplication(arr) {
return [...new Set([...arr])]
},
/*数组最大值*/
max(arr) {
return Math.max.apply(null, arr);
},
/*数组最小值*/
min(arr) {
return Math.min.apply(null, arr);
},
//字符串首字母变大写
changeIndexToUpperCase(str) {
return str.replace(/\b\w+\b/g, function (word) {
return word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase();
});
},
//float偏移处理 eg. 1.67*100结果会偏移,使用mul(1.67*100)
mul(a, b) {
let c = 0,
d = a.toString().replace(',', ''),
e = b.toString();
try {
c += d.split(".")[1].length;
} catch (f) {
}
try {
c += e.split(".")[1].length;
} catch (f) {
}
return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
},
//格式化价格,12345.1 =》 12,345.10
formatePrice(value) {
value = (value + '').replace(/\.\d{2}(\d*)/, (match, $1) => match.replace($1, ''))//强制截取两位小数
if (isNaN(value)) {
return ''
} else {
//补0
var s = value.toString();
var rs = s.indexOf('.');
if (rs < 0) {
rs = s.length;
s += '.';
}
while (s.length <= rs + 2) {
s += '0';
}
}
//千分位打逗号
return (s + '').replace(/(\d{1,3})(?=(\d{3})+(?:$|\.))/g, "$1,");
},
//emoji判断
isEmojiCharacter(substring) {
for (var i = 0; i < substring.length; i++) {
var hs = substring.charCodeAt(i);
if (0xd800 <= hs && hs <= 0xdbff) {
if (substring.length > 1) {
var ls = substring.charCodeAt(i + 1);
var uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
if (0x1d000 <= uc && uc <= 0x1f77f) {
return true;
}
}
} else if (substring.length > 1) {
var ls = substring.charCodeAt(i + 1);
if (ls == 0x20e3) {
return true;
}
} else {
if (0x2100 <= hs && hs <= 0x27ff) {
return true;
} else if (0x2B05 <= hs && hs <= 0x2b07) {
return true;
} else if (0x2934 <= hs && hs <= 0x2935) {
return true;
} else if (0x3297 <= hs && hs <= 0x3299) {
return true;
} else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030
|| hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b
|| hs == 0x2b50) {
return true;
}
}
}
},
//解决计算偏移 eg. 1.67 - 1 = 0.66999999999 ,改用 accSub(1.67 - 1)
//加法偏移
accAdd(arg1, arg2) {
var r1, r2, m;
try {
r1 = arg1.toString().split(".")[1].length;
}
catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
}
catch (e) {
r2 = 0;
}
m = Math.pow(10, Math.max(r1, r2));
return (arg1 * m + arg2 * m) / m;
}
//减法函数
accSub(arg1, arg2) {
var r1, r2, m, n;
try {
r1 = arg1.toString().split(".")[1].length;
}
catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
}
catch (e) {
r2 = 0;
}
m = Math.pow(10, Math.max(r1, r2));
//last modify by deeka
//动态控制精度长度
n = (r1 >= r2) ? r1 : r2;
return ((arg1 * m - arg2 * m) / m).toFixed(n);
}
//除法
accDiv(arg1, arg2) {
var t1 = 0, t2 = 0, r1, r2;
try {
t1 = arg1.toString().split(".")[1].length;
}
catch (e) {
}
try {
t2 = arg2.toString().split(".")[1].length;
}
catch (e) {
}
r1 = Number(arg1.toString().replace(".", ""));
r2 = Number(arg2.toString().replace(".", ""));
return (r1 / r2) * Math.pow(10, t2 - t1);
}
//乘法
accMul(a, b) {
let c = 0,
d = a.toString().replace(',', ''),
e = b.toString();
try {
c += d.split(".")[1].length;
} catch (f) {
}
try {
c += e.split(".")[1].length;
} catch (f) {
}
return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
}
// 获取两点直线距离
getDistance(lat1, lng1, lat2, lng2) {
var lon1 = (Math.PI / 180) * lng1
var lon2 = (Math.PI / 180) * lng2
lat1 = (Math.PI / 180) * lat1
lat2 = (Math.PI / 180) * lat2
// 地球半径
var R = 6371
// 两点间距离 km,如果想要米的话,结果*1000就可以了
var d = Math.acos(Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1)) *
R
return d.toFixed(1)
}
}