You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hami/packages/web/src/utils/index.js

588 lines
14 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { isFunction } from 'lodash';
import { ElMessage } from 'element-plus';
/**
* Created by PanJiaChen on 16/11/18.
*/
/**
* Parse the time to string
* @param {(Object|string|number)} time
* @param {string} cFormat
* @returns {string | null}
*/
export function parseTime(time, cFormat) {
if (arguments.length === 0 || !time) {
return null;
}
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}';
let date;
if (typeof time === 'object') {
date = time;
} else {
if (typeof time === 'string') {
if (/^[0-9]+$/.test(time)) {
// support "1548221490638"
time = parseInt(time);
} else {
// support safari
// https://stackoverflow.com/questions/4310953/invalid-date-in-safari
time = time.replace(new RegExp(/-/gm), '/');
}
}
if (typeof time === 'number' && time.toString().length === 10) {
time = time * 1000;
}
date = new Date(time);
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay(),
};
const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
const value = formatObj[key];
// Note: getDay() returns 0 on Sunday
if (key === 'a') {
return ['日', '一', '二', '三', '四', '五', '六'][value];
}
return value.toString().padStart(2, '0');
});
return time_str;
}
/**
* @param {number} time
* @param {string} option
* @returns {string}
*/
export function formatTime(time, option) {
if (('' + time).length === 10) {
time = parseInt(time) * 1000;
} else {
time = +time;
}
const d = new Date(time);
const now = Date.now();
const diff = (now - d) / 1000;
if (diff < 30) {
return '刚刚';
} else if (diff < 3600) {
// less 1 hour
return Math.ceil(diff / 60) + '分钟前';
} else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + '小时前';
} else if (diff < 3600 * 24 * 2) {
return '1天前';
}
if (option) {
return parseTime(time, option);
} else {
return (
d.getMonth() +
1 +
'月' +
d.getDate() +
'日' +
d.getHours() +
'时' +
d.getMinutes() +
'分'
);
}
}
/**
* @param {string} url
* @returns {Object}
*/
export function getQueryObject(url) {
url = url == null ? window.location.href : url;
const search = url.substring(url.lastIndexOf('?') + 1);
const obj = {};
const reg = /([^?&=]+)=([^?&=]*)/g;
search.replace(reg, (rs, $1, $2) => {
const name = decodeURIComponent($1);
let val = decodeURIComponent($2);
val = String(val);
obj[name] = val;
return rs;
});
return obj;
}
/**
* @param {string} input value
* @returns {number} output value
*/
export function byteLength(str) {
// returns the byte length of an utf8 string
let s = str.length;
for (var i = str.length - 1; i >= 0; i--) {
const code = str.charCodeAt(i);
if (code > 0x7f && code <= 0x7ff) s++;
else if (code > 0x7ff && code <= 0xffff) s += 2;
if (code >= 0xdc00 && code <= 0xdfff) i--;
}
return s;
}
/**
* @param {Array} actual
* @returns {Array}
*/
export function cleanArray(actual) {
const newArray = [];
for (let i = 0; i < actual.length; i++) {
if (actual[i]) {
newArray.push(actual[i]);
}
}
return newArray;
}
/**
* @param {Object} json
* @returns {Array}
*/
export function param(json) {
if (!json) return '';
return cleanArray(
Object.keys(json).map((key) => {
if (json[key] === undefined) return '';
return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]);
}),
).join('&');
}
/**
* @param {string} url
* @returns {Object}
*/
export function param2Obj(url) {
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ');
if (!search) {
return {};
}
const obj = {};
const searchArr = search.split('&');
searchArr.forEach((v) => {
const index = v.indexOf('=');
if (index !== -1) {
const name = v.substring(0, index);
const val = v.substring(index + 1, v.length);
obj[name] = val;
}
});
return obj;
}
/**
* @param {string} val
* @returns {string}
*/
export function html2Text(val) {
const div = document.createElement('div');
div.innerHTML = val;
return div.textContent || div.innerText;
}
/**
* Merges two objects, giving the last one precedence
* @param {Object} target
* @param {(Object|Array)} source
* @returns {Object}
*/
export function objectMerge(target, source) {
if (typeof target !== 'object') {
target = {};
}
if (Array.isArray(source)) {
return source.slice();
}
Object.keys(source).forEach((property) => {
const sourceProperty = source[property];
if (typeof sourceProperty === 'object') {
target[property] = objectMerge(target[property], sourceProperty);
} else {
target[property] = sourceProperty;
}
});
return target;
}
/**
* @param {HTMLElement} element
* @param {string} className
*/
export function toggleClass(element, className) {
if (!element || !className) {
return;
}
let classString = element.className;
const nameIndex = classString.indexOf(className);
if (nameIndex === -1) {
classString += '' + className;
} else {
classString =
classString.substr(0, nameIndex) +
classString.substr(nameIndex + className.length);
}
element.className = classString;
}
/**
* @param {string} type
* @returns {Date}
*/
export function getTime(type) {
if (type === 'start') {
return new Date().getTime() - 3600 * 1000 * 24 * 90;
} else {
return new Date(new Date().toDateString());
}
}
/**
* @param {Function} func
* @param {number} wait
* @param {boolean} immediate
* @return {*}
*/
export function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result;
const later = function () {
// 据上一次触发时间间隔
const last = +new Date() - timestamp;
// 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
// 如果设定为immediate===true因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args);
if (!timeout) context = args = null;
}
}
};
return function (...args) {
context = this;
timestamp = +new Date();
const callNow = immediate && !timeout;
// 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
context = args = null;
}
return result;
};
}
/**
* This is just a simple version of deep copy
* Has a lot of edge cases bug
* If you want to use a perfect deep copy, use lodash's _.cloneDeep
* @param {Object} source
* @returns {Object}
*/
export function deepClone(source) {
if (!source && typeof source !== 'object') {
throw new Error('error arguments', 'deepClone');
}
const targetObj = source.constructor === Array ? [] : {};
Object.keys(source).forEach((keys) => {
if (source[keys] && typeof source[keys] === 'object') {
targetObj[keys] = deepClone(source[keys]);
} else {
targetObj[keys] = source[keys];
}
});
return targetObj;
}
/**
* @param {Array} arr
* @returns {Array}
*/
export function uniqueArr(arr) {
return Array.from(new Set(arr));
}
/**
* @returns {string}
*/
export function createUniqueString() {
const timestamp = +new Date() + '';
const randomNum = parseInt((1 + Math.random()) * 65536) + '';
return (+(randomNum + timestamp)).toString(32);
}
/**
* Check if an element has a class
* @param {HTMLElement} elm
* @param {string} cls
* @returns {boolean}
*/
export function hasClass(ele, cls) {
return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}
/**
* Add class to element
* @param {HTMLElement} elm
* @param {string} cls
*/
export function addClass(ele, cls) {
if (!hasClass(ele, cls)) ele.className += ' ' + cls;
}
/**
* Remove class from element
* @param {HTMLElement} elm
* @param {string} cls
*/
export function removeClass(ele, cls) {
if (hasClass(ele, cls)) {
const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
ele.className = ele.className.replace(reg, ' ');
}
}
export const timeParse = (obj = new Date(), format = 'YYYY-MM-DD HH:mm:ss') => {
obj = new Date(obj);
const year = obj.getFullYear();
const mon =
obj.getMonth() + 1 < 10 ? '0' + (obj.getMonth() + 1) : obj.getMonth() + 1;
const day = obj.getDate() < 10 ? '0' + obj.getDate() : obj.getDate();
const hour = obj.getHours() < 10 ? '0' + obj.getHours() : obj.getHours();
const min = obj.getMinutes() < 10 ? '0' + obj.getMinutes() : obj.getMinutes();
const second =
obj.getSeconds() < 10 ? '0' + obj.getSeconds() : obj.getSeconds();
format = format
.replace('YYYY', year + '')
.replace('MM', mon + '')
.replace('DD', day + '')
.replace('HH', hour + '')
.replace('mm', min + '')
.replace('ss', second + '');
return format;
};
export const calculateDuration = (createTime) => {
if (!createTime) {
return '--';
}
const create = new Date(createTime);
if (isNaN(create.getTime())) {
return '--';
}
const now = new Date();
const diff = now - create; // 时间差(毫秒)
const seconds = Math.floor((diff / 1000) % 60);
const minutes = Math.floor((diff / 1000 / 60) % 60);
const hours = Math.floor((diff / 1000 / 60 / 60) % 24);
const days = Math.floor(diff / 1000 / 60 / 60 / 24);
let duration = '';
if (days > 0) duration += `${days}`;
if (hours > 0) duration += `${hours} 小时 `;
if (minutes > 0) duration += `${minutes} 分钟 `;
if (seconds > 0 || duration === '') duration += `${seconds}`;
return duration.trim();
};
//可指定长度生成随机id
export function getRandomId(length) {
const characters =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let randomId = '';
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * characters.length);
randomId += characters.charAt(randomIndex);
}
return randomId;
}
export const parseMemory = (memory) => {
return +memory + ' GB';
};
export const generateUUID = () => {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (Math.random() * 16) | 0,
v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
};
export const renderProps = (fn, props) => {
if (isFunction(fn)) {
return fn(props);
}
return fn;
};
export const getDaysInRange = (startDate, endDate) => {
const result = [];
let currentDate = new Date(startDate);
while (currentDate <= endDate) {
const formattedDate = currentDate.toISOString().split('T')[0]; // 获取年月日部分并格式化
result.push(formattedDate);
currentDate.setDate(currentDate.getDate() + 1);
}
return result;
};
export const getRandom = (max) => {
return Math.floor(Math.random() * max);
};
export const getDaysInMonth = (yearMonth) => {
const [year, month] = yearMonth.split('-').map(Number);
const currentDate = new Date();
const currentYear = currentDate.getFullYear();
const currentMonth = currentDate.getMonth() + 1;
const currentDay = currentDate.getDate();
const isCurrentMonth = year === currentYear && month === currentMonth;
const daysInMonth = isCurrentMonth
? currentDay - 1
: new Date(year, month, 0).getDate();
const daysArray = [];
for (let day = 1; day <= daysInMonth; day++) {
const formattedDay = `${month.toString().padStart(2, '0')}-${day
.toString()
.padStart(2, '0')}`;
daysArray.push(formattedDay);
}
return daysArray;
};
export const getMonthsInYear = (year) => {
const currentDate = new Date();
const currentYear = currentDate.getFullYear();
const currentMonth = currentDate.getMonth() + 1;
const monthsArray = [];
for (let month = 1; month <= 12; month++) {
if (+year === currentYear && month > currentMonth) {
break; // 如果是当前年份且月份大于当前月份,停止循环
}
const formattedMonth = `${year}-${month.toString().padStart(2, '0')}`;
monthsArray.push(formattedMonth);
}
return monthsArray;
};
export const getDataByPath = (obj, path) => {
// 使用正则表达式分割路径字符串
const keys = path.split('.');
// 遍历路径,逐层深入对象
let result = obj;
for (const key of keys) {
if (result && typeof result === 'object' && key in result) {
result = result[key];
} else {
// 如果路径无效,返回 undefined 或者其他默认值
return undefined;
}
}
return result;
};
export function daysSince(dateString) {
// 将传入的日期字符串转换为Date对象
const pastDate = new Date(dateString);
// 获取当前日期
const currentDate = new Date();
// 计算两个日期之间的时间差,得到的结果是毫秒数
const timeDifference = currentDate - pastDate;
// 将时间差从毫秒转换为天1天 = 24小时 * 60分钟 * 60秒 * 1000毫秒
const daysDifference = Math.floor(timeDifference / (1000 * 60 * 60 * 24));
return daysDifference;
}
export function copy(str) {
const textarea = document.createElement('textarea');
textarea.value = str;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
ElMessage.success('复制成功');
}
export function roundToDecimal(num, decimalPlaces) {
if (typeof num !== 'number' || typeof decimalPlaces !== 'number') {
throw new TypeError('参数必须是数字');
}
// 判断是否是小数
if (num % 1 !== 0) {
// 进行四舍五入
const factor = Math.pow(10, decimalPlaces);
return Math.round(num * factor) / factor;
}
// 如果不是小数,返回原数字
return num;
}
export function toBoolean(str) {
return str === 'true';
}
export const clearEdges = (items) =>
items.map((item) => ({
...item,
children: clearEdges(item.edges.children),
}));
// 字节转GB
export const bytesToGB = (bytes) => {
return Math.round(bytes / (1024 * 1024 * 1024));
}
export function parseUrl(url) {
const [pathname, queryString] = url.split('?');
const query = {};
if (queryString) {
queryString.split('&').forEach(pair => {
const [key, value] = pair.split('=');
query[decodeURIComponent(key)] = decodeURIComponent(value || '');
});
}
return { pathname, query };
}