Files
jczxw-java/src/components/ele-admin-pro/packages/util.js
2021-08-06 16:12:31 +08:00

524 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/** 常用工具方法 license by http://eleadmin.com */
/**
* 倒计时
* @param endTime 结束时间
* @param serverTime 服务端当前时间
* @param callback 回调
* @returns {number} 定时器实例
*/
export function countdown(endTime, serverTime, callback) {
let type = typeof serverTime === 'function',
end = new Date(endTime).getTime(),
now = new Date((!serverTime || type) ? new Date().getTime() : serverTime).getTime(),
count = end - now,
time = [
Math.floor(count / (1000 * 60 * 60 * 24)), // 天
Math.floor(count / (1000 * 60 * 60)) % 24, // 时
Math.floor(count / (1000 * 60)) % 60, // 分
Math.floor(count / 1000) % 60 // 秒
];
if (type) {
callback = serverTime;
}
let timer = setTimeout(() => {
this.countdown(endTime, now + 1000, callback);
}, 1000);
callback && callback(count > 0 ? time : [0, 0, 0, 0], serverTime, timer);
if (count <= 0) {
clearTimeout(timer);
}
return timer;
}
/**
* 时间语义化
* @param time 时间
* @param onlyDate 超过30天是否仅返回日期
* @returns {string}
*/
export function timeAgo(time, onlyDate) {
if (!time) {
return '';
}
if (typeof time === 'string') {
time = time.replace(/-/g, '/');
}
let arr = [[], []],
stamp = new Date().getTime() - new Date(time).getTime();
// 30天以上返回具体日期
if (stamp > 1000 * 60 * 60 * 24 * 31) {
stamp = new Date(time);
arr[0][0] = this.digit(stamp.getFullYear(), 4);
arr[0][1] = this.digit(stamp.getMonth() + 1);
arr[0][2] = this.digit(stamp.getDate());
// 是否输出时间
if (!onlyDate) {
arr[1][0] = this.digit(stamp.getHours());
arr[1][1] = this.digit(stamp.getMinutes());
arr[1][2] = this.digit(stamp.getSeconds());
}
return arr[0].join('-') + ' ' + arr[1].join(':');
}
if (stamp >= 1000 * 60 * 60 * 24) {
return ((stamp / 1000 / 60 / 60 / 24) | 0) + '天前';
} else if (stamp >= 1000 * 60 * 60) {
return ((stamp / 1000 / 60 / 60) | 0) + '小时前';
} else if (stamp >= 1000 * 60 * 3) {
return ((stamp / 1000 / 60) | 0) + '分钟前';
} else if (stamp < 0) {
return '未来';
} else {
return '刚刚';
}
}
/**
* 数字前置补零
* @param num 数字
* @param length 位数
* @returns {string}
*/
export function digit(num, length) {
let str = '';
num = String(num);
length = length || 2;
for (let i = num.length; i < length; i++) {
str += '0';
}
return num < Math.pow(10, length) ? str + (num | 0) : num;
}
/**
* 时间格式化
* @param time 时间
* @param format 格式
* @returns {string}
*/
export function toDateString(time, format) {
if (!time) {
return '';
}
if (typeof time === 'string') {
time = time.replace(/-/g, '/');
} else if (typeof time === 'number' && String(time).length === 10) {
time = time * 1000; // 10位时间戳处理
}
const date = new Date(time),
ymd = [
digit(date.getFullYear(), 4),
digit(date.getMonth() + 1),
digit(date.getDate())
],
hms = [
digit(date.getHours()),
digit(date.getMinutes()),
digit(date.getSeconds())
];
return (format || 'yyyy-MM-dd HH:mm:ss')
.replace(/yyyy/g, ymd[0])
.replace(/MM/g, ymd[1])
.replace(/dd/g, ymd[2])
.replace(/HH/g, hms[0])
.replace(/mm/g, hms[1])
.replace(/ss/g, hms[2]);
}
/**
* html转义
* @param html
* @returns {string}
*/
export function escape(html) {
return String(html || '')
.replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/'/g, '&#39;')
.replace(/"/g, '&quot;');
}
/**
* pid形式数据转children形式
* @param data 需要转换的数组
* @param idKey id字段名
* @param pidKey pid字段名
* @param childKey 生成的children字段名
* @param pid 顶级的pid
* @param addPIds 是否添加所有父级id的字段
* @param parentsKey 所有父级id的字段名称默认parentIds
* @param parentIds 所有父级id
* @returns {[]}
*/
export function toTreeData(data, idKey, pidKey, childKey, pid, addPIds, parentsKey, parentIds) {
if (typeof data === 'object' && !Array.isArray(data)) {
idKey = data.idKey;
pidKey = data.pidKey;
childKey = data.childKey;
pid = data.pid;
addPIds = data.addPIds;
parentsKey = data.parentsKey;
parentIds = data.parentIds;
data = data.data;
}
if (!childKey) {
childKey = 'children';
}
if (typeof pid === 'undefined') {
pid = [];
data.forEach((d) => {
let flag = true;
for (let i = 0; i < data.length; i++) {
if (d[pidKey] == data[i][idKey]) {
flag = false;
break;
}
}
if (flag) {
pid.push(d[pidKey]);
}
});
}
let result = [];
data.forEach((d) => {
if (d[idKey] == d[pidKey]) {
console.error('data error: ', d)
return;
}
if (Array.isArray(pid) ? (pid.indexOf(d[pidKey]) !== -1) : (d[pidKey] == pid)) {
let children = toTreeData({
data: data,
idKey: idKey,
pidKey: pidKey,
childKey: childKey,
pid: d[idKey],
addPIds: addPIds,
parentsKey: parentsKey,
parentIds: (parentIds || []).concat([d[idKey]])
});
if (children.length > 0) {
d[childKey] = children;
}
if (addPIds) {
d[parentsKey || 'parentIds'] = parentIds || [];
}
result.push(d);
}
});
return result;
}
/**
* 遍历children形式数据
* @param data 需要遍历的数组
* @param callback 回调
* @param childKey children字段名
*/
export function eachTreeData(data, callback, childKey = 'children', pname = '') {
if (!data || !data.length) {
return;
}
data.forEach((d) => {
d.pname = pname
if (callback(d) !== false && d[childKey]) {
eachTreeData(d[childKey], callback, childKey,d.title);
}
});
}
/**
* 处理树形数据
* @param data 需要处理的数据
* @param formatter 处理器
* @param childKey children字段名
* @returns {[]} 处理后的数据
*/
export function formatTreeData(data, formatter, childKey = 'children') {
let result = [];
if (data && data.length) {
data.forEach((d) => {
let item = formatter(d);
if (item !== false) {
if (item[childKey]) {
item[childKey] = formatTreeData(item[childKey], formatter, childKey);
}
result.push(item);
}
});
}
return result;
}
/**
* 让浏览器全屏切换
* @param el dom
* @param fullscreen 是否全屏
* @returns {boolean} 全屏状态
*/
export function toggleFullscreen(el, fullscreen) {
if (!el) {
el = document.documentElement;
}
if (typeof fullscreen === 'undefined' || fullscreen === null) {
fullscreen = !isFullscreen();
}
if (fullscreen) {
const rfs = (
el.requestFullScreen ||
el.webkitRequestFullScreen ||
el.mozRequestFullScreen ||
el.msRequestFullScreen
);
if (rfs) {
rfs.call(el);
} else {
throw new Error('您的浏览器不支持全屏模式');
}
} else {
const cfs = (
document.exitFullScreen ||
document.webkitCancelFullScreen ||
document.mozCancelFullScreen ||
document.msExitFullscreen
);
if (cfs) {
cfs.call(document);
}
}
return fullscreen;
}
/**
* 获取当前是否是全屏状态
* @returns {boolean}
*/
export function isFullscreen() {
return !!(
document.fullscreenElement ||
document.webkitFullscreenElement ||
document.mozFullScreenElement ||
document.msFullscreenElement
);
}
/**
* 获取屏幕宽度
* @returns {number}
*/
export function screenWidth() {
return document.documentElement.clientWidth || document.body.clientWidth;
}
/**
* 获取屏幕高度
* @returns {number}
*/
export function screenHeight() {
return document.documentElement.clientHeight || document.body.clientHeight;
}
/**
* 获取html的纯文本
* @param html
* @returns {string}
*/
export function htmlToText(html) {
return html.replace(/<[^>]+>/g, '');
}
/**
* 获取设备信息
* @param key 自定义的agent
* @returns
*/
export function device(key) {
const agent = navigator.userAgent.toLowerCase(),
result = {os: null, ie: false};
// 获取版本号
function getVersion(label) {
const exp = new RegExp(label + '/([^\\s\\_\\-]+)');
return (agent.match(exp) || [])[1] || false;
}
// 获取操作系统
if (/windows/.test(agent)) {
result.os = 'windows';
} else if (/linux/.test(agent)) {
result.os = 'linux';
} else if (/iphone|ipod|ipad|ios/.test(agent)) {
result.os = 'ios';
} else if (/mac/.test(agent)) {
result.os = 'mac';
} else if (/android/.test(agent)) {
result.os = 'android';
}
// 获取ie版本
if (!!window.ActiveXObject || 'ActiveXObject' in window) {
result.ie = (agent.match(/msie\s(\d+)/) || [])[1] || '11';
}
// 获取微信版本
result.weixin = getVersion('micromessenger');
// 获取自定义的agent
if (key && !result[key]) {
result[key] = getVersion(key);
}
// 是否移动设备
result.android = /android/.test(agent);
result.ios = result.os === 'ios';
result.mobile = result.android || result.ios;
return result;
}
/**
* 生成随机字符串
* @param length 长度
* @param radix 基数
* @returns {string}
*/
export function uuid(length = 32, radix) {
const num = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
let result = '';
for (let i = 0; i < length; i++) {
result += num.charAt(Math.floor(Math.random() * (radix || num.length)));
}
return result;
}
/**
* 生成m到n的随机数
* @param m 最小值, 包含
* @param n 最大值, 不包含
* @returns {number}
*/
export function random(m, n) {
return Math.floor(Math.random() * (m - n) + n);
}
/**
* 百度地图坐标转高德地图坐标
* @param point 坐标
* @returns {{lng: number, lat: number}}
*/
export function bd09ToGcj02(point) {
const x_pi = (3.14159265358979324 * 3000.0) / 180.0;
const x = point.lng - 0.0065, y = point.lat - 0.006;
const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
return {
lng: z * Math.cos(theta),
lat: z * Math.sin(theta)
};
}
/**
* 高德地图坐标转百度地图坐标
* @param point 坐标
* @returns {{lng: number, lat: number}}
*/
export function gcj02ToBd09(point) {
const x_pi = (3.14159265358979324 * 3000.0) / 180.0;
const x = point.lng, y = point.lat;
const z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
const theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
return {
lng: z * Math.cos(theta) + 0.0065,
lat: z * Math.sin(theta) + 0.006
};
}
/**
* 深度克隆
* @param obj
* @return
*/
export function deepClone(obj) {
let result;
const type = typeOf(obj);
if (type === 'Object') {
result = {};
} else if (type === 'Array') {
result = [];
} else {
return obj;
}
Object.keys(obj).forEach(key => {
const copy = obj[key],
cType = this.typeOf(copy);
if (cType === 'Object' || cType === 'Array') {
result[key] = deepClone(copy);
} else {
result[key] = obj[key];
}
});
return result;
}
/**
* 获取变量类型
* @param obj
* @returns {string}
*/
export function typeOf(obj) {
if (obj === null) {
return 'Null';
}
if (typeof obj === 'undefined') {
return 'Undefined';
}
return Object.prototype.toString.call(obj).slice(8, -1);
}
/**
* 播放音频
* @param url 音频地址
*/
export function play(url) {
return new Audio(url).play();
}
/**
* 导出excel
* @param XLSX XLSX对象
* @param sheet 数组或sheet对象
* @param sheetname 文件名称
* @param type 文件格式
*/
export function exportSheet(XLSX, sheet, sheetname = 'sheet1', type = 'xlsx') {
if (Array.isArray(sheet)) {
sheet = XLSX.utils.aoa_to_sheet(sheet);
}
let workbook = {
SheetNames: [sheetname],
Sheets: {}
};
workbook.Sheets[sheetname] = sheet;
XLSX.writeFile(workbook, sheetname + '.' + type);
}
/**
* 数字千分位
* @param num
* @returns {string}
*/
export function formatNumber(num) {
return String(num).replace(/(\d{1,3})(?=(\d{3})+(?:$|\.))/g, '$1,');
}
/**
* 判断是否是外链
* @param url
* @returns {boolean}
*/
export function isUrl(url) {
return !!(url && (
url.startsWith('http://') ||
url.startsWith('https://') ||
url.startsWith('//')
));
}